引言

Sobel算子是一种常用的边缘检测算法,是一种离散性差分算子,用差分近似代替梯度。对x求1阶差分用来检测竖直边缘,同样的对y求1阶差分用来检测水平边缘。

sobel算子对垂直和水平方向上的排列表达的较好,但对于其他角度的表达往往不够准确。

Sobel算子根据像素点上下、左右邻点灰度加权差,在边缘处达到极值这一现象检测边缘。对噪声具有平滑作用,提供较为精确的边缘方向信息,边缘定位精度不够高。当对精度要求不是很高时,是一种较为常用的边缘检测方法。

具体原理

图像在某一点A的梯度,只需要计算其相邻两个像素点的差值即可得到X方向Y方向上的梯度;但为了更加合理的判断某一点的梯度大小,需要借助算子为这个以点A为中心的ksize×ksize区域(也即内核,一般是ksize取3或5或者其他奇数)添加权重,来扩大差异,增强边缘检测效果。离中心点越近的像素权重越大,越重要。

因为计算一点的梯度需要借助周边区域的多个点的灰度值,因而对图像中的噪点比较敏感,因此时常在调用sobel方法进行计算之前,需要先借助高斯滤波器或者其他滤波器对原图像进行平滑\模糊处理以降噪。所以完整的Sobel梯度计算过程是:

  1. 高斯滤波器对原图像平滑降噪GaussianBlur;
  2. 转灰度图cvtColor;
  3. 求X和Y方向的梯度Sobel。

当内核为3*3时,横向和纵向方向上的卷积因子分别为:
sobelx=[−101−202−101]sobel_x=\left[ \begin{matrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{matrix} \right] sobelx​=⎣⎡​−1−2−1​000​121​⎦⎤​sobely=[−12−1000121]sobel_y=\left[ \begin{matrix} -1 & 2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1 \end{matrix} \right] sobely​=⎣⎡​−101​202​−101​⎦⎤​
假设原图像为A=[f(x−1,y−1)f(x,y−1)f(x+1,y−1)f(x−1,y)f(x,y)f(x+1,y)f(x−1,y+1)f(x,y+1)f(x+1,y+1)]A=\left[ \begin{matrix} f(x-1,y-1) & f(x,y-1) & f(x+1,y-1) \\ f(x-1,y) & f(x,y) & f(x+1,y) \\ f(x-1,y+1) & f(x,y+1) & f(x+1,y+1) \end{matrix} \right]A=⎣⎡​f(x−1,y−1)f(x−1,y)f(x−1,y+1)​f(x,y−1)f(x,y)f(x,y+1)​f(x+1,y−1)f(x+1,y)f(x+1,y+1)​⎦⎤​,分别做卷积可以得到:
Gx=sobelx∗A=[−101−202−101]∗AG_x=sobel_x*A=\left[ \begin{matrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{matrix} \right]*A Gx​=sobelx​∗A=⎣⎡​−1−2−1​000​121​⎦⎤​∗AGy=sobely∗A=[−12−1000121]∗AG_y=sobel_y*A=\left[ \begin{matrix} -1 & 2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1 \end{matrix} \right]*A Gy​=sobely​∗A=⎣⎡​−101​202​−101​⎦⎤​∗A
注意:

  • 这里的乘积是将两矩阵相应位置处的值相乘,然后把所有值相加,不是矩阵的乘法;
  • opencv对图像坐标的定义为原点在左上角角位置,x轴是从原点水平向右正向增大,y轴是从原点竖直向下正向增大。一个像素点的坐标为(x,y),那么(x+1,y+1)在该点的右下角;
  • sobel算子一般是,右减左,下减上,得到图像中某一点的梯度。

由上述公式计算得到Gy和Gx后,可以计算得到G的值:

或者采用简便算法:

一个点的G的代表该点的梯度,如果大于某一设定范围则认为该点是边缘点

如果为一幅图像有竖直边缘,该竖直边缘的水平两侧灰度将存在差异,同理如果存在水平边缘,该边缘的垂直两侧灰度将存在差异,sobel算子利用这种差异实现竖直边缘和水平边缘的检测。

下面左图表示用大于一定阈值的Gx来识别边缘点的结果,中图为用大于一定阈值的Gy来识别边缘点的结果,右图为用大于一定阈值的G来识别边缘点的结果。

代码实现

在C++中,opencv的Sobel函数如下:

CV_EXPORTS_W void Sobel( InputArray src, OutputArray dst, int ddepth,int dx, int dy,int ksize=3,double scale=1, double delta=0,int borderType=BORDER_DEFAULT );

在python中,通过cv2.Sobel来调用Sobel函数如下:

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

参数具体含义:

  • src:输入图像,Mat类型。
  • dst:目标图像,Mat类型。
  • ddepth:int类型的ddepth,目标图像的深度,-1表示采用的是与原图像相同的深度。目标图像的深度必须大于等于原图像的深度。因为进行减法操作后不一定得到的是正值,也可能是负值,也可能大于255,但是uint8(即8位无符号数)不允许这些数的存在。因此要指定ddepth = cv2.CV_64F 以包容负值的存在(eg:cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)),此时进行图像的展示,会先将数组中的负值视为0。但是随后会调用其他方法(cv2.convertScaleAbs)以进行绝对值化的操作,转回原来的uint8形式。此时进行展示时,会使得负值转化为正值,得到我们完整的特征图。
    支持如下src.depth()和ddepth的组合:
    (1) 若src.depth() = CV_8U, 取ddepth =-1/CV_16S/CV_32F/CV_64F;
    (2) 若src.depth() = CV_16U/CV_16S, 取ddepth =-1/CV_32F/CV_64F;
    (3) 若src.depth() = CV_32F, 取ddepth =-1/CV_32F/CV_64F;
    (4) 若src.depth() = CV_64F, 取ddepth = -1/CV_64F。
  • dx:int类型,表示对x差分的阶数,0表示这个方向上没有求导,一般为0、1、2。
  • dy:int类型,表示对x差分的阶数,0表示这个方向上没有求导,一般为0、1、2。
  • ksize:int类型,表示Sobel核的大小,默认值3,必须取1,3,5或7。
  • scale:double类型,计算导数值时可选的缩放因子,默认值是1。
  • delta:double类型,表示在结果存入目标图(第二个参数dst)之前可选的delta值,默认值0。
  • borderType:int类型,边界模式,默认值为BORDER_DEFAULT。

具体基于python和C++的边缘检测代码参考sobel算子原理与实现。

参考资料

  1. OpenCV Sobel算子水平和垂直方向导数问题
  2. sobel算子原理与实现
  3. Harris角点检测数学计算过程与CornerHarris方法参数的一点说明【DataWhale学习记录】

【CV】Sobel算子简介相关推荐

  1. CUDA精进之路(四):图像处理——Sobel算子边缘检测

    引言 关于图像边缘检测,记得刚开始接触图像处理时,第一个自己实现的程序是通过笔记本摄像头采集图像,利用OpenCV自带的算法库进行Canny算子边缘检测,那时候当看到程序运行后,视频窗口实时显示经Ca ...

  2. 【OpenCV入门教程之十二】OpenCV边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/25560901 作者:毛星云(浅墨) ...

  3. OpenCV(十五)边缘检测1 -- Sobel算子(一阶微分算子,X、Y方向边缘检测)

    目录 一.边缘检测基础理论 1.作用: 2.分类 1.基于搜索 2.基于零穿越 3.算子比较 二.Sobel算子基础理论 1.作用 2.原理及推导 3.更详细推导 4.Sobel函数 二.实战 1.对 ...

  4. Sobel算子及cvSobel

    转自:http://blog.sina.com.cn/s/blog_4bdbec750100mufo.html 由于项目里要用到边缘检测,所以今天研究了一下最简单的梯度的方法. 首先,我们来开一下计算 ...

  5. 【OpenCV 4开发详解】Sobel算子

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  6. sobel算子_OpenCV 学习:4 Sobel算子

    1 背景介绍 图像底层的处理对象,比如图像的噪点.边缘.直线.圆.特征点等为目的.那么本章主要解决的问题是如何提取图形中的边缘?是我们关心中的重点.那么,其数学原理是一阶离散差分的形式.故我们知道把一 ...

  7. Sobel算子取代:基于特定点方向的canny边缘检测

    前言: Canny边缘检测使用了Sobel算子,计算dx和dy两个方向,对于特定方向的边缘检测,可以作少量修改. 代码: 计算特定方向上的边缘 void CannyOrient( cv::Mat &a ...

  8. 【OpenCV 例程200篇】64. 图像锐化——Sobel 算子

    [OpenCV 例程200篇]64. 图像锐化--Sobel 算子 欢迎关注 『OpenCV 例程200篇』 系列,持续更新中 欢迎关注 『Python小白的OpenCV学习课』 系列,持续更新中 3 ...

  9. OpenCV中的Sobel算子

    OpenCV中的Sobel算子 刚开始第一次接触这个东西的时候也是感觉一脸懵逼,这是什么鬼.完全看不懂.今天再次接触到,感觉理解的透彻了一点. 首先来看一下Sobel算子是个什么东西: -1 0 1 ...

最新文章

  1. oracle 四分位函数,Oracle分析函数四——函数RANK,DENSE_RANK,FIRST,LAST…
  2. JAVA继承心得体会及建议_Java继承总结
  3. curl 使用 ~/.netrc
  4. post基础-百度翻译接口测试
  5. m227fdw恢复出厂设置_惠普M227fdw使用说明
  6. 计算机视觉中 RNN 应用于目标检测
  7. Linux 设备驱动的固件加载【转】
  8. SLAM和三维重建中的SFM区别
  9. 你所不知道的Redis热点问题以及如何发现热点
  10. 【最详细】数据结构(C语言版 第2版)课后习题答案全集 严蔚敏 等 编著
  11. 【设计模式】建造者模式
  12. NS3入门:第一个程序first.cc
  13. 迪杰斯特拉--链式向前星
  14. 处处吻(粤语汉字英译)
  15. 编写函数,对传送过来的三个数选出最大值和最小值,并通过形参传回调用函数
  16. 修改谷歌浏览器不安全提示
  17. IDEA打包时clean报错Failed to delete
  18. 实战分享:一文读懂RS-232总线
  19. ClassNotFoundException: com.fasterxml.jackson.databind.AnnotationIntrospector$XmlExtensions的解决方法
  20. MFC创建处理中进度条,循环滚动进度条的方法

热门文章

  1. Glance体系结构
  2. 女孩子转行软件测试还是ui,女生可以做软件测试吗?
  3. 【带锁的门】(在走廊上有n个带锁的门,从1到n依次编号。最初所有的门都是关着的。我们从门前经过n次,每次都从1号门开始。在第i次经过时(i = 1,2,…, n)我们改变i的整数倍号锁的状态)
  4. 淘宝撸猫瓜分20亿红包追线球赢喵币有哪些技巧?
  5. C/C++飞机零部件管理系统
  6. Linux多路复用之select方案
  7. chrome.webRequest
  8. 【金融】财务管理公司金融 (二) 财务分析
  9. html设置最小宽度 滚动条,如何在CSS中设置滚动条的宽度?
  10. 90.【SpringSwagger 文档交互】