Canny边缘检测

Posted missdx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Canny边缘检测相关的知识,希望对你有一定的参考价值。

Canny边缘检测

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

  • 高斯滤波器

技术图片

 

  •  梯度和方向

技术图片

 

  •  非极大值抑制
指寻找像素点局部最大值,将非极大值点所对应的灰度值置为0,这样可以剔除掉一大部分非边缘的点。要进行非极大值抑制,就首先要确定像素点C的灰度值在其8值邻域内是否为最大。图1中蓝色的线条方向为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。检测结果还是包含了很多由噪声及其他原因造成的假边缘。因此还需要进一步的处理。


非极大值抑制中有两种方法。
方法一:线性插值法
技术图片

 

 方法二:

技术图片

 

  •  双阈值检测
技术图片

 

 

import cv2 as cv
import numpy as np


img = cv.imread(lena.jpg, cv.IMREAD_GRAYSCALE)

c = cv.Canny(img, 80, 150)

cv.imshow(c, c)
cv.waitKey(0)
cv.destroyAllWindows()

技术图片

 

 其中, c = cv.Canny(img, 80, 150) 后面两个数字表示双阈值检测中的最大值和最小值,适当的调整,可以改变检测结果。



以上是关于Canny边缘检测的主要内容,如果未能解决你的问题,请参考以下文章

openCV Canny 边缘检测改进

Canny边缘检测算法的步骤和理解

Canny边缘检测算法(python 实现)

Canny边缘检测

Matlab边缘检测问题

转载传统车道线检测-canny边缘检测-霍夫变换-完整代码(python)