我们再上个教程中留了一个小彩蛋——形态学的梯度问题,通常情况下,它被用于提取图像的轮廓,今天我们来了解图像边缘的另一种方法,它将比形态学梯度更有效,适用范围也更广。

Sobel算子

前面的例子,已经接触到了图像卷积运算。最终要的卷积运算之一是用于计算图像的导数(或近似导数)。为什么图像中导数的计算很重要,看下面边缘检测的例子:

很容易观察到上面图像中像素灰度值变化没有规律。一种比较好的描述这种变化的方法是采用导数。其中梯度剧烈变化的地方代表图像灰度值变化强烈的地方,也就是边缘。

为了更好的说明,以1维图像(也就是图像的1行)为例。边缘出现在灰度值跳变的地方,如下图所示:

如果对上面的1维图像求导数,得到下图,可以很明显的看到边缘所在的位置。

从上面的解释,我们可以设置一个阈值,根据局部像素变化强烈程度获取图像边缘。

sobel算子是一个离散微分算子,计算得到的是图像梯度的近似值。sobel算子结合了高斯平滑和微分。

假设输入图像是I,,核大小为3,通过下面运算分别计算水平方向和垂直方向的微分:

a.水平方向:

b.垂直方向:

具体运算为:

结合上面结果可以计算出图像中一个点的近似梯度:

或者表示为:

需要注意的是,当核的大小为3时,也就是上面所示的Sobel核可能会产生明显的误差(毕竟Sobel只是微分的近似值)。

在OpenCV-Python中,使用Sobel的算子的函数原型如下:

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

前四个是必须的参数:

第一个参数是需要处理的图像;

第二个参数是图像的深度,-1表示采用的是与原图像相同的深度。目标图像的深度必须大于等于原图像的深度;

dx和dy表示的是求导的阶数,0表示这个方向上没有求导,一般为0、1、2。

其后是可选的参数:

dst不用解释了;

ksize是Sobel算子的大小,必须为1、3、5、7。

scale是缩放导数的比例常数,默认情况下没有伸缩系数;

delta是一个可选的增量,将会加到最终的dst中,同样,默认情况下没有额外的值加到dst中;

borderType是判断图像边界的模式。这个参数默认值为cv2.BORDER_DEFAULT。

现在我们来看实验图像:

实战代码:import cv2

import numpy as np

img = cv2.imread("pie.png",0)

x = cv2.Sobel(img,cv2.CV_16S,1,0)

cv2.imshow("x",x)

cv2.waitKey(0)

cv2.destroyAllWindows()

我们发现没有输出,原因在于图像格式的问题,在Sobel函数的第二个参数这里使用了cv2.CV_16S。因为OpenCV文档中对Sobel算子的介绍中有这么一句:“in the case of 8-bit input images it will result in truncated derivatives”。即Sobel函数求完导数后会有负值,还有会大于255的值。而原图像是uint8,即8位无符号数,所以Sobel建立的图像位数不够,会有截断。因此要使用16位有符号的数据类型,即cv2.CV_16S。

在经过处理后,别忘了用convertScaleAbs()函数将其转回原来的uint8形式。否则将无法显示图像,而只是一副灰色的窗口。convertScaleAbs()的原型为:

dst = cv2.convertScaleAbs(src[, dst[, alpha[, beta]]])

其中可选参数alpha是伸缩系数,beta是加到结果上的一个值。结果返回uint8类型的图片。

由于Sobel算子是在两个方向计算的,最后还需要用cv2.addWeighted(...)函数将其组合起来。其函数原型为:

dst = cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])

当然,这个函数我们在前面已经讲述过在这里就不多讲述了。

我们再来看代码:import cv2

import numpy as np

img = cv2.imread("pie.png",0)

x = cv2.Sobel(img,cv2.CV_16S,1,0)

y = cv2.Sobel(img,cv2.CV_16S,0,1)

absX = cv2.convertScaleAbs(x)

absY = cv2.convertScaleAbs(y)

dst = cv2.addWeighted(absX,0.5,absY,0.5,0)

cv2.imshow("x",absX)

cv2.imshow("y",absY)

cv2.imshow("res",dst)

cv2.waitKey(0)

cv2.destroyAllWindows()

先分别来看下,x,y两个方向上的:

再看看最终相加在一起的:

由于Sobel算子是滤波算子的形式,用于提取边缘,可以利用快速卷积函数, 简单有效,因此应用广泛。美中不足的是,Sobel算子并没有将图像的主体与背景严格地区分开来,即Sobel算子没有严格地模拟人的视觉生理特征,所以提取的图像轮廓有时并不能令人满意。

Scharr算子

Scharr() 函数提供了比标准Sobel函数更精确的计算结果。它使用了下面的核:

除了卷积核与Sobel不同,在其余方面它与Sobel基本一致,我们来看它的函数原型:

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

参数就不再介绍了,与Sobel是完全一致的,我们来看看代码演示:import cv2

import numpy as np

img = cv2.imread("pie.png",0)

x = cv2.Scharr(img,cv2.CV_16S,1,0)

y = cv2.Scharr(img,cv2.CV_16S,0,1)

absX = cv2.convertScaleAbs(x)

absY = cv2.convertScaleAbs(y)

dst = cv2.addWeighted(absX,0.5,absY,0.5,0)

cv2.imshow("res",dst)

cv2.waitKey(0)

cv2.destroyAllWindows()

本次教程所讲述的Sobel算子与Scharr算子在图形的边缘检测方面有些缺陷,想必大家也看到了,不过在下次教程我们将会讲述这个问题。

python实现sobel_OpenCV-Python系列之Sobel和Scharr算子相关推荐

  1. 空间滤波 - 锐化处理 - 一阶差分算法(Sobel、Scharr算子)

    目录 1. 介绍 2. Sobel 算子 3. Scharr 算子 1. 介绍 空间滤波的另一种用途是图像的锐化,锐化的作用是突出灰度中的过渡区域 图像的模糊在空间域当中可以通过平滑(平均)邻域中的像 ...

  2. python实现sobel_python通过robert、sobel、Laplace算子实现图像边缘提取详解

    实现思路: 1,将传进来的图片矩阵用算子进行卷积求和(卷积和取绝对值) 2,用新的矩阵(与原图一样大小)去接收每次的卷积和的值 3,卷积图片所有的像素点后,把新的矩阵数据类型转化为uint8 注意: ...

  3. [Python从零到壹] 五十八.图像增强及运算篇之图像锐化Sobel、Laplacian算子实现边缘检测

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  4. 九十八、轻松搞定Python中的Markdown系列

    @Author:Runsen @Date:2020/7/15 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏 ...

  5. 八十四、Python | Leetcode回溯算法系列

    @Author:Runsen @Date:2020/7/7 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏艰 ...

  6. 八十二、Python | Leetcode贪心算法系列

    @Author:Runsen @Date:2020/7/5 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏艰 ...

  7. 大牛推荐的30本经典编程书籍,从Python到前端全系列。

    注:为了方便阅读与收藏,我们也制作了30本书籍完整清单的Markdown.PDF版以及思维导图版,大家可以在实验楼公众号后台回复关键字"书籍推荐"获取. Python 系列(10本 ...

  8. django 按钮的样式_【实战演练】Python+Django网站开发系列11-成绩查询与成绩录入...

    #本文欢迎转载,转载请注明出处和作者 终于做到最后一步了,选课.删除.已选展示.修改密码等功能都已经完成,剩下查询已选课程的成绩(学生界面)与成绩录入(老师界面).其中成绩查询的页面与之前做过的基本上 ...

  9. python items函数用法,Python中dictionary items()系列函数的用法实例

    本文实例讲述了Python中dictionary items()系列函数的用法,对Python程序设计有很好的参考借鉴价值.具体分析如下: 先来看一个示例: import html # availab ...

最新文章

  1. Office 365管理员指引 9 ——Lync 自定义会议邀请
  2. 这项技术是谷歌AI的New Sexy:利于隐私、节能环保,目前最大挑战是布道阐释
  3. C#之Directory类、DirectoryInfo类和Fileinfo,File以及FilesSystemInfo
  4. 解决Sharepoint每天第一次打开速度慢的问题
  5. galago 介绍_赢得预装Linux的System76 Galago Pro笔记本电脑
  6. 三坐标测量圆直径_多台三坐标测量机联动测量方法的研究
  7. 我通过了 Google 技术面试,所以你也能行!
  8. 第 20 章 观察者模式
  9. 阿里开源首个移动AI项目,淘宝同款推理引擎
  10. SELECT中的多表连接
  11. 巴蜀1471 魔兽争霸
  12. 青龙面板除了JD的另外玩法 跑跑 能赚Q和省Q的“果冻宝盒”
  13. 虚拟地址与虚拟内存的理解
  14. SQL SERVER之填充因子
  15. 2017年异步社区优秀图书和作译者评选TOP10
  16. 鸿蒙事业单位专业技术,事业单位专业技术岗考什么?
  17. java电话面试_记一次java电话面试
  18. [转] 网站性能优化之------------- 数据库及服务器架构篇
  19. elasticsearch配置告警方案问题记录
  20. NEFU 大一寒假训练十二(set)2020.02.18

热门文章

  1. threadlocal内存泄露_ThreadLocal 简介
  2. jsp获取连接池的实时连接数_PHP进阶教程-实现一个简单的MySQL连接池
  3. 37. Leetcode 100. 相同的树 (二叉树-二叉树性质)
  4. geyser学习记录(day2):我们在命令行当中怎么使用这个架构?
  5. python 包介绍:osmnx
  6. Python应用实战-Python五个实用的图像处理场景
  7. 深度学习核心技术精讲100篇(三十九)-医疗健康领域的短文本理解
  8. tensorflow从入门到精通100讲(二)-IRIS数据集应用实战
  9. pycharm安装怎么选_客厅窗帘怎么选 客厅窗帘怎么安装好看
  10. Python入门100题 | 第076题