学习心得:Sobel算子及Opencv实现

Sobel算子是用来提取图像边缘的,而边缘在灰度图中表现为灰度值变化剧烈的位置,可以用像素值差分结果的大小来表征变化剧烈与否。
离散情况下的差分对应的是连续域的微分,因此一般的边缘提取算子其思想都是求图像的微分,如1阶微分和2阶微分,同时又因为图像存在x和y两个方向,因此会出现偏微分。

Sobel算子原理

Sobel算子计算图像差分,依赖两个卷积核,如下图所示。
在这里插入图片描述
左侧代表在x方向上进行加权差分,右侧代表在y方向上的加权差分。此处要注意的是,卷积核在真正参与图像卷积的时候,要旋转180度,这与数字图像处理中的卷积定义有关。旋转之后形成的运算模板如下:
在这里插入图片描述
通过2个卷积核和图像卷积,可以得到两个方向上的差分图像。差分图像和源图像的尺寸相同,其像素值的含义:像素值越大,代表源图像在该位置处的差分结果越大。因此差分图像中灰度值越大(即越白)的点,是边缘的可能性越大。
通过一定的加权融合方法,融合两幅差分图像即可得到原始图像的边缘图像。

Opencv实现

在OpenCV里提供了sobel边缘提取的函数:

dst = cv2.Sobel(src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]])

前四个是必须的参数:
src:需要处理的图像;
ddpteh:是图像的深度,-1表示采用的是与原图像相同的深度。目标图像的深度 必须大于等于原图像的深度;
dx和dy表示的是求导的阶数,0表示这个方向上没有求导,一般为0、1、2。
可选的参数:
dst:目标图像
ksize:Sobel算子的大小,必须为1、3、5、7。
scale:是缩放导数的比例常数,默认情况下没有伸缩系数;
delta:是一个可选的增量,将会加到最终的dst中,同样,默认情况下没有额外的值加到dst中;
borderType:判断图像边界的模式。这个参数默认值cv2.BORDER_DEFAULT。

图像深度参数

ddpteh这个参数代表dst图像的深度,可选的参数如CV_16S、CV_32F、CV_64F等。
由于Sobel算子计算的是差分,有正有负,并且可能存在超过255的数,因此如果采用8为深度的话,显示图像会有问题。

求导阶数

两个参数分别代表对x和y方向的求导阶数。
这里一个容易出问题的地方在于,如果两个参数都给1,理论上是对x和y方向上都求导,得到的应该是一个融合后的边缘图像。然而实际结果是,输出的边缘图像灰度值偏低,即边缘都特别浅。
正确的做法如下:

sobel_x = cv.Sobel(img_gussian, cv.CV_16S, 1, 0, 5)
sobel_y = cv.Sobel(img_gussian, cv.CV_16S, 0, 1, 5)
abs_x = cv.convertScaleAbs(sobel_x) 
abs_y = cv.convertScaleAbs(sobel_y)
img_sobel = cv.addWeighted(abs_x,0.5, abs_y, 0.5, 0)

先分别得到两个方向上的差分图像,再对每个像素求绝对值;之后通过addWeighted函数进行加权融合。这样得到的边缘图像比较正常。

实例

在这里插入图片描述
这是对两个方向同时求导得到的结果,图像非常的浅。
在这里插入图片描述
从左到右分别是x方向差分图,y方向差分图,融合后的边缘图像。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值