Canny边缘检测 原理&&python代码

Canny边缘检测

分为5步:

  • 1) 使用高斯滤波器,以平滑图像,滤除噪声。
  • 2) 计算图像中每个像素点的梯度强度和方向。
  • 3) 应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。
  • 4) 应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。
  • 5) 通过抑制孤立的弱边缘最终完成边缘检测。

1.高斯滤波器

原理就是距离目标像素越近的相邻像素,其高斯核值越大,类似高斯函数,越近,影响越大。此处高斯核还进行了归一化处理。

为了尽可能减少噪声对边缘检测结果的影响,所以必须滤除噪声以防止由噪声引起的错误检测。为了平滑图像,使用高斯滤波器与图像进行卷积,该步骤将平滑图像,以减少边缘检测器上明显的噪声影响。

下面是一个尺寸为3x3的高斯卷积核的例子(需要注意归一化):

2.梯度检测

边缘检测就是梯度检测,这里要知道梯度的大小和方向

这里用sobel算子,sobel算子有X和Y方向,

合起来的梯度大小和方向就是   

扫描二维码关注公众号,回复: 5560346 查看本文章

3.非极大值抑制

顾名思义:只保留大梯度,不是极大值就抑制他。

非极大值抑制是一种边缘稀疏技术,非极大值抑制的作用在于“瘦”边。对图像进行梯度计算后,仅仅基于梯度值提取的边缘仍然很模糊。而非极大值抑制则可以帮助将局部最大值之外的所有梯度值抑制为0,对梯度图像中每个像素进行非极大值抑制的算法是:

  • 1)        将当前像素的梯度强度与沿正负梯度方向上的两个像素进行比较。
  • 2)        如果当前像素的梯度强度与另外两个像素相比最大,则该像素点保留为边缘点,否则该像素点将被抑制。

通常我们选择线性插值,如下图中心点c,假设梯度方向是那条斜线,则分别还有上下两个交点,即该C像素的临近点,怎样计算两个交点的值呢?就是含有权值的加和,如下所示,权值由距离的比值来算。

 4.双阀值。

一般的边缘检测算法用一个阀值来滤除噪声或颜色变化引起的小的梯度值,而保留大的梯度值。Canny算法应用双阀值,即一个高阀值和一个低阀值来区分边缘像素。

  • 如果 边缘像素点梯度值>高阀值,则被认为是强边缘点。
  • 如果 低阀值<边缘梯度值<高阀值,则标记为弱边缘点。
  • 如果 边缘像素点梯度值<低阀值,则被抑制掉。

5.抑制孤立低阈值点

此时,强边缘被划分为边缘,小于低阈值的被抑制,剩下弱边缘等待被分类,弱边缘有可能是真实的边缘,也有可能是噪声或者颜色变化引起的。

通常,由真实边缘引起的弱边缘像素将连接到强边缘像素,而噪声响应未连接。为了跟踪边缘连接,通过查看弱边缘像素及其8个邻域像素,只要其中一个为强边缘像素,则该弱边缘点就可以保留为真实的边缘。


5步完成,就完成了Canny边缘检测算法,当然这些步骤大牛们已经封装好了代码,我们应用的时候只需要直接调用Canny函数即可。

import cv2
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

img=cv2.imread('F://from 2to7 notebook//images//lena.jpg')
v1=cv2.Canny(img,80,150)
v2=cv2.Canny(img,50,100)
res=np.hstack((v1,v2))
cv2.imshow('res',res)
cv2.waitKey(0)
cv2.destroyAllWindows()

当阈值大的时候,检测的边缘少;当阈值小的时候,检测的边缘多而杂;具体两个阈值选多少,还是要看具体情况而定。

参考:https://www.cnblogs.com/mightycode/p/6394810.html

参考:https://www.cnblogs.com/techyan1990/p/7291771.html

猜你喜欢

转载自blog.csdn.net/xiachong27/article/details/88385123
今日推荐