内容简介:canny边缘检测是一个流行的边缘检测算法,它分为几个步骤由于边缘检测对图像中的噪声很敏感,第一步是用5x5高斯滤波器去除图像中的噪声,在前面图像平滑的文章中已经讲过。第二步,在水平方向和垂直方向用Sobel算子对平滑后的图像进行梯度计算,得到水平方向(GX)和垂直方向(Gy)上的一阶导数。
canny边缘检测是一个流行的边缘检测算法,它分为几个步骤
1.消除噪声
由于边缘检测对图像中的噪声很敏感,第一步是用5x5高斯滤波器去除图像中的噪声,在前面图像平滑的文章中已经讲过。
2.梯度值和方向的计算
第二步,在水平方向和垂直方向用Sobel算子对平滑后的图像进行梯度计算,得到水平方向(GX)和垂直方向(Gy)上的一阶导数。
梯度值和方向的公式:
梯度方向总是垂直于边缘的,在canny边缘检测算法中,梯度方向被简化到4个方向角度,0,45,90,135。
3.非极大值抑制
在获得梯度幅值和方向后,对图像进行全面扫描,以消除可能不在边缘上的像素。在每个像素上,检查像素是否是其邻域内沿梯度方向的局部最大值。例如下面的边缘梯度:
C,A,B三个梯度值都在梯度方向上,对比这三个梯度,只保留最大的A进入下一阶段的计算,而C,B都设置为0,因此canny边缘检测得到的都是轮廓比较细的边缘,精确度也相对较高。
4.滞后阈值
这个阶段决定了哪些像素是真正的边缘,哪些不是边缘。为此设定了两个阈值,minVal和maxVal。任何强度梯度大于maxVal的边缘都肯定是边缘,而minVal以下的边缘肯定是非边缘的,因此被丢弃。处于这两个阈值之间的人根据其连通性分为边缘或非边缘,如果它们连接到“确定边缘”像素,则它们被视为边缘的一部分,否则它们也会被丢弃。如下图:
边缘像素A位于maxVal之上,因此被认为是“确定边缘”。虽然边缘像素C的梯度值在maxVal以下,但它与A相连接,因此也被认为是有效边,我们得到了AC这条完整的曲线。但是对于边缘像素B,虽然它高于minVal,并且与边缘C梯度所处的区域相同,但它没有连接到任何“确定边缘”,因此被丢弃。因此,为了得到正确的结果,我们必须合理地选择minVal和maxVal,这是非常重要的。Canny 推荐的 高:低 阈值比在 2:1 到3:1之间。
这一阶段也消除了小段像素噪声的干扰,边缘一定都是长线段。
所以canny最终得到的是图像中的梯度值大的强边缘部分。
5.opencv的canny边缘计算函数
opencv提供了函数cv2.canny()中来执行上述所有步骤。
void cv::Canny ( InputArray image, //待处理图像 OutputArray edges, //边缘结果 double threshold1, //minVal double threshold2, //maxVal int apertureSize = 3,//sobel内核大小 bool L2gradient = false //是否使用更精确的梯度值计算函数(默认是第2节图中的公式) )
示例:
img = cv2.imread('test.jpg', 0) edges = cv2.Canny(img, 75, 150) plt.subplot(121), plt.imshow(img, cmap='gray') plt.title('Original Image'), plt.xticks([]), plt.yticks([]) plt.subplot(122), plt.imshow(edges, cmap='gray') plt.title('Edge Image'), plt.xticks([]), plt.yticks([]) plt.show()
根据图像的具体情况,选择合适的minVal/maxVal是非常重要的。
以上所述就是小编给大家介绍的《Opencv图像处理系列(七)—— Canny边缘检测》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Opencv图像处理系列(六)—— 图像梯度
- Opencv图像处理系列(九)—— 图像轮廓
- Python 图像处理 OpenCV (15):图像轮廓
- Opencv图像处理系列(三)——图像二值化
- Opencv图像处理系列(八)—— 图像金字塔
- Facebook 开源图像处理库 Spectrum,优化移动端图像生成
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。