zoukankan      html  css  js  c++  java
  • Sobel边缘检测

    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()

     测试图片:

    运行结果:

  • 相关阅读:
    svn出现权限不足时的解决方法
    子线程简单实现(ZT)
    Ubuntu下安装Apache mysql php的命令
    修改主机名Ubuntu
    form:select form:options 标签数据回显
    form:select form:options 标签数据回显
    checkbox选择根据后台List数据进行回显
    checkbox选择根据后台List数据进行回显
    Java随机数
    Java随机数
  • 原文地址:https://www.cnblogs.com/yibeimingyue/p/10878514.html
Copyright © 2011-2022 走看看