sobel算子原理与实践

       索贝尔算子(Sobeloperator)主要用于获得数字图像的一阶梯度,是一种离散性差分算子它是prewitt算子的改进形式,改进之处在于sobel算子认为,邻域的像素对当前像素产生的影响不是等价的,所以距离不同的像素具有不同的权值,对算子结果产生的影响也不同。一般来说,距离越远,产生的影响越小。

       图像处理中认为,灰度值变化剧烈的地方就是边缘。那么如何判断灰度值变化?如何度量剧烈sobel算子就对这些问题做了自己的规范,而且命名为sobel算子,就是对一副图像的输入到输出边缘信息的整个处理过程。

       sobel算子的思想,Sobel算子认为,邻域的像素对当前像素产生的影响不是等价的,所以距离不同的像素具有不同的权值,对算子结果产生的影响也不同。一般来说,距离越远,产生的影响越小。

       sobel算子的原理,对传进来的图像像素做卷积,卷积的实质是在求梯度值,或者说给了一个加权平均,其中权值就是所谓的卷积核;然后对生成的新像素灰度值做阈值运算,以此来确定边缘信息。

      卷积核和算法实现原理:

                                

       该算子包含两组3x3的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。如果以A代表原始图像,GxGy分别代表经横向及纵向边缘检测的图像灰度值,其公式如下:

                                                   

具体计算如下:

图像的每一个像素的横向及纵向灰度值通过以下公式结合,来计算该点灰度的大小:

                                                                                    

通常,为了提高效率使用不开平方的近似值:

                                                                                      

然后可用以下公式计算梯度方向:

                                                                                      

若图像为:

                                                                                             

则使用近似公式的计算的结果为:

                                                   

另外,卷积核也可以旋转,用与查找不与x,y轴平行或垂直的方向上的边缘。

                                            

                                            

                                            

                                             

MTLAB代码实现:

来源:https://www.cnblogs.com/wxl845235800/p/7700887.html

Gx=[1.0 2.0 1.0;0.0 0.0 0.0;-1.0 -2.0 -1.0];
Gy=[-1.0 0.0 1.0;-2.0 0.0 2.0;-1.0 0.0 1.0];
 
img=imread('lena.jpg');
image=rgb2gray(img);
 
subplot(2,2,1);  
imshow(image);   
title('原图');  
 
gradx=conv2(Gx,image,'full'); 
gradx=abs(gradx); %计算图像的sobel垂直梯度 
subplot(2,2,2); 
imshow(gradx,[]); 
title('图像的sobel垂直梯度');
 
grady=conv2(Gy,image,'full'); 
grady=abs(grady); %计算图像的sobel水平梯度 
subplot(2,2,3); 
imshow(grady,[]); 
title('图像的sobel水平梯度'); 
 
grad=gradx+grady;  %得到图像的sobel梯度 
subplot(2,2,4); 
imshow(grad,[]); 
title('图像的sobel梯度');

结果:

                                                

C++代码实现:

来源:http://blog.csdn.net/dcrmg/article/details/52280768

#include "core/core.hpp"   
#include "highgui/highgui.hpp"   
#include "imgproc/imgproc.hpp"   
#include "iostream" 
 
using namespace std;
using namespace cv;
 
int main(int argc, char *argv[])
{
    Mat image = imread("lena.jpg", 0);
    Mat imageX = Mat::zeros(image.size(), CV_16SC1);
    Mat imageY = Mat::zeros(image.size(), CV_16SC1);
    Mat imageXY = Mat::zeros(image.size(), CV_16SC1);
    Mat imageX8UC;
    Mat imageY8UC;
    Mat imageXY8UC;
    if (!image.data)
    {
        return -1;
    }
    GaussianBlur(image, image, Size(3, 3), 0); //高斯滤波消除噪点 
    uchar *P = image.data;
    uchar *PX = imageX.data;
    uchar *PY = imageY.data;
    int step = image.step;
    int stepXY = imageX.step;
    for (int i = 1; i<image.rows - 1; i++)
    {
        for (int j = 1; j<image.cols - 1; j++)
        {
            //通过指针遍历图像上每一个像素 
            PX[i*imageX.step + j*(stepXY / step)] = abs(P[(i - 1)*step + j + 1] + P[i*step + j + 1] * 2 + P[(i + 1)*step + j + 1] - P[(i - 1)*step + j - 1] - P[i*step + j - 1] * 2 - P[(i + 1)*step + j - 1]);
            PY[i*imageX.step + j*(stepXY / step)] = abs(P[(i + 1)*step + j - 1] + P[(i + 1)*step + j] * 2 + P[(i + 1)*step + j + 1] - P[(i - 1)*step + j - 1] - P[(i - 1)*step + j] * 2 - P[(i - 1)*step + j + 1]);
        }
    }
    addWeighted(imageX, 0.5, imageY, 0.5, 0, imageXY);//融合X、Y方向   
    convertScaleAbs(imageX, imageX8UC);
    convertScaleAbs(imageY, imageY8UC);
    convertScaleAbs(imageXY, imageXY8UC);   //转换为8bit图像 
 
    Mat imageSobel;
    Sobel(image, imageSobel, CV_8UC1, 1, 1); //Opencv的Sobel函数 
 
    imshow("Source Image", image);
    imshow("X Direction", imageX8UC);
    imshow("Y Direction", imageY8UC);
    imshow("XY Direction", imageXY8UC);
    imshow("Opencv Soble", imageSobel);
    waitKey();
    return 0;
}

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

  • 13
    点赞
  • 104
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值