基本操作
-
图像IO操作的API:
-
cv.imread(): 读取图像
-
cv.imshow():显示图像
-
cv.imwrite(): 保存图像
-
-
在图像上绘制几何图像
-
cv.line(): 绘制直线
-
cv.circle(): 绘制圆形
-
cv.rectangle(): 绘制矩形
-
cv.putText(): 在图像上添加文字
-
-
直接使用行列索引获取图像中的像素并进行修改
-
图像的属性
| 属性 | API |
| ---- | ---- |
| 形状 | img.shape |
| 图像大小 | img.size |
| 数据类型 | img.dtype | -
拆分通道: cv.split()
-
通道合并:cv.merge()
-
色彩空间的改变
- cv.cvtColor(input_image,flag)
-
图像加法:将两幅图像加载一起
- cv.add()
-
图像的混合:将两幅图像按照不同的比例进行混合
- cv.addweight()
图像处理
几何变换
-
图像缩放:对图像进行放大或缩小
cv.resize(img,dsize,fx=0,fy=0,interpolation=cv2.INTER_LINEAR)
interpolation插值 | 含义 |
---|---|
cv2.INTER_LINEAR | 双线性插值法 |
cv2.INTER_NEAREST | 最近邻插法 |
cv2.INTER_AREA | 像素区域重采样(默认) |
cv2.INTER_CUBIC | 双三次插值 |
-
图像平移:
指定平移矩阵后,调用
cv.warpAffine(img,M,(cols,rows))
平移图像 -
图像旋转:
调用
cv.getRotationMatrix2D(center, angle, scale)
获取旋转矩阵,然后调用cv.warpAffine()
进行旋转 -
仿射变换:
调用
cv.getAffineTransform
将创建变换矩阵,最后该矩阵将传递给cv.warpAffine()
进行变换 -
透射变换:
通过函数
cv.getPerspectiveTransform()
找到变换矩阵,将cv.warpPerspective()
进行投射变换 -
金字塔
图像金字塔是图像多尺度表达的一种,使用的API:
-
cv.pyrUp(): 向上采样
-
cv.pyrDown(): 向下采样
-
形态学操作
- 连通性
- 邻接关系:4邻接,8邻接和D邻接
- 连通性:4连通,8连通和m连通
-
形态学操作
-
腐蚀和膨胀:
-
腐蚀:求局部最大值 cv.erode(img,kernel,iterations)
-
膨胀:求局部最小值 cv.dilate(img,kernel,iterations)
-
-
开闭运算:
-
开:先腐蚀后膨胀 cv.morphologyEx(img, cv.MORPH_OPEN, kernel)
-
闭:先膨胀后腐蚀 cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)
- 礼帽和黑帽:
-
礼帽:原图像与开运算之差 cv.morphologyEx(img, cv.MORPH_TOPHAT, kernel)
-
黑帽:闭运算与原图像之差 cv.morphologyEx(img, cv.MORPH_BLACKHAT, kernel)
-
图像平滑
1. 图像噪声
- 椒盐噪声:图像中随机出现的白点或者黑点
- 高斯噪声:噪声的概率密度分布是正态分布
2. 图像平滑
- 均值滤波:算法简单,计算速度快,在去噪的同时去除了很多细节部分,将图像变得模糊
cv.blur(src, ksize, anchor, borderType)
- 高斯滤波: 去除高斯噪声
cv.GaussianBlur(src,ksize,sigmaX,sigmaY,borderType)
- 中值滤波: 去除椒盐噪声
cv.medianBlur(src, ksize)
直方图
- 灰度直方图:
- 直方图是图像中像素强度分布的图形表达方式。
- 它统计了每一个强度值所具有的像素个数。
- 不同的图像的直方图可能是相同的
cv.calcHist (images,channels,mask,histSize,ranges[,hist[,accumulate]])
- 掩膜
创建蒙版,透过mask进行传递,可获取感兴趣区域的直方图
cv.bitwise_and(input_img,out_img,mask = mask)
- 直方图均衡化:增强图像对比度的一种方法
cv.equalizeHist()
:输入是灰度图像,输出是直方图均衡图像
4.自适应的直方图均衡
将整幅图像分成很多小块,然后再对每一个小块分别进行直方图均衡化,最后进行拼接
clahe cv.createCLAHE(clipLimit,tileGridSize)
边缘检测
-
边缘检测的原理
基于搜索:利用一阶导数的最大值获取边界
基于零穿越:利用二阶导数为0获取边界 -
Sobel算子
基于搜索的方法获取边界
-
cv.sobel(src, ddepth, dx, dy, dst, ksize, scale, delta, borderType)
-
cv.convertScaleAbs()
-
cv.addweights()
-
-
Laplacian算子
基于零穿越获取边界
cv.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])
-
Canny算法
canny = cv2.Canny(image, threshold1, threshold2)
流程:
噪声去除:高斯滤波
计算图像梯度:sobel算子,计算梯度大小和方向
非极大值抑制:利用梯度方向像素来判断当前像素是否为边界点
滞后阈值:设置两个阈值,确定最终的边界
5 算子比较
算子 | 优缺点比较 |
---|---|
Roberts | 对具有陡峭的低噪声的图像处理效果较好,但利用Roberts算子提取边缘的结果是边缘比较粗,因此边缘定位不是很准确。 |
Sobel | 对灰度渐变和噪声较多的图像处理效果比较好,Sobl算子对边缘定位比较准确。 |
Kirsch | 对灰度渐变和噪声较多的图像处理效果较好。 |
Prewitt | 对灰度渐变和噪声较多的图像处理效果较好。 |
Laplacian | 对图像中的阶跃性边缘点定位准确,对噪声非常敏感,丢失一部分边缘的方向信息,造成一些不连续的检测边缘。 |
LoG | L0G算子经常出现双边缘像素边界,而且该检测方法对噪声比较敏感,所以很少用L0G算子检测边缘,而是用来判断边缘像素是位于图像的明区还是暗区。 |
Canny | 此方法不容易受噪声的干扰,能够检测到真正的弱边缘。在edge函数中,最有效的边缘检测方法是Canny方法。该方法的优点在于使用两种不同的阅值分别检测强边缘和弱边缘,并且仅当弱边缘与强边缘相连时,才将弱边缘包含在输出图像中。因此,这种方法不容易被噪声“填充”,跟容易检测出真正的弱边缘。 |
模版匹配和霍夫变换
- 模板匹配
-
原理:在给定的图片中查找和模板最相似的区域
-
API:利用
cv.matchTemplate()
进行模板匹配,然后使用cv.minMaxLoc()
搜索最匹配的位置。
- 霍夫线检测
-
原理:将要检测的内容转换到霍夫空间中,利用累加器统计最优解,将检测结果表示处理
-
API:cv2.HoughLines(img, rho, theta, threshold)
-
注意:该方法输入是的二值化图像,在进行检测前要将图像进行二值化处理
- 霍夫圆检测
-
方法:霍夫梯度法
-
API:cv.HoughCircles(image, method, dp, minDist, param1=100, param2=100, minRadius=0,maxRadius=0)