用canny算子实现数字图像的边缘检测,简述canny边缘检测方法

  用canny算子实现数字图像的边缘检测,简述canny边缘检测方法

  1.问题描述在处理图像的时候,有时候我们需要图像的边界,或者通过图像获得某些信息。如何有效准确地找到这些边界并显示出来是一个问题,Canny算法可以很好地解决这个问题。

  2.简单介绍一下Canny算法Canny是一种多阶段算法,具体如下:

  高斯滤波:平滑图像,消除噪声梯度和方向计算:利用Sobel算子计算每个像素的梯度和方向。非最大抑制:消除边缘检测引起的杂散。对应(原本不是边缘检测)双阈值:检测真实和潜在的边缘滞后技术:通过抑制弱边缘完成边缘检测和跟踪边界。2.1高斯滤波本质上是一种模糊的图像,玩过PS的人应该都很清楚。原始图像中有许多噪声。用涂抹工具擦拭,但是没有杂音。

  这个阶段类似于卷积。将图像乘以33或55的加权滤镜。

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

  滤波的主要目的是降噪,一般的图像处理算法都需要先降噪。高斯滤波主要是平滑(模糊)图像,也可能增加边缘的宽度。

  2.2计算图像的梯度和方向。对于平滑后的图像,首先在水平和垂直方向上用Sobel核计算水平Gx和垂直Gy(具体计算过程参见链接)。

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

  从而得到图像中各点的梯度值和梯度方向。

  2.3通过非最大抑制NMS计算梯度值和梯度方向后,对图片进行全面扫描,去除不构成边缘的无关像素。

  对于每个像素,检查它是否是梯度方向上其相邻像素中的局部最大值。如图所示:

  点A位于图像的边缘(垂直方向)。渐变方向垂直于边缘。B点和C点位于梯度方向。

  所以检查A点,B点,C点,判断A点是否是局部最大值。如果A点是局部最大值,继续下一阶段;如果点A不是局部最大值,它将被抑制(设置为0)。

  简单地说,NMS得到的结果是一个边缘很细的二值图像。可以理解为所有的边缘点标记为1,非边缘点标记为0。

  2.4双阈值筛选这个阶段主要判断上面的NMS哪些是真边缘,哪些是假边缘。

  在这个阶段,需要设置两个阈值,minVal和maxVal。强度大于maxVal的任何边缘被确定为边缘,而强度小于minVal的边缘被确定为非边缘,并被丢弃。

  maxVal和minVal之间的边为待判定边,进行连续性判断。如果与确定的边相连,则认为是真实边的一部分;否则,它将被丢弃,如下图所示。

  边a大于maxVal,所以是“确定边”。

  虽然边C小于maxVal,但它与边A相连,所以认为它是一条有效边,可以得到一条完整的边曲线。

  然而,虽然边B大于minVal,且与边C位于同一区域,但它并不与任何“确定边”相连,因此边B被丢弃。

  从上面可以看出,minVal和maxVal值的选择对于边缘检测的结果非常重要。

  此外,这一阶段的处理还去除了小像素噪声,因为边缘被假定为长曲线。

  最后得到图像的有效边缘。

  

注意

  如何设置这两个值,我们要分析这两个值的变化对图像的影响。

  MaxVal:它带来了最明显的不同。增加maxVal无疑会导致原来的边界点直接消失。但是当它消失的时候,它会一片片的消失。

  minVal:增加MinVal会导致一些待定像素被丢弃,即两个阈值边界附近的像素会被丢弃。由此产生的现象就是边界被打破,这个非件就消失了。只是边界信息不完整。

  拍视频=cv2。以Canny(img,80,250)为例:分别增加minVal和maxVal。

  增加minVal:(边界有缺陷)

  增加maxVal:(边界出现又消失,边界信息完整)

  在实际应用中,观察梯度图像,如果边界信息缺损,那么适当的减小最小值如果有不想要的区域出现,那么适当的增加最大值实现开放计算机视觉提供了cv2.canny()函数。

  edge=cv2 .Canny(图像,阈值1,阈值2[,边缘[,孔径大小[,L2渐变]])# # #参数图像-输入图片,必须为单通道的灰度图参数阈值一和阈值2 -分别对应于阈值最小值和最大值参数孔径大小-用于计算图片提取的索贝尔核尺寸。默认为3.参数L2梯度-指定计算梯度的等式。当参数为真实的时,采用2.2 中的梯度计算公式,其精度更高;否则采用的梯度计算公式为:梯度G=Gx Gy###具体代码如下

  从绘制精美的图表导入cv2导入数组作为铭牌导入pyplot作为plt img=cv2.imread(test.jpg ,0) edges=cv2 .Canny(img,100,200) plt.subplot(121),plt.imshow(img,cmap=gray) plt.title(原始图像)、plt.xticks([])、plt.yticks([]) plt.subplot(122)、plt.imshow(edges,cmap=gray) plt.title(边缘图像),plt.xticks([]),plt.yticks([]) plt.show()效果

  带滚动条代码

  import numpy as NP import cv 2 def nothing(x):passimg=cv2。im read(/home/cheng/Desktop/1。jpg ,0)cv2。命名窗口(“RES”)cv2。创建trackbar( min , res ,0,25,nothing)cv2。创建trackbar( max , RES ,0,25,nothing)while(1):if cv2。等待键(1)0x ff==27:break maxVal=cv2。gettrackbarpos( max , RES )minVal=1Canny(img,10*minVal,10*maxVal) cv2.imshow(res ,canny)cv2.destroyAllWindows()效果

  4.参考opencv-python(13):Canny边缘检测

  Python - Opencv之谨慎的边缘检测

  谨慎的边缘检测算法

用canny算子实现数字图像的边缘检测,简述canny边缘检测方法