Canny 边缘检测算法 是 John F. Canny 于 1986年开发出来的一个多级边缘检测算法,也被很多人认为是边缘检测的最优算法,.
最优边缘检测的三个主要评价标准是:
Canny边缘检测的步骤
1.消除噪声
由于边缘检测对图像中的噪声很敏感,所以第一步是使用5x5的高斯滤波器去除图像中的噪声。
计算过程:将高斯核K归一化变为归一化高斯核H后,遍历平滑图像中的每一个像素点。
详细介绍参见我之前写的博文:【OpenCV-图像处理】图像平滑处理函数
2.计算图像的梯度
计算梯度幅值和方向。 此处,按照Sobel滤波器的步骤,用Sobel核在水平方向和垂直方向对平滑后的图像进行滤波,得到水平方向(Gx)和垂直方向(Gy)的一阶导数。:
a.使用下列公式计算梯度幅值和方向:
梯度方向近似到四个可能角度之一(一般 0°, 45°, 90°, 135°)
计算过程:
详细介绍参见我之前写的博文:【OpenCV-图像处理】如何计算图像梯度,以及如何使用梯度来检测边缘
3.非极大值抑制
这一步排除非边缘像素, 仅仅保留了一些细线条(候选边缘)。
4.滞后阈值(双阈值检测)
最后一步,Canny 使用了滞后阈值,滞后阈值需要两个阈值(高阈值和低阈值):
Canny 推荐的 高:低 阈值比在 2:1 到3:1之间。
edges = cv2.Canny ( InputArray image,
double threshold1,
double threshold2,
int apertureSize = 3,
bool L2gradient = false
)
参数 | 说明 |
---|---|
image | 8位输入图像(灰度图像) |
edges | 输出图像 (支持原地计算,可为输入图像) |
threshold1 | 迟滞过程的第一个阈值minVal |
threshold2 | 迟滞过程的第二个阈值maxVal |
apertureSize | Sobel算子的核大小,缺省值是3 |
L2gradient | 它指定了寻找梯度大小的方程。如果为真,则使用上述更准确的方程,否则使用此函数:Edge_Gradient(G)= |
#######Canny边缘检测########
import numpy as np
import cv2
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #文字字体为黑体
#读取图像
img = cv2.imread('car.jpg',0) #第二个参数0与cv2.IMREAD_GRAYSCALE等价,代表转换为灰度图
#Canny边缘检测
edges1 = cv2.Canny(img,100,200) #阈值为100-200
edges2 = cv2.Canny(img,20,200) #阈值为100-200
edges3 = cv2.Canny(img,100,400) #阈值为100-200
plt.subplot(221),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(222),plt.imshow(edges1,cmap = 'gray')
plt.title('Edge Image1(阈值为100-200 )'), plt.xticks([]), plt.yticks([])
plt.subplot(223),plt.imshow(edges2,cmap = 'gray')
plt.title('Edge Image2(阈值为20-200 )'), plt.xticks([]), plt.yticks([])
plt.subplot(224),plt.imshow(edges3,cmap = 'gray')
plt.title('Edge Image3(阈值为100-400 )'), plt.xticks([]), plt.yticks([])
plt.show()
运行结果:
主要参考于OpenCV官方网站:http://www.opencv.org.cn/
目前博主已更新OpenCV平滑处理函数、形态学操作函数的详细介绍,链接如下:
【OpenCV-图像处理】图像平滑处理函数
【OpenCV-图像处理】形态学变换函数
【OpenCV-图像处理】图像阈值处理
【OpenCV-图像处理】如何计算图像梯度,以及如何使用梯度来检测边缘
<后续还会继续翻译和整理【OpenCV-图像处理】相关内容,如果需要,可持续关注我哦~> |
<翻译和整理不易,留个赞或评论支持一下我吧^^>
如有疑问,欢迎批评指正^^