2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 计算机视觉基础-图像处理 Task06 边缘检测

计算机视觉基础-图像处理 Task06 边缘检测

时间:2024-07-15 07:05:40

相关推荐

计算机视觉基础-图像处理 Task06 边缘检测

文章目录

Sobel算子Canny边缘检测1.高斯滤波2.计算梯度强度和方向3.非极大值抑制4.用双阈值算法检测和连接边缘函数实现Sobel算子Canny算法

Sobel算子

我们可以使用3×3 的卷积核来进行图像求导:

其中I表示原图片,Gx和Gy分别表示沿图片水平和竖直方向上的变化,∗表示卷积操作

下面以Sobel算子为例讲述如何计算梯度

x方向的Sobel算子为:

若图像G 中一个3×3的窗口为A,要计算梯度的像素点为e,则和Sobel算子进行卷积之后,像素点e在x方向的梯度值为:

其中 ∗为卷积符号,sum表示矩阵中所有元素相加求和。

Canny边缘检测

Canny边缘检测于1986年由JOHN CANNY首次在论文《A Computational Approach to Edge Detection》中提出,就此拉开了Canny边缘检测算法的序幕。

Canny边缘检测是从不同视觉对象中提取有用的结构信息并大大减少要处理的数据量的一种技术,目前已广泛应用于各种计算机视觉系统。Canny发现,在不同视觉系统上对边缘检测的要求较为类似,因此,Canny边缘检测可以实现一种具有广泛应用意义的边缘检测技术。边缘检测的一般标准包括:

以低的错误率检测边缘,也即意味着需要尽可能准确的捕获图像中尽可能多的边缘。检测到的边缘应精确定位在真实边缘的中心。图像中给定的边缘应只被标记一次,并且在可能的情况下,图像的噪声不应产生假的边缘。

为了满足这些要求,Canny使用了变分法。Canny检测器中的最优函数使用四个指数项的和来描述,它可以由高斯函数的一阶导数来近似。

在目前常用的边缘检测方法中,Canny边缘检测算法是具有严格定义的,可以提供良好可靠检测的方法之一。由于它具有满足边缘检测的三个标准和实现过程简单的优势,成为边缘检测最流行的算法之一。

完成一个Canny边缘检测算法可以分为以下四步:

1.高斯滤波

边缘检测结果容易受到图像噪声的影响,图片中一些噪声会大大影像边缘检测。因此为了使图像平滑,可以用高斯滤波器内核与图像进行卷积。 此步骤将使图像稍微平滑,以减少边缘检测器上明显噪声的影响。

大小为(2k+1)×(2k+1)的高斯滤波器核的方程式为:

其中Hij 就是一个权重

下面一个5×5高斯卷积核例子,用于创建相邻图像,σ=1.4(表示卷积运算。)

注意,选择高斯核的大小会影响检测器的性能。 尺寸越大,检测器对噪声的灵敏度越低。 此外,随着高斯滤波器核大小的增加,用于检测边缘的定位误差将略有增加。一般5x5是一个比较不错的trade off(协定)。

2.计算梯度强度和方向

进行高斯滤波后,图像中的边缘可以指向各个方向,接下来使用四个算子来检测图像中的水平、垂直和对角边缘。边缘检测的算子(如Roberts,Prewitt,Sobel等)返回水平和垂直 方向的一阶导数值,由此便可以确定像素点的梯度G和方向θ 。

其中G为梯度强度, θ表示梯度方向,arctan为反正切函数。通过上式我们可以得到一个梯度矩阵G和方向矩阵 θ。

3.非极大值抑制

在每一点上,邻域中心与沿着其对应的梯度方向的两个像素相比,若中心像素为最大值,则保留,否则中心置0,这样可以抑制非极大值,保留局部梯度最大的点,以得到细化的边缘。

对图像进行梯度计算后,仅仅基于梯度值提取的边缘仍然很模糊。对边缘有且应当只有一个准确的响应。而非极大值抑制则可以帮助将局部最大值之外的所有梯度值抑制为0。非极大值抑制是一种边缘稀疏技术,非极大值抑制的作用在于“瘦”边。直观上地看,对第二步得到的图片,边缘由粗变细了。

4.用双阈值算法检测和连接边缘

双阈值法非常简单,我们假设两类边缘:经过非极大值抑制之后的边缘点中,梯度值超过TH的称为强边缘,梯度值小于TH大于TL的称为弱边缘,梯度小于TL的不是边缘。

可以肯定的是,强边缘必然是边缘点,因此必须将T1设置的足够高,以要求像素点的梯度值足够大(变化足够剧烈),而弱边缘可能是边缘,也可能是噪声,如何判断呢?当弱边缘的周围8邻域有强边缘点存在时,就将该弱边缘点变成强边缘点,以此来实现对强边缘的补充。实际中人们发现T1:T2=2:1的比例效果比较好,其中T1可以人为指定,也可以设计算法来自适应的指定,比如定义梯度直方图的前30%的分界线为T1。检查8邻域的方法叫边缘滞后跟踪,连接边缘的办法还有区域生长法等等。

函数实现

Sobel算子

# -*- coding: utf-8 -*-"""cv2.Sobel(src, #参数是需要处理的图像;ddepth, #图像的深度,-1表示采用的是与原图像相同的深度。目标图像的深度必须大于等于原图像的深度dx, #dx和dy表示的是求导的阶数,0表示这个方向上没有求导,一般为0、1、2。dy[, dst[, #输出图片ksize[,#Sobel算子的大小,必须为1、3、5、7。scale[, #缩放导数的比例常数,默认情况下没有伸缩系数;delta[, #可选的增量,将会加到最终的dst中,同样,默认情况下没有额外的值加到dst中;borderType #判断图像边界的模式。这个参数默认值为cv2.BORDER_DEFAULT。]]]]]) """import cv2import numpy as npfrom matplotlib import pyplot as plt#读图img = cv2.imread('IMG/test.jpg',0)sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5)#画图plt.subplot(1,3,1),plt.imshow(img,cmap = 'gray')plt.title('Original'), plt.xticks([]), plt.yticks([])plt.subplot(1,3,2),plt.imshow(sobelx,cmap = 'gray')plt.title('Sobel X'), plt.xticks([]), plt.yticks([])plt.subplot(1,3,3),plt.imshow(sobely,cmap = 'gray')plt.title('Sobel Y'), plt.xticks([]), plt.yticks([])plt.show()

Canny算法

# -*- coding: utf-8 -*-"""cv2.Canny(image, # 输入原图(必须为单通道图)threshold1,threshold2, # 较大的阈值2用于检测图像中明显的边缘[, edges[,apertureSize[, # apertureSize:Sobel算子的大小L2gradient ]]]) # 参数(布尔值):true: 使用更精确的L2范数进行计算(即两个方向的倒数的平方和再开放),false:使用L1范数(直接将两个方向导数的绝对值相加)。"""import cv2import numpy as npimport matplotlib.pyplot as pltoriginal_img = cv2.imread("IMG/test.jpg", 0)# canny边缘检测img1 = cv2.GaussianBlur(original_img,(3,3),0)canny = cv2.Canny(img1, 50, 150)# 画图plt.subplot(1,2,1),plt.imshow(original_img,cmap = 'gray')plt.title('Original'), plt.xticks([]), plt.yticks([])plt.subplot(1,2,2),plt.imshow(canny,cmap = 'gray')plt.title('Canny'), plt.xticks([]), plt.yticks([])plt.show()

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。