Canny 边缘检测是很流行的边缘检测算法,是在1986年由John F.Canny提出的。它是一个多级(multi-stage)算法。下面详细介绍每一级。
1.减少噪音
因为边缘检测对噪音非常敏感,所以实现边缘检测的第一步,是使用高斯滤波器对图像中的噪音进行移除。
2.寻找图像中的强度梯度(Intensity Gradient)
用Sobel kernel在水平和垂直方向过滤来平滑图像,并取得图像在水平和垂直方向的一阶导数(first derivate)
利用以上取得的两个图像,可以用以下公式找到每个像素的边缘梯度和方向:
文章图片
梯度方向总是垂直于边。它被四舍五入为四个角中的一个,表示垂直、水平和两个对角线方向。
3.Non-maximum Suppression非最大值抑制
上述获取梯度的大小和方向之后,一张移除了不想要的像素(这些像素是指不组成边的)全图,为了得到这张全图(为了移除这些像素),对每一个像素进行查验,判断它是否是梯度方向上的像零点的相邻最大值(local maximum)。
文章图片
上图为例,梯度方向是正交与(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);如果它和"确定边"的像素相连,则为边;如果和"不为边"的像素相连,则不为边(丢弃)。如下图:
文章图片
上图中,边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--->不是,使用的是:
文章图片
(默认为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-Python实战(18)——深度学习简介与入门示例
- opencv|图像处理之椒盐噪声的添加与去除
- 人脸识别|【人脸识别系列】| 实现人脸截图保存并编写128维特征向量
- opencv|网络爬虫入门练习
- OpenCV|【OpenCV 完整例程】89. 带阻滤波器的传递函数
- OpenCV|【OpenCV 完整例程】90. 频率域陷波滤波器
- OpenCV|【OpenCV 完整例程】22. 图像添加非中文文字
- OpenCV|【OpenCV 完整例程】91. 高斯噪声、瑞利噪声、爱尔兰噪声
- opencv|python+opencv车道线,实线虚线的检测