canny算子的边缘检测算法,canny边缘检测算法步骤

  canny算子的边缘检测算法,canny边缘检测算法步骤

  本文主要介绍了如何利用Canny算法检测纸张上硬币的边缘。文章中的示例代码解释得很详细,感兴趣的朋友可以跟着边肖试一试。

  00-1010 1.问题背景2。Canny算法(1)、高斯平滑(2) Sobel算子计算梯度(3)非最大化抑制(4)滞后边缘跟踪。

  

目录

 

  纸上有一枚一元银币。能否借助Canny和Hough找到它的坐标方程?

  要确定一个圆的坐标方程,首先要检测它的边缘,然后求出它在纸上的相对位置和半径。

  本文采用Canny算法对纸币上的银币边缘进行检测。

  

一、问题背景

 

  Canny可以用来获取图像中物体的边缘,其步骤如下

  高斯平滑用于计算图像梯度(记录其强度和方向),使用非最大值抑制,并使用滞后边缘跟踪。经过以上四个步骤,我们得到的纸张上的硬币边缘提取效果如下。

  

二、Canny 算法

 

  类GaussianSmoothingNet(nn。模块):

  def __init__(self) - None:

  超级(GaussianSmoothingNet,self)。__init__()

  filter_size=5

  #形状为(1,5)且方差为1.0的高斯滤波器核

  generated _ filters=Gaussian(filter _ size,std=1.0)。整形([1,过滤器大小])

  # GFH (V) 3360水平(垂直)高斯滤波器水平(垂直)高斯滤波器内核

  自我。GFH=nn。Conv2d(1,1,kernel_size=(1,filter_size),padding=(0,filter_size//2))

  自我。GFV=nn。Conv2d(1,1,kernel_size=(filter_size,1),padding=(filter_size//2,0))

  #将W的值设置为高斯平滑内核,将B的值设置为0.0

  init_parameter(自身。GFH,generated_filters,np.array([0.0]))

  init_parameter(自身。GFV,生成_过滤器。t,np.array([0.0]))

  定义转发(自身,img):

  Img _ r=img [:033601] #取出RGB三个通道的数据

  img_g=img[:1:2]

  img_b=img[:2:3]

  #水平和垂直过滤图片的三个通道。

  迷离_img_r=自我。GFV(自我。GFH(img_r))

  迷离_img_g=自我。GFV(自我。GFH(img_g))

  迷离_img_b=自我。GFV(自我。GFH(img_b))

  #合并成一张图片

  模糊_ img=torch . stack([模糊_img_r,模糊_img_g,模糊_img_b],dim=1)

  模糊_ img=torch . stack([torch . squeeze(模糊_img)])

  返回模糊_img

  高斯平滑(模糊)后的图像比原图更加模糊,如下图右边的银币所示。

  请参阅:完整代码的gaussian_smoothing。

  

(一)、高斯平滑

 

  obel算子计算梯度

  

PAI = 3.1415926

 

  将梯度强度当作图片进行输出,得到右下图最右侧图片,可知硬币的边缘区域梯度值较大(越大越亮)

  

 

  完整代码见:sobel_filter

  

 

  

(三)非极大化抑制

 

  非极大化抑制(NMS)的过程为:

  

  • 将梯度强度矩阵grad_magnitude的每一点都作为中心像素点,与其同向或者反向的两个相邻点(共有8个)的梯度强度进行比较。

  • 若中心点的梯度小于这两个方向上的梯度,则点中心的的梯度值设为0

 

  进过上面的两个步骤,可以用一个像素的宽度替代了梯度屋脊效应,同时保留了屋脊的梯度强度(最大的梯度)。

  

class NonMaxSupression(nn.Module):

 

  directional_filter的用处是什么?

  

# 输入

 

  可知其获取输入的八个方向的梯度值(在当前项目的代码中,为获取当前点梯度与其它8个方向梯度之差)

  根据梯度的强度和方向,将方向分成8个类别(即对于每一点有八个可能方向),如上代码中 "米" 型图所示。

  下面给出计算当前点正向邻域的相邻点的梯度强度的过程(反向同理)

  梯度方向grad_orientation: 0, 1,, 2, 3, 4, 5, 6, 7 (共有8哥方向)

  各方向梯度强度all_orient_magnitude: [[..方向0的梯度..], [..方向1的梯度..], ..., [..方向7的梯度..]]

  故对于方向为 i 的点,其在梯度强度中的位置为 all_orient_magnitude[i][x, y],将all_orient_magnitude变化为一维向量后,对应的位置为position = current_orient × pixel_count + pixel_offset,我们就可以根据这个位置信息拿到当前点与其正向邻域点梯度强度之差(同理也可以拿到反向的)。

  以下为辅助图示:

  

 

  最后效果如下右侧图所示(左侧为未进行最大化抑制的图)

  

 

  完整代码见:nonmax_supression

  

 

  

(四)滞后边缘跟踪

 

  我们思考后发现,到目前为止仍有如下几个问题:

  

  • 如果图像中有噪声,可能会出现边缘无关的点(伪边)

  • 边缘点时阴时明

 

  所以最后我们就需要进行滞后边缘跟踪了,其步骤如下:

  

  • 设定两个阈值(一高一低),将梯度强度小于低阈值的像素点的梯度强度设为0,得到图像A

  • 将梯度强度小于高阈值的像素点的梯度强度设为0,得到图像B

 

  我们知道由于A的阈值较低,故边缘保留较完整,连续性较好,但是伪边可能也较多,B正好与A相反。

  据此我们设想以B为基础,A为补充,通过递归追踪来补全B中边缺失的像素点。

  

to_bw = lambda image: (image > 0.0).astype(float)

 

  如下图为依次为低阈值、高阈值的效果图

  

 

  如下为滞后边缘跟踪后的效果图

  

 

  可知其相对上方左侧图,一些伪边被消除了,相对右侧图,细节更加的丰富。

  完整代码见:hysteresis_thresholding

  以上就是Python利用Canny算法检测硬币边缘的详细内容,更多关于Python Canny检测边缘的资料请关注盛行IT软件开发工作室其它相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: