OpenCV|OpenCV学习笔记(7)--Canny Edge Detection Canny边缘检测

Canny 边缘检测是很流行的边缘检测算法,是在1986年由John F.Canny提出的。它是一个多级(multi-stage)算法。下面详细介绍每一级。
1.减少噪音
因为边缘检测对噪音非常敏感,所以实现边缘检测的第一步,是使用高斯滤波器对图像中的噪音进行移除。
2.寻找图像中的强度梯度(Intensity Gradient)
用Sobel kernel在水平和垂直方向过滤来平滑图像,并取得图像在水平和垂直方向的一阶导数(first derivate)
利用以上取得的两个图像,可以用以下公式找到每个像素的边缘梯度和方向:
OpenCV|OpenCV学习笔记(7)--Canny Edge Detection Canny边缘检测
文章图片

梯度方向总是垂直于边。它被四舍五入为四个角中的一个,表示垂直、水平和两个对角线方向。
3.Non-maximum Suppression非最大值抑制
上述获取梯度的大小和方向之后,一张移除了不想要的像素(这些像素是指不组成边的)全图,为了得到这张全图(为了移除这些像素),对每一个像素进行查验,判断它是否是梯度方向上的像零点的相邻最大值(local maximum)。
OpenCV|OpenCV学习笔记(7)--Canny Edge Detection Canny边缘检测
文章图片

上图为例,梯度方向是正交与(is normal to )边,点A在边上(垂直方向),点B和点C在梯度方向上。所以点A就会被查验是否和点B、点C相比较,判断它是否是相邻最大值(local maximum)。是的话,A被认为是下一个next stage; 不是的话,则为0。
得到一个“thin edge".
4.Hysteresis Thresholding(滞后阈值法)
这一步,来判断上诉结果中,哪一个是真正的边。为了实现这个,需要两个minVal和maxVal的阈值。所有边的强度梯度超过maxval确定为边,低于minVal的确定不为边(丢弃)。基于中间的判断是否为边是根据其连续性(connectivity);如果它和"确定边"的像素相连,则为边;如果和"不为边"的像素相连,则不为边(丢弃)。如下图:
OpenCV|OpenCV学习笔记(7)--Canny Edge Detection Canny边缘检测
文章图片

上图中,边A是在maxVal之上,是“确定边”,虽然边C在maxVal之下(minVal)之上,但它和边A相连,所以认为它是有效边,这样我们就得到了一个完整的曲线。但是对于边B,虽然和边C在同一个区域,但它没有和“确认边”相连,故丢弃。
在这个过程中,选择好一个minVal和maxVal非常重要。
这一步,we get strong edges.

用OpenCV实现Canny边缘检测:
cv2.Canny(src,minVal,maxVal,aperture_size,L2gradient)
其中aperture_size表示第二步中sobel的kernel size,通常为3
【OpenCV|OpenCV学习笔记(7)--Canny Edge Detection Canny边缘检测】L2gradient表示是否使用第二步的公式来求解梯度大小,True--->是
False--->不是,使用的是:OpenCV|OpenCV学习笔记(7)--Canny Edge Detection Canny边缘检测
文章图片
(默认为false)

import cv2 import numpy as np from matplotlib import pyplot as pltimg = cv2.imread("r.jpg",0)edges = cv2.Canny(img,100,200)plt.subplot(121),plt.imshow(img,cmap ="gray") plt.title("Orignal"),plt.xticks([]),plt.yticks([])plt.subplot(122),plt.imshow(edges,cmap="gray") plt.title("Edge Image"),plt.xticks([]),plt.yticks([])plt.show()

实现:
OpenCV|OpenCV学习笔记(7)--Canny Edge Detection Canny边缘检测
文章图片


    推荐阅读