图像处理以及边缘检测
图像梯度
★ 对于梯度的运算就是卷积的运算的过程 ★
Sobel算子
算子核矩阵如下:
注意这里并不是一成不变的,Sonbel核的大小会影响它对核值的改变
- 类似于高斯滤波,近的位置对于中心点影响大,远的位置影响小
上述可以看出,对于梯度变换黑到白的变换梯度为正,白到黑的变化梯度为负
代码演示
1 | sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3) |
Scharr算子
算子核矩阵如下:
代码展示
1
2
3
4
5scharrx = cv2.Scharr(img, cv2.CV_64F, 1, 0)
scharry = cv2.Scharr(img, cv2.CV_64F, 0, 1)
scharrx = cv2.convertScaleAbs(scharrx)
scharry = cv2.convertScaleAbs(scharry)
scharrxy = cv2.addWeighted(scharrx, 0.5, scharry, 0.5, 0)
Laplacian算子
算子核矩阵如下:
- 代码展示
1 | laplacian = cv2.Laplacian(img, cv2.CV_64F) |
算子对比
代码如下
1 | img = cv2.imread('../img/2.jpg', cv2.IMREAD_GRAYSCALE) |
第一个是原图,第二个是Sobel,第三个是Scharr,第四个是Laplacian
边缘检查
Canny边缘检测
- 使用高斯滤波器,以平滑图像,滤除噪声(已解决)
- 计算图像中每个像素点的梯度强度和方向(已解决)
- 应用非极大值抑制,以消除边缘检测带来的杂算响应
- 应用双阈值检查来确定真实的和潜在的边缘
- 通过抑制孤立的弱边缘最终完成边缘检查
非极大值抑制
- 线性插值:设$g_1$的梯度幅值为$M(g_1)$,设$g_2$的梯度幅值为$M(g_2)$,那么对于$dTmp_1$的亚像素的梯度复制为
其中$w = \frac {distance(dTmp_1,g2)}{distance(dTmp_1,g2)}$,$distance(x,y)$代表$x$到$y$的距离
- 简化方法
为了简化计算,由于一个像素周围共有8个像素,把一个像素的方向离散成八个方向,这样就只需要计算前后的即可,不应插值了
双阈值检查
- 梯度值 >
maxVal
: 处理为边界 minVal
<梯度值<maxVal
: 连有边界的保留,否则舍弃- 梯度值 <
minVal
: 舍弃
代码展示
1 | img = cv2.imread('../img/2.jpg', cv2.IMREAD_GRAYSCALE) |
运行结果:
对于阈值设置的大小我们可以发现这个,对于越大的的阈值范围(如图一)得到的细节越少杂讯点也少,而对于阈值范围越小的检测(如图二),得到的细节比较多但是同时加剧了得到杂质点的可能
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Mirclea's blog!