十五 Canny边缘检测算法

一、Canny算法介绍

Canny 的目标是找到一个最优的边缘检测算法,最优边缘检测的含义是:

好的检测- 算法能够尽可能多地标识出图像中的实际边缘。

好的定位- 标识出的边缘要尽可能与实际图像中的实际边缘尽可能接近。

最小响应- 图像中的边缘只能标识一次,并且可能存在的图像噪声不应标识为边缘。

推文:Canny边缘检测算法原理及其VC实现详解(一)

1、canny算法步骤

1.高斯模糊--GaussianBlur  消除噪声。 一般情况下,使用高斯平滑滤波器卷积降噪。,因为canny是对噪声敏感的算法,所以先降噪,但是降噪不要太过,以免丢失
2.灰度转换--cvtColor  
3.计算梯度--Sobel/Scharr
4.非最大信号抑制
5.高低阈值输出二值图像

2、非最大信号抑制

 图像梯度幅值矩阵中的元素值越大,说明图像中该点的梯度值越大,但这不不能说明该点就是边缘(这仅仅是属于图像增强的过程)。在Canny算法中,非极大值抑制是进行边缘检测的重要步骤,通俗意义上是指寻找像素点局部最大值,将非极大值点所对应的灰度值置为0,这样可以剔除掉一大部分非边缘的点(这是本人的理解)。

根据图可知,要进行非极大值抑制,就首先要确定像素点C的灰度值在其8值邻域内是否为最大。图中蓝色的线条方向为C点的梯度方向,这样就可以确定其局部的最大值肯定分布在这条线上,也即出了C点外,梯度方向的交点dTmp1和dTmp2这两个点的值也可能会是局部最大值。因此,判断C点灰度与这两个点灰度大小即可判断C点是否为其邻域内的局部最大灰度点。如果经过判断,C点灰度值小于这两个点中的任一个,那就说明C点不是局部极大值,那么则可以排除C点为边缘。这就是非极大值抑制的工作原理。

  注意以下两点:

        1)中非最大抑制是回答这样一个问题:“当前的梯度值在梯度方向上是一个局部最大值吗?” 所以,要把当前位置的梯度值与梯度方向上两侧的梯度值进行比较;

        2)梯度方向垂直于边缘方向。

        但实际上,我们只能得到C点邻域的8个点的值,而dTmp1和dTmp2并不在其中,要得到这两个值就需要对该两个点两端的已知灰度进行线性插值,也即根据图中的g1和g2对dTmp1进行插值,根据g3和g4对dTmp2进行插值,这要用到其梯度方向,这是Canny算法中要求解梯度方向矩阵Thita的原因。

        完成非极大值抑制后,会得到一个二值图像,非边缘的点灰度值均为0,可能为边缘的局部灰度极大值点可设置其灰度为128。根据下文的具体测试图像可以看出,这样一个检测结果还是包含了很多由噪声及其他原因造成的假边缘。因此还需要进一步的处理。

 3、高低阈值输出二值图像

二、代码实现两种canny方法

1、需要我们求出梯度,这里用sobel计算梯度

Canny(dx, dy, threshold1, threshold2[, edges[, L2gradient]]) -> edges

使用带自定义图像渐变的Canny算法在图像中查找边缘,

dx参数表示输入图像的x导数(x导数满足16位,选择CV_16SC1或CV_16SC3)

dy参数表示输入图像的y导数(y导数满足16位,选择CV_16SC1或CV_16SC3)。

threshold1参数表示设置的低阈值。

threshold2参数表示设置的高阈值,一般设定为低阈值的3倍 (根据Canny算法的推荐)。

edges参数表示输出边缘图像,单通道8位图像。

L2gradient参数表示L2gradient参数表示一个布尔值,如果为真,则使用更精确的L2范数进行计算(即两个方向的倒数的平方和再开方),否则使用L1范数(直接将两个方向导数的绝对值相加)。

代码实现

 1 import cv2 as cv
 2 
 3 def edge_demo(image):
 4     #1、高斯模糊 去噪声
 5         #arg:输入图像
 6         #arg:高斯核(可以是(0,0),这样会自动根据sigmax计算得来)
 7         #age:sigmax(高斯核函数在X方向的的标准偏差)
 8     gaosiblur = cv.GaussianBlur(image,(3,3),0)
 9 
10     #2、灰度转换
11     gray = cv.cvtColor(gaosiblur,cv.COLOR_BGR2GRAY)
12 
13     #3、计算梯度
14     xgrad = cv.Sobel(gray,cv.CV_16SC1,1,0)   #canny方法API要求不允许使用浮点数
15     ygrad = cv.Sobel(gray,cv.CV_16SC1,0,1)
16 
17     #4.Canny方法中包含非最大信号抑制和双阈值输出
18     edge_output = cv.Canny(xgrad,ygrad,50,150)         #50是低阈值,150是高阈值
19     cv.imshow('canny_edge',edge_output)
20     
21     # 相与,获取颜色(掩模就是canny_edge,两个imag先与之后,最后在与mask与,mask的黑色部分用于剔除,白色部分用于保留)
22     dst = cv.bitwise_and(image,image,mask=edge_output)  
23     cv.imshow('color edge',dst)
24 
25 img = cv.imread('1.jpg')
26 cv.imshow('input image',img)
27 edge_demo(img)
28 cv.waitKey(0)
29 cv.destroyAllWindows()

2、直接调用Canny算法在单通道灰度图像中查找边缘

def Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None): 

image参数表示8位输入图像。

threshold1参数表示设置的低阈值。

threshold2参数表示设置的高阈值,一般设定为低阈值的3倍 (根据Canny算法的推荐)。

edges参数表示输出边缘图像,单通道8位图像。

apertureSize参数表示Sobel算子的大小。

L2gradient参数表示一个布尔值,如果为真,则使用更精确的L2范数进行计算(即两个方向的倒数的平方和再开方),否则使用L1范数(直接将两个方向导数的绝对值相加)。

代码实现

 1 import cv2 as cv
 2 
 3 def edge_demo(image):
 4 
 5     #1、高斯模糊 去噪声
 6         #arg:输入图像
 7         #arg:高斯核(可以是(0,0),这样会自动根据sigmax计算得来)
 8         #age:sigmax(高斯核函数在X方向的的标准偏差)
 9     gaosiblur = cv.GaussianBlur(image,(3,3),0)
10 
11     #2、灰度转换
12     gray = cv.cvtColor(gaosiblur,cv.COLOR_BGR2GRAY)
13 
14     #3、直接传入灰度图像,Canny方法中包含计算梯度,菲最大信号抑制和双阈值输出
15     edge_output = cv.Canny(gray,50,150)         #50是低阈值,150是高阈值
16     cv.imshow('canny_edge',edge_output)
17     dst = cv.bitwise_and(image,image,mask=edge_output)  #相与,获取颜色
18     cv.imshow('color edge',dst)
19 img = cv.imread('1.jpg')
20 cv.imshow('input image',img)
21 edge_demo(img)
22 cv.waitKey(0)
23 cv.destroyAllWindows()

 三、掩膜mask

在有些图像处理的函数中有的参数里面会有mask参数,即此函数支持掩膜操作,首先何为掩膜以及有什么用,如下:

数字图像处理中的掩膜的概念是借鉴于PCB制版的过程,在半导体制造中,许多芯片工艺步骤采用光刻技术,用于这些步骤的图形“底片”称为掩膜(也称作“掩模”),其作用是:在硅片上选定的区域中对一个不透明的图形模板遮盖,继而下面的腐蚀或扩散将只影响选定的区域以外的区域。
图像掩膜与其类似,用选定的图像、图形或物体,对处理的图像(全部或局部)进行遮挡,来控制图像处理的区域或处理过程。

数字图像处理中,掩模为二维矩阵数组,有时也用多值图像,图像掩模主要用于:
①提取感兴趣区,用预先制作的感兴趣区掩模与待处理图像相乘,得到感兴趣区图像,感兴趣区内图像值保持不变,而区外图像值都为0。
②屏蔽作用,用掩模对图像上某些区域作屏蔽,使其不参加处理或不参加处理参数的计算,或仅对屏蔽区作处理或统计。
③结构特征提取,用相似性变量或图像匹配方法检测和提取图像中与掩模相似的结构特征。
④特殊形状图像的制作。

在所有图像基本运算的操作函数中,凡是带有掩膜(mask)的处理函数,其掩膜都参与运算(输入图像运算完之后再与掩膜图像或矩阵运算)。
利用掩膜(mask)进行“与”操作,即掩膜图像白色区域是对需要处理图像像素的保留,黑色区域是对需要处理图像像素的剔除,其余按位操作原理类似只是效果不同而已。


原文地址:https://www.cnblogs.com/pacino12134/p/9877971.html