Sobel算子:[-1  0  1

-2  0  2

-1  0  1]

用此算子与原图像做卷积,可以检测出垂直方向的边缘。算子作用在图像的第二列,结果是:200,200,200;作用在第三列,结果是:

200,200,200;

对当前列左右两侧的元素进行差分,由于边缘的值明显小于(或大于)周边像素,所以边缘的差分结果会明显不同,这样就提取出了垂直边缘。同理,把上面那个矩阵转置一下,就是提取水平边缘。这种差分操作就称为图像的梯度计算。


图像梯度

概念: 把图片想象成连续函数,因为边缘部分的像素值是与旁边像素明显有区别的,所以对图片局部求极值,就可以得到整幅图片的边缘信息了。不过图片是二维的离散函数,导数就变成了差分,这个差分就称为图像的梯度。

理解:求一阶差分应该是指对图像相邻像素求取差分。


边缘 – 是像素值发生跃迁的地方(变化率最大处,导数最大处),是图像的显著特征之一,在图像特征提取、对象检测、模式识别等方面都有重要的作用。

Sobel算子和Scharr算子

(1)Sobel算子:是离散微分算子(discrete differentiation operator),用来计算图像灰度的近似梯度,梯度越大越有可能是边缘。

Soble算子的功能集合了高斯平滑和微分求导,又被称为一阶微分算子,求导算子,在水平和垂直两个方向上求导,得到的是图像在X方法与Y方向梯度图像。

缺点:比较敏感,容易受影响,要通过高斯模糊(平滑)来降噪。

算子是通过权重不同来扩大差异。

梯度计算:(在两个方向求导,假设被作用图像为 I)

水平变化: 将 I 与一个奇数大小的内核 Gx进行卷积。比如,当内核大小为3时, Gx的计算结果为:

垂直变化: 将 I 与一个奇数大小的内核 Gy进行卷积。比如,当内核大小为3时, Gy的计算结果为:

在图像的每一像素上,结合以上两个结果求出近似梯度:

有时也用下面更简单公式代替,计算速度快:(最终图像梯度)。

(2)Scharr:当内核大小为3时, 以上Sobel内核可能产生比较明显的误差(毕竟,Sobel算子只是求取了导数的近似值)。 为解决这一问题,OpenCV提供了 Scharr 函数,但该函数仅作用于大小为3的内核。该函数的运算与Sobel函数一样快,但结果却更加精确,不怕干扰,其内核为:

(3)Sobel/Scharr提取边缘(求导)步骤:

1)高斯模糊平滑降噪:

GaussianBlur( src, dst, Size(3,3), 0, 0, BORDER_DEFAULT );

2)转灰度:

cvtColor( src, gray, COLOR_RGB2GRAY );

3)求X和Y方向的梯度(求导):

Sobel(gray_src, xgrad, CV_16S, 1, 0, 3);

Sobel(gray_src, ygrad, CV_16S, 0, 1, 3);

Scharr(gray_src, xgrad, CV_16S, 1, 0);

Scharr(gray_src, ygrad, CV_16S, 0, 1);

4)像素取绝对值:

convertScaleAbs(A, B); //计算图像A的像素绝对值,输出到图像B

5)相加X和Y,得到综合梯度,称为振幅图像:

addWeighted( A, 0.5,B, 0.5, 0, AB); //混合权重相加,效果较差

或者循环获取像素,每个点直接相加,效果更好。

来源:https://zhuanlan.zhihu.com/p/40491339


 
什么是核?其实就是一组权重的集合,将这组权重集合放入源像素中,会产生一个新的像素,就像一块毛玻璃一样在原始图像上移动,最亮的点经过核中央像素时,所生成新的像素会比它周围的更加突出,这就是把边缘检测了出来。

来源:https://zhuanlan.zhihu.com/p/50966625


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

Sobel算子是典型的基于一阶导数的边缘检测算子,由于该算子中引入了类似局部加权平均的运算,因此对噪声具有平滑作用,能很好的消除噪声的影响。Sobel算子对于象素的位置的影响做了加权。

Sobel算子包含两组3x3的矩阵,分别为横向及纵向模板,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。


Sobel算子是典型的基于一阶导数的边缘检测算子,是离散型的差分算子。该算子对噪声具有平滑作用,能很好的消除噪声的影响。Sobel算子对于像素的位置的影响做了加权,与Prewitt算子、Roberts算子相比因此效果更好。

Sobel算子包含两组3x3的矩阵,分别为横向及纵向模板,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。

链接:https://zhuanlan.zhihu.com/p/56728333


import cv2
import numpy as np
img = cv2.imread("fengjing.jpg", 0)
x = cv2.Sobel(img,cv2.CV_16S,1,0) #1,0代表只计算x方向计算边缘
y = cv2.Sobel(img,cv2.CV_16S,0,1) #0,1代表只在y方向计算边缘
absX = cv2.convertScaleAbs(x)
absY = cv2.convertScaleAbs(y)
dst = cv2.addWeighted(absX,0.5,absY,0.5,0)
cv2.imshow("absX", absX)
cv2.imshow("absY", absY)
cv2.imshow("Result", dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

测试图片:

运行结果:

Sobel边缘检测的更多相关文章

  1. 图像特征提取:Sobel边缘检测

    前言 点和线是做图像分析时两个最重要的特征,而线条往往反映了物体的轮廓,对图像中边缘线的检测是图像分割与特征提取的基础.文章主要讨论两个实际工程中常用的边缘检测算法:Sobel边缘检测和Canny边缘 ...

  2. Sobel边缘检测算法(转载)

    转载请注明出处:  http://blog.csdn.net/tianhai110 索贝尔算子(Sobel operator)主要用作边缘检测,在技术上,它是一离散性差分算子,用来运算图像亮度函数的灰 ...

  3. 数字图像处理之sobel边缘检测

    在前两部文章介绍了几种边缘检测算法,和位图的内存结构.如果对前两篇文章已经理解透彻 了,那么本文将带你进入数字图像处理的世界. 本文通过C代码实现基本的sobel边缘检测,包括8个方向和垂直方向: 代 ...

  4. 基于FPGA的Sobel边缘检测的实现

    前面我们实现了使用PC端上位机串口发送图像数据到VGA显示,通过MATLAB处理的图像数据直接是灰度图像,后面我们在此基础上修改,从而实现,基于FPGA的动态图片的Sobel边缘检测.中值滤波.Can ...

  5. 基于MATLAB的Sobel边缘检测算法实现

    图像边缘就是图像灰度值突变的地方,也就是图像在该部分的像素值变化速度非常之快,就比如在坐标轴上一条曲线有刚开始的平滑突然来个大转弯,在变化出的导数非常大. Sobel算子主要用作边缘检测,它是一离散型 ...

  6. 【转】基于FPGA的Sobel边缘检测的实现

    前面我们实现了使用PC端上位机串口发送图像数据到VGA显示,通过MATLAB处理的图像数据直接是灰度图像,后面我们在此基础上修改,从而实现,基于FPGA的动态图片的Sobel边缘检测.中值滤波.Can ...

  7. Sobel边缘检测算法

    索贝尔算子(Sobel operator)主要用作边缘检测,在技术上,它是一离散性差分算子,用来运算图像亮度函数的灰度之近似值.在图像的任何一点使用此算子,将会产生对应的灰度矢量或是其法矢量 Sobe ...

  8. zedboard zynq 学习 sobel 边缘检测 IP核 制作 根据 文档 Xapp890

    官方文档http://www.xilinx.com/support/documentation/application_notes/xapp890-zynq-sobel-vivado-hls.pdf ...

  9. SSE再学习:灵活运用SIMD指令6倍提升Sobel边缘检测的速度(4000*3000的24位图像时间由180ms降低到30ms)。

    这半年多时间,基本都在折腾一些基本的优化,有很多都是十几年前的技术了,从随大流的角度来考虑,研究这些东西在很多人看来是浪费时间了,即不能赚钱,也对工作能力提升无啥帮助.可我觉得人类所谓的幸福,可以分为 ...

随机推荐

  1. jquery的push()

    JavaScript push() 方法 JavaScript Array 对象 定义和用法 push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度. 语法 arrayObject.pus ...

  2. Eclipse注释模板设置

    设置注释模板的入口: Window->Preference->Java->Code Style->Code Template 然后展开Comments节点就是所有需设置注释的元 ...

  3. js读取json包装的map集合

    后台 Map<String,Integer> map = new HashMap<>(); map.put("你好1", 1); map.put(" ...

  4. C# .Net 下 x86使用大内存的处理

    /LARGEADDRESSAWARE 选项通知链接器应用程序可处理大于 2 GB 的地址. 在 64 位编译器中,默认情况下启用此选项. 在 32 位编译器中,如果未在链接器行上指定 /LARGEAD ...

  5. Coursera machine learning 第二周 编程作业 Linear Regression

    必做: [*] warmUpExercise.m - Simple example function in Octave/MATLAB[*] plotData.m - Function to disp ...

  6. Intellij idea 切换SVN路径

    一直不懂如何切换路径,每次都是删除---->检出:本地源码都不能保存下来,非常麻烦 //在idea中svn切换到新分支:[vcs] -> [subversion] -> [updat ...

  7. ubuntu study

    1.statement a.Fist af all,I think myself be to study miv in instruction. b.again,I think myself be t ...

  8. Linux下的目录操作

    . 此层目录 .. 上层目录 - 前一个工作目录 ~ 当前用户的工作目录 ~account 表示account的家目录 1.cd:改变目录,change Directory的缩写. 2.pwd:显示当 ...

  9. 首页底部菜单FragmentTabHost的使用

    一般现在的菜单都是底部FragmentTabHost,切换Fragment来实现的,今天我们就使用这个来看看如何实现的 首先是布局文件 <?xml version="1.0" ...

  10. 执行动态的delphi脚本

    相关资料:https://www.cnblogs.com/linyawen/archive/2011/10/01/2196950.html 如何在程序中执行动态生成的Delphi代码 经常发现有人提这 ...