1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > [图像处理]-Canny边缘检测算法

[图像处理]-Canny边缘检测算法

时间:2019-02-19 09:16:07

相关推荐

[图像处理]-Canny边缘检测算法

1.问题描述

在处理图像时,有时我们需要图像的边界或通过边界得到一定的信息,如何有效而准确的找到这些边界并显示出来就了一个问题,而Canny算法则可以很好的解决它。

2.简述Canny算法

Canny 是一种 multi-stage 算法,分别如下:

高斯滤波:平滑图像,消除噪声梯度和方向计算:利用Sobel算子计算每个像素点的梯度和方向非极大值抑制:消除边缘检测带来的杂散相应(本来不是边缘检测出来是)双阈值:检测真正和潜在的边缘滞后技术:通过抑制弱边缘来完成边缘检测跟踪边界

2.1高斯滤波

本质就是模糊图像,玩过PS的应该很好了解,本来图像上有很多噪点,用涂抹工具抹一下,噪点没了,图片变模糊了,噪点消失了.

这一阶段比较类似于卷积,拿一个33或55的带权重的滤波器给图像乘一下.

这里以size=3的高斯内核为例:这里做了归一化处理(元素和为 1)

滤波的主要目的是降噪,一般的图像处理算法都需要先进行降噪。而高斯滤波主要使图像变得平滑(模糊),同时也有可能增大了边缘的宽度。

2.2计算图像梯度及方向

对于平滑后的图像,首先在水平和垂直方向采用 Sobel kernel 计算得到水平方向Gx和垂直方向Gy(具体计算过程参考链接).

然后计算每个像素的边缘梯度和梯度方向:

这样就得到的图像中每一个点的梯度值及梯度方向

2.3非最大值抑制 NMS

计算得到梯度值和梯度方向后,对图片进行全面的扫描,以去除不构成边缘的无关像素点.

对于每个像素,检查其是否是在梯度方向中其临近像素点中的局部最大值. 如图:

点 A 位于图像边缘(垂直方向). 梯度方向(Gradient Direction) 垂直于边缘. 点 B 和点 C 位于梯度方向.

因此,检查点 A 和点 B,点 C,确定点A 是否是局部最大值. 如果点 A 是局部最大值,则继续下一个阶段;如果点 A 不是局部最大值,则其被抑制(设为 0).

简单来说,NMS 得到的结果是一个 薄边缘(thin edges) 的二值图片.可以理解为边缘点全部被标为1,非边缘点被标为0 .

2.4双阈值筛选

这一阶段主要判断上面NMS后的哪些是真正的边缘,哪些是假边缘

该阶段需要设定两个阈值,minVal 和 maxVal,任何边缘强度大于maxVal的确定为边缘,而小于minVal的确定为非边缘,进行丢弃.

位于maxVal与minVal之间的为待确定边缘,进行连续性判断,如果其连着确定边缘则认为是真正边缘的一部分,否则,进行丢弃.如下图所示.

边缘 A 大于 maxVal,因此为“确定边缘(sure-edge)”.

虽然边缘 C 小于 maxVal,但其连接着边缘 A,因此也认为是有效边缘,以得到完整的边缘曲线.

但,边缘 B 虽然大于 minVal,并与边缘 C 位于相同的区域,但其没有与任何“确定边缘”相连接,因此,丢弃该边缘 B.

由上可见,minVal 和 maxVal 值的选择对于边缘检测的结果非常重要.

此外,该阶段的处理还移除小的像素噪声,因为假设边缘是长曲线.

最终,即可得到图片的有效边缘.

注意

具体这两个值怎么设置,我们就要分析两个值变化对图像的影响。

maxVal: 带来最明显的差异,增大maxVal无疑会导致原来的边界点可能会直接消失。但这种消失时是成片消失。

minVal: 增大minVal,会导致有些待定像素点被弃用,也就是靠近边界像素点的介于双阈值之间的被弃用。导致的现象就是边界出现破损,这种非成片消失。只是边界信息不完整。

下面以 video = cv2.Canny(img, 80, 250) 为例:分别增大minVal和maxVal。

增大minVal: (边界出现缺损)

增大maxVal: (边界出现成片消失,边界信息完整)

在实际应用中,观察梯度图像,如果边界信息缺损,那么适当的减小minVal;如果有不想要的区域出现,那么适当的增加MaxVal。

3.opencv实现

OpenCV 提供了 cv2.canny() 函数.

edge = cv2.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient ]]])###参数 Image - 输入图片,必须为单通道的灰度图参数 threshold1 和 threshold2 - 分别对应于阈值 minVal 和 maxVal参数 apertureSize - 用于计算图片提取的 Sobel kernel 尺寸. 默认为 3.参数 L2gradient - 指定计算梯度的等式. 当参数为 True 时,采用 2.2 中的梯度计算公式,其精度更高;否则采用的梯度计算公式为:梯度|G|=|Gx|+|Gy|###

具体代码如下

import cv2import numpy as npfrom matplotlib import pyplot as pltimg = cv2.imread('test.jpg',0)edges = cv2.Canny(img, 100, 200)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()

效果

带滚动条代码

import numpy as npimport cv2def nothing(x):passimg=cv2.imread('/home/cheng/Desktop/1.jpg',0)cv2.namedWindow('res')cv2.createTrackbar('min','res',0,25,nothing)cv2.createTrackbar('max','res',0,25,nothing)while(1):if cv2.waitKey(1)&0xFF==27:breakmaxVal=cv2.getTrackbarPos('max','res')minVal=cv2.getTrackbarPos('min','res')canny=cv2.Canny(img,10*minVal,10*maxVal)cv2.imshow('res',canny)cv2.destroyAllWindows()

效果

4.参考

opencv-python(13):Canny边缘检测

Python - Opencv 之 Canny 边缘检测

Canny边缘检测算法

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。