Canny边缘检测算法基本过程中第一步是什么(canny边缘检测算法原理),本文通过数据整理汇集了Canny边缘检测算法基本过程中第一步是什么(canny边缘检测算法原理)相关信息,下面一起看看。

今天的思想是利用Canny边缘检测算法来构建一种能够勾勒出图像上任意物体边缘的算法。

首先,让描述Canny边缘检测器:

Canny边缘检测算子是一种边缘检测算子,它使用多级算法来检测图像中的大范围边缘。它是由约翰f坎尼在1986年开发的。Canny还提出了边缘检测的计算理论,并解释了这项技术的工作原理。

Canny边缘检测算法由五个步骤组成:

降噪;

梯度计算;

非最大抑制;

双门槛;

滞后边缘跟踪。

应用这些步骤后,您将能够获得以下结果:

左边是原始图像,右边是经过处理的图像

最后值得一提的是,该算法是基于灰度图像的。因此,在执行上述步骤之前,应先将图像转换为灰度。

因为场景背后的数学主要基于导数(参见步骤2:梯度计算),所以边缘检测结果对图像噪声高度敏感。

消除图像噪声的一种方法是使用高斯模糊来平滑图像。因此,图像卷积技术使用高斯核(3x3,5x5,7x7等。).内核大小取决于预期的模糊效果。基本上,核心越小,模糊越不明显。在我们的例子中,我们将使用55高斯核函数。

大小为(2k 1)(2k 1)的高斯滤波器核的等式为:

高斯滤波器核方程

用于生成高斯5x5内核的Python代码:

将numpy作为np导入

def gaussian_kernel(大小,sigma=1):

size=int(size) //2

x,y=np.mgrid[-size:size 1,-size:size 1]

正常=1/(2.0 * np.pi * sigma**2)

g=NP . exp(-((x * * 2y * * 2)/(2.0 * sigma * * 2)))*正常

返回g

应用高斯模糊后,我们得到以下结果:

原始图像(左)-使用高斯滤镜的模糊图像(西格玛=1.4,内核大小5x5)

梯度计算步骤通过使用边缘检测算子计算图像的梯度来检测边缘强度和方向。

边缘对应于像素强度的变化。要检测它,最简单的方法是应用滤镜来突出显示两个方向上的强度变化:水平(x)和垂直(y)

当平滑图像时,计算导数Ix和Iy。它可以通过分别用Sobel核Kx和Ky进行卷积I来实现:

Sobel滤波器用于两个方向(水平和垂直)

然后,梯度的振幅g和斜率计算如下:

梯度和边缘方向

这里s如何将Sobel滤波器应用于图像,以及如何得到强度和边缘方向矩阵。Python代码如下:

从scipy导入ndimage

def sobel_filters(img):

Kx=np.array([[-1,0,1],[-2,0,2],[-1,0,1]],np.float32)

Ky=np.array([[1,2,1],[0,0,0],[-1,-2,-1]],np.float32)

IX=n image . filters . convolve(img,Kx)

iy=n image . filters . convolve(img,Ky)

G=np.hypot(Ix,Iy)

G=G/G.max() * 255

=NP . arctan 2(Iy,Ix)

返回(G,)

模糊图像(左)-梯度强度(右)

结果几乎在意料之中。我们可以看到有些边缘很厚,有些边缘很薄。非最大抑制步骤将有助于我们减少厚度。

另外,渐变强度等级在0到255之间,不均匀。产生的边缘应该具有相同的强度(即白色像素=255)。

理想情况下,最终图像的边缘应该很细。因此,我们必须执行非最大值抑制,以使边缘更薄。

原理很简单:算法遍历梯度强度矩阵上的所有点,在边缘方向找到最大值的像素。

让让我们举个简单的例子:

图中左上角的红框表示处理后的梯度强度矩阵的一个强度像素。对应的边缘方向用橙色箭头表示,其角度为-pi弧度(/- 180度)。

聚焦左上角的红色方块像素。

边缘是橙色虚线(从左到右水平)。该算法的目的是检查同方向像素的强度是高于还是低于处理后像素的强度。在上面的例子中,像素(I,j)正在被处理,同方向的像素用蓝色(I,j-1)和(I,j 1)高亮显示。如果这两个像素中的一个比正在处理的像素更强,那么将只保留更强的一个。像素(I,j-1)看起来更强,因为它是白色的(值255)。因此,当前像素(I,j)的亮度值被设置为0。如果在边缘方向没有具有更强值的像素,则保留当前像素的值。

现在让让我们关注另一个例子:

在这种情况下,方向是橙色虚线对角线。所以这个方向最强的像素是像素(i-1,j 1)。

让让我们总结一下。每个像素有2个主要标准(弧度的边缘方向和像素强度(0到255之间))。基于这些输入,非最大抑制步长为:

创建初始化为0的矩阵,其大小与原始梯度强度矩阵相同;

根据角度矩阵的角度值识别边缘方向;

检查相同方向上的像素是否比当前处理的像素具有更高的亮度;

返回使用非最大抑制算法处理的图像。

Python代码如下:

def非最大抑制(img,D):

m,N=img.shape

Z=np.zeros((M,N),dtype=np.int32)

角度=D * 180。/np.pi

角度[角度0]=180

对于范围内的I(1,M-1):

对于范围(1,N-1)中的j:

尝试:

q=255

r=255

#角度0

如果(0=角度[i,j] 22.5)或(157.5=角度[i,j]=180):

q=img[i,j 1]

r=img[i,j-1]

#角度45

elif (22.5=角度[i,j] 67.5):

q=img[i 1,j-1]

r=img[i-1,j 1]

#角度90

elif (67.5=角度[i,j] 112.5):

q=img[i 1,j]

r=img[i-1,j]

#角度135

elif (112.5=angle[i,j] 157.5):

q=img[i-1,j-1]

r=img[i 1,j 1]

if (img[i,j]=q)和(img[i,j]=r):

Z[i,j]=img[i,j]

否则:

Z[i,j]=0

除了e:

及格

返回Z

结果是相同的图像,但边缘更细。但是,我们仍然可以注意到边缘亮度的一些变化:一些像素似乎比其他像素更亮,我们将在最后两步中尝试弥补这一缺陷。

非最大抑制的结果

双阈值步骤旨在识别3种像素:强、弱和不相关:

强像素意味着像素的强度如此之高,以至于我们确信它们对最终的边缘有贡献。

弱像素是强度值不足以被认为是强的,但也不足以被认为与边缘检测无关的像素。

其他像素被认为与边缘无关。

现在您可以看到这两个阈值代表了什么:

高阈值用于识别强像素(强度高于高阈值)。

低阈值用于识别无关像素(强度低于低阈值)

强度在两个阈值之间的所有像素都被标记为弱,滞后机制(下一步)将帮助我们识别哪些可以被认为是强的,哪些被认为是不相关的。

定义阈值(img,低阈值比率=0.05,高阈值比率=0.09):

highThreshold=img . max()* highThreshold ratio;

low threshold=highThreshold * low threshold ratio;

m,N=img.shape

res=np.zeros((M,N),dtype=np.int32)

weak=np.int32(25)

strong=np.int32(255)

strong_i,strong _ j=NP . where(img=high threshold)

zeros_i,zeros _ j=NP . where(img low threshold)

weak_i,weak _ j=NP . where((img=low threshold))

res[strong_i,strong_j]=strong

res[weak_i,weak_j]=弱

返回(res,弱,强)

该步骤的结果是只有2个像素强度值(强和弱)的图像:

非最大抑制图像(左)-阈值结果(右)

根据阈值结果,当且仅当被处理像素周围的至少一个像素是强像素时,滞后由被转换成强像素的弱像素组成,如下:

定义滞后(img,弱,强=255):

m,N=img.shape

对于范围内的I(1,M-1):

对于范围(1,N-1)中的j:

if (img[i,j]==弱):

尝试:

if ((img[i 1,j-1]==strong)或(img[i 1,j]==strong)或(img[i 1,j 1]==strong)

or (img[i,j-1]==strong)或(img[i,j 1]==strong)

or (img[i-1,j-1]==strong)或(img[i-1,j]==strong)或(img[i-1,j 1]==strong)):

img[i,j]=strong

否则:

img[i,j]=0

除了e:

及格

返回img

更多Canny边缘检测算法基本过程中第一步是什么(canny边缘检测算法原理)相关信息请关注本站。