Canny边缘检测实例

边缘检测发展

Canny 边缘检测是一种从不同视觉对象中提取有用结构信息并显着减少要处理的数据量的技术。它已广泛应用于各种计算机视觉系统。 Canny 发现,在不同的视觉系统上应用边缘检测的要求是比较相似的。因此,可以在各种情况下实施满足这些要求的边缘检测解决方案。边缘检测的一般标准包括:
1:以低错误率检测边缘,这意味着检测应准确捕捉图像中显示的尽可能多的边缘
2:从操作员处检测到的边缘点应准确定位在边缘的中心。
3:图像中的给定边缘应仅标记一次,并且在可能的情况下,图像噪声不应产生错误边缘。

Canny边缘检测的步骤

1:应用高斯滤波去平滑图像为了去除噪音的影响。
2:计算图像的x轴和y轴的梯度,并计算梯度的合方向
3:使用非极大值抑制,对那些伪边界点抑制
4:把min_max应用到上面得到的图像
5:通过滞后跟踪边缘:通过抑制所有其他弱且未连接到强边缘的边缘来完成边缘的检测。

高斯滤波

因为噪音的存在会轻易地影响到图像的边界,因此我们在进行边缘检测的开始要对图像进行平滑滤波,其中比较常用的滤波器就是高斯滤波,我们将其记做为 H H H,其尺寸是 ( 2 k + 1 , 2 k + 1 ) (2k+1,2k+1) (2k+1,2k+1)下面给出其表达式:
H i j = 1 2 π σ 2 e x p ( − ( i − ( k + 1 ) ) 2 + ( j − ( k + 1 ) ) 2 2 σ 2 1 < = i , j < = ( 2 k + 1 ) H_{ij} = \frac{1}{2\pi\sigma^2}exp(-\frac{(i-(k+1))^2+(j-(k+1))^2}{2\sigma^2} 1 <= i,j <= (2k+1) Hij=2πσ21exp(2σ2(i(k+1))2+(j(k+1))21<=i,j<=(2k+1)
举例给出一个当 k = 2 k= 2 k=2的矩阵 H H H:
H = 1 159 [ 2 4 5 4 2 4 9 12 9 2 5 12 15 12 5 4 9 12 9 4 2 4 5 4 2 ] H = \frac{1}{159}\begin{bmatrix}2&4&5&4&2\\ 4&9&12&9&2\\5&12&15&12&5\\4&9&12&9&4\\2&4&5&4&2\end{bmatrix} H=1591245424912945121512549129422542
记我们的图像矩阵为 A A A,那么高斯滤波和我们图像做下面的卷积运算:
B = H ∗ A B = H * A B=HA
使用 H H H从左到右从上到下对原图像进行平滑处理。

计算图像的梯度大小和方向

首先给出计算梯度大小的公式:
G = G x 2 + G y 2 θ = a r c t a n ( G y G x ) G = \sqrt{G_x^2 + G_y^2} \\ \theta = arctan(\frac{G_y}{G_x}) G=Gx2+Gy2 θ=arctan(GxGy)
如下面的图像所示:虽然使用了arctan反三角函数,但是我们在这里却只使用了四个角度 0 。 , 4 5 。 , 9 0 。 , 13 5 。 0^。,45^。,90^。,135^。 04590135算出来的梯度距离那个方向近,我们就将其归为哪一类。例如:当 θ ∈ [ 0 , 22.5 ] o r [ 157.5 , 180 ] \theta \in[0,22.5] or [157.5,180] θ[0,22.5]or[157.5,180]时,我们将其映射到 0 。 0^。 0
如下面的图示:
在这里插入图片描述

非极大值抑制

在一些实施方式中,算法将连续梯度方向分类为一小组离散方向,然后在前一步的输出(即,边缘强度和梯度方向)上移动3×3滤波器。在每个像素时,如果其幅度不大于梯度方向上的两个邻居的大小,则抑制中心像素的边缘强度(通过将其值设置为0)。例如:
1:如果中心点梯度角度为0°(即边缘处于南北方向),如果其梯度幅度大于东部和西部方向上的像素的大小,则认为该点将被认为是在边缘上。
2:如果圆角梯度角度为90°(即边缘在东西方向上),如果其梯度幅度大于北部和南方方向的像素的大小,则将视线视为边缘。
3:如果圆角梯度角度为135°(即边缘处于东北 - 西南方向),如果其梯度大小大于西北部和东南部的像素处的大小,则将视线视为在边缘上方向,
4:如果圆角梯度角度为45°(即边缘处于西北部 - 东南方向),如果其梯度幅度大于东北和西南西北部的像素的大小,则视线被认为是在边缘上方向。
在这里插入图片描述
做一个试例:对于中心点A来说,其梯度角度为0,此时对其左右的两个点的梯度大小进行比较,如果该点的梯度大小大于其他两个,那么A点的梯度大小得以保留,否则将大小其抑制,设置为0。

双阈值

在这里插入图片描述
在施加非最大抑制之后,剩余的边缘像素在图像中提供了更准确的真实边缘的表示。然而,一些边缘像素仍然是由噪声和颜色变化引起的。为了解释这些杂散的响应,必须用弱梯度值滤除边缘像素,并具有高梯度值的边缘像素。这是通过选择高阈值和低阈值来实现的。如果边缘像素的梯度值高于高阈值,则标记为强边像素。如果边缘像素的梯度值小于高阈值并且大于低阈值,则标记为弱边缘像素。如果边缘像素的梯度值小于低阈值,则将抑制它。经验确定了两个阈值,并且它们的定义取决于给定输入图像的内容。

边缘跟踪滞后

到目前为止,强边像素肯定应该参与最终边缘图像,因为它们从图像中的真实边缘提取。但是,将有一些关于弱边缘像素的争论,因为这些像素可以从真正的边缘或噪声/颜色变化中提取。为了实现准确的结果,应拆除由后一种原因引起的弱边缘。通常,由真正边缘引起的弱边缘像素将连接到强边像素,而噪声响应是未连接的。要跟踪边缘连接,通过查看弱边缘像素及其8个连接的邻域像素来应用BLOB分析。只要有一个涉及BLOB的一个强边像素,可以将弱边缘点识别为应保留的。

opencv实现canny边缘检测

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

#cv2.canny(img, min_val. max_val, kernal_size, L2gradient=False(default))
img = cv2.imread('orginal.JPG', 0)
image = cv2.Canny(img, 100, 200, 5)
#print(img.dtype)
plt.subplot(121)
plt.imshow(img, cmap='gray')
plt.axis('off')
plt.xticks([])
plt.yticks([])
plt.title('orginal image')

plt.subplot(122)
plt.imshow(image, cmap='gray')
plt.xticks([])
plt.yticks([])
plt.axis('off')
plt.title('Caany dection')

plt.show()
new = np.concatenate((img, image), axis=1)
cv2.imwrite('combined.jpg', new)

在这里插入图片描述

结语

上文的认识大多来自于维基百科,还有一些内容没有写的,如果有哪些不足或者错误的地方还请各位uu前来指正。
有关canny的详细内容可阅读https://en.wikipedia.org/wiki/Canny_edge_detector

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐