opencv-python常用函数解析及参数介绍(七)——边缘检测

前言

在之前的文章中我们介绍了使用膨胀和腐蚀、计算图像梯度的方式来获取图像的轮廓,本篇文章将介绍另外一种可以获取图像轮廓的方法——边缘检测

1.基本概念

首先我们来看一下边缘检测的基本过程

1) 滤波

使用高斯滤波器,以平滑图像,滤除噪声
在这里插入图片描述
H即为高斯分布的卷积核,初看上去似乎这个矩阵似乎很莫名其妙,但其实他的特征很明显,中间的数值要比周围的大,因为高斯滤波使用的卷积核是满足高斯分布,即正态分布的(是的,高斯分布就是正态分布)

关于高斯滤波的细节请参考之前的文章:opencv-python常用函数解析及参数介绍(三)——图像滤波

2) 计算梯度

计算图像中每个像素点的梯度强度和方向。

我们以3x3的sobel算子为例计算梯度
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在之前的文章中我们知道,sobel的梯度因为算子可以分成Sx和Sy,所以梯度也可以分为两个梯度,一个是Gx,更加侧重左右的偏差,即侧重竖直方向的边缘,而Gy更加侧重上下的偏差,即侧重水平方向的边缘,那么我们得到了x方向的梯度Gx,y方向的梯度Gy,那么总梯度应该为

G x 2 + G y 2 \sqrt{Gx^2+Gy^2} Gx2+Gy2
这里我们只求得了梯度的大小,那么如何计算梯度的方向呢

我们已经知道了x方向的梯度大小为Gx,y方向的梯度大小为Gy
假设梯度方向与 x 轴方向的夹角为 θ 则 t a n θ = G y G x 即 : θ = a r c t a n ( G y G x ) 假设梯度方向与x轴方向的夹角为 \theta \\则tan\theta = \frac{Gy}{Gx} \\ 即:\theta = arctan(\frac{Gy}{Gx}) 假设梯度方向与x轴方向的夹角为θtanθ=GxGy:θ=arctan(GxGy)

关于图像梯度的计算的详细细节可以参照上一篇博客:opencv-python常用函数解析及参数介绍(六)——图像梯度

3) 非极大值抑制

顾名思义就是抑制不是极大值的值,应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。
在本问题中可以理解为只选用最大的梯度。

4) 双阈值检测

应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。

其细节上表现为,设置两个阈值,一个阈值决定下限,另一个阈值决定上限,超过阈值上限的梯度可以理所应当的被认为是边缘,低于下限的梯度被认为不是边缘,而对应在上下限直接的范围梯度,应该看与他相连的梯度是不是已经被认为是边缘,如果已经被认为是边缘了,那么与边缘相连的也一定是边缘。

2.opencv中的边缘检测

上述的过程似乎有些复杂,幸好,在opencv中我们可以使用cv2.Canny进行边缘检测,我们只需设置双阈值检测中需要的上下限就好

效果展示

我们假设有一张名为kl.png的图片
在这里插入图片描述
为了展示方便,我们依然先编写一个展示函数

def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()

对这张图片进行边缘检测的效果如下

img=cv2.imread("kl.png",cv2.IMREAD_GRAYSCALE)

v1=cv2.Canny(img,80,150)
cv_show(v1,'res')

在这里插入图片描述

分析对比

与上篇文章中直接使用梯度当做边缘的效果相比似乎是更好的,那么这是为什么呢?其主要的区别就是从双阈值检测,因为我们进行了双阈值检测,在这个过程中当某一个点上的梯度小于设置的下限时就会被丢弃,即立即判断这个点不是边缘,所以相比之下,结果看起来会更干净(因为直接使用梯度作为边缘时一些较小梯度的点仍然会被保留)

当我们把下限设置成0时,即不对梯度的下限做限制,我们可以清晰的看到有些本不属于边缘的位置被当成了边缘

img=cv2.imread("kl.png",cv2.IMREAD_GRAYSCALE)
v1=cv2.Canny(img,0,150)
cv_show(v1,'res')

下面我们来对上下限进行修改,然后做一下对比

img=cv2.imread("kl.png",cv2.IMREAD_GRAYSCALE)

v1=cv2.Canny(img,0,150)
v2=cv2.Canny(img,50,150)
v3=cv2.Canny(img,50,200)

res = np.hstack((v1,v2,v3))
cv_show(cv2.resize(res, (1500, 500)),'res')

在这里插入图片描述

从这个对比中我们可以得到一个结论,上限相同时,降低下限,会导致被直接判断成非边界的点减少,从而得到更多的边缘,下限相同时,升高上限,会使得直接被判断成边界的点减少,同时也会影响到与被判断成边界的点相连的点,产生更少的边缘

3.结尾

关于边缘检测所需的内容,如果感兴趣可以参照之前的一个博客边缘检测生成(伪)手绘线稿风格的视频简易版教程自己生成一个边缘检测的(伪)线稿视频,关于图像的处理所用的全都是本专栏介绍过的知识

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

艾醒(AiXing-w)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值