【CV】Sobel算子简介
引言
Sobel算子是一种常用的边缘检测算法,是一种离散性差分算子,用差分近似代替梯度。对x求1阶差分用来检测竖直边缘,同样的对y求1阶差分用来检测水平边缘。
sobel算子对垂直和水平方向上的排列表达的较好,但对于其他角度的表达往往不够准确。
Sobel算子根据像素点上下、左右邻点灰度加权差,在边缘处达到极值这一现象检测边缘。对噪声具有平滑作用,提供较为精确的边缘方向信息,边缘定位精度不够高。当对精度要求不是很高时,是一种较为常用的边缘检测方法。
具体原理
图像在某一点A的梯度,只需要计算其相邻两个像素点的差值即可得到X方向Y方向上的梯度;但为了更加合理的判断某一点的梯度大小,需要借助算子为这个以点A为中心的ksize×ksize区域(也即内核,一般是ksize取3或5或者其他奇数)添加权重,来扩大差异,增强边缘检测效果。离中心点越近的像素权重越大,越重要。
因为计算一点的梯度需要借助周边区域的多个点的灰度值,因而对图像中的噪点比较敏感,因此时常在调用sobel方法进行计算之前,需要先借助高斯滤波器或者其他滤波器对原图像进行平滑\模糊处理以降噪。所以完整的Sobel梯度计算过程是:
- 高斯滤波器对原图像平滑降噪GaussianBlur;
- 转灰度图cvtColor;
- 求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−1000121⎦⎤sobely=[−12−1000121]sobel_y=\left[ \begin{matrix} -1 & 2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1 \end{matrix} \right] sobely=⎣⎡−101202−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−1000121⎦⎤∗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=⎣⎡−101202−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算子原理与实现。
参考资料
- OpenCV Sobel算子水平和垂直方向导数问题
- sobel算子原理与实现
- Harris角点检测数学计算过程与CornerHarris方法参数的一点说明【DataWhale学习记录】
【CV】Sobel算子简介相关推荐
- CUDA精进之路(四):图像处理——Sobel算子边缘检测
引言 关于图像边缘检测,记得刚开始接触图像处理时,第一个自己实现的程序是通过笔记本摄像头采集图像,利用OpenCV自带的算法库进行Canny算子边缘检测,那时候当看到程序运行后,视频窗口实时显示经Ca ...
- 【OpenCV入门教程之十二】OpenCV边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/25560901 作者:毛星云(浅墨) ...
- OpenCV(十五)边缘检测1 -- Sobel算子(一阶微分算子,X、Y方向边缘检测)
目录 一.边缘检测基础理论 1.作用: 2.分类 1.基于搜索 2.基于零穿越 3.算子比较 二.Sobel算子基础理论 1.作用 2.原理及推导 3.更详细推导 4.Sobel函数 二.实战 1.对 ...
- Sobel算子及cvSobel
转自:http://blog.sina.com.cn/s/blog_4bdbec750100mufo.html 由于项目里要用到边缘检测,所以今天研究了一下最简单的梯度的方法. 首先,我们来开一下计算 ...
- 【OpenCV 4开发详解】Sobel算子
本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...
- sobel算子_OpenCV 学习:4 Sobel算子
1 背景介绍 图像底层的处理对象,比如图像的噪点.边缘.直线.圆.特征点等为目的.那么本章主要解决的问题是如何提取图形中的边缘?是我们关心中的重点.那么,其数学原理是一阶离散差分的形式.故我们知道把一 ...
- Sobel算子取代:基于特定点方向的canny边缘检测
前言: Canny边缘检测使用了Sobel算子,计算dx和dy两个方向,对于特定方向的边缘检测,可以作少量修改. 代码: 计算特定方向上的边缘 void CannyOrient( cv::Mat &a ...
- 【OpenCV 例程200篇】64. 图像锐化——Sobel 算子
[OpenCV 例程200篇]64. 图像锐化--Sobel 算子 欢迎关注 『OpenCV 例程200篇』 系列,持续更新中 欢迎关注 『Python小白的OpenCV学习课』 系列,持续更新中 3 ...
- OpenCV中的Sobel算子
OpenCV中的Sobel算子 刚开始第一次接触这个东西的时候也是感觉一脸懵逼,这是什么鬼.完全看不懂.今天再次接触到,感觉理解的透彻了一点. 首先来看一下Sobel算子是个什么东西: -1 0 1 ...
最新文章
- oracle 四分位函数,Oracle分析函数四——函数RANK,DENSE_RANK,FIRST,LAST…
- JAVA继承心得体会及建议_Java继承总结
- curl 使用 ~/.netrc
- post基础-百度翻译接口测试
- m227fdw恢复出厂设置_惠普M227fdw使用说明
- 计算机视觉中 RNN 应用于目标检测
- Linux 设备驱动的固件加载【转】
- SLAM和三维重建中的SFM区别
- 你所不知道的Redis热点问题以及如何发现热点
- 【最详细】数据结构(C语言版 第2版)课后习题答案全集 严蔚敏 等 编著
- 【设计模式】建造者模式
- NS3入门:第一个程序first.cc
- 迪杰斯特拉--链式向前星
- 处处吻(粤语汉字英译)
- 编写函数,对传送过来的三个数选出最大值和最小值,并通过形参传回调用函数
- 修改谷歌浏览器不安全提示
- IDEA打包时clean报错Failed to delete
- 实战分享:一文读懂RS-232总线
- ClassNotFoundException: com.fasterxml.jackson.databind.AnnotationIntrospector$XmlExtensions的解决方法
- MFC创建处理中进度条,循环滚动进度条的方法
热门文章
- Glance体系结构
- 女孩子转行软件测试还是ui,女生可以做软件测试吗?
- 【带锁的门】(在走廊上有n个带锁的门,从1到n依次编号。最初所有的门都是关着的。我们从门前经过n次,每次都从1号门开始。在第i次经过时(i = 1,2,…, n)我们改变i的整数倍号锁的状态)
- 淘宝撸猫瓜分20亿红包追线球赢喵币有哪些技巧?
- C/C++飞机零部件管理系统
- Linux多路复用之select方案
- chrome.webRequest
- 【金融】财务管理公司金融 (二) 财务分析
- html设置最小宽度 滚动条,如何在CSS中设置滚动条的宽度?
- 90.【SpringSwagger 文档交互】