zoukankan      html  css  js  c++  java
  • Sobel算子

    【摘要】本文将粗略的介绍Sobel算子。

      Sobel算子是像素图像边缘检测中最重要的算子之一,在机器学习、数字媒体、计算机视觉等信息科技领域起着举足轻重的作用。在技术上,它是一个离散的一阶差分算子,用来计算图像亮度函数的一阶梯度之近似值。在图像的任何一点使用此算子,将会产生该点对应的梯度矢量或是其法矢量。在边缘检测中,常用的一种模板是Sobel 算子。Sobel 算子有两个,一个是检测水平边缘的 ;另一个是检测垂直边缘的 。与Prewitt算子相比,Sobel算子对于像素的位置的影响做了加权,可以降低边缘模糊程度,因此效果更好。由于Sobel算子是滤波算子的形式,用于提取边缘,可以利用快速卷积函数, 简单有效,因此应用广泛。美中不足的是,Sobel算子并没有将图像的主体与背景严格地区分开来,换言之就是Sobel算子没有基于图像灰度进行处理,由于Sobel算子没有严格地模拟人的视觉生理特征,所以提取的图像轮廓有时并不能令人满意。 在观测一幅图像的时候,我们往往首先注意的是图像与背景不同的部分,正是这个部分将主体突出显示,基于该理论,我们给出了下面阈值化轮廓提取算法,该算法已在数学上证明当像素点满足正态分布时所求解是最优的。(百度百科)

    【原理】

      对传入的图像像素进行卷积处理,卷积的实质是在求梯度值,或者说给了一个加权平均,其中权值就是所谓的卷积核;然后对生成的新像素灰度值做阈值运算,以此来确定边缘信息。算子包含两组3x3的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。Gx及Gy分别代表经横向及纵向边缘检测的图像,其公式如图1:

            图1 Sobel Gx和Gy方向卷积核

    原图中的作用点像素值通过卷积之后为,其公式如图2

                      

                          图2 梯度计算公式

    可用以下公式计算梯度方向,其公式如图3

                      

                        图3 梯度计算公式  

    【C++代码】

    #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("qiaoba.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;
    }
    View Code

    参考文章

    http://www.cnblogs.com/sophia-hxw/p/6088035.html

    https://baike.baidu.com/item/Sobel%E7%AE%97%E5%AD%90/11000092?fr=aladdin

  • 相关阅读:
    epoll oneshot
    回望五月
    都知道的copy_from_user
    ixgbe 驱动 为xxx驱动做准备1
    面试问题集锦
    数据治理
    阅读
    hive 数据仓库面试题目集锦
    面试小问题集锦
    Scala学习笔记~尚硅谷学习视频
  • 原文地址:https://www.cnblogs.com/raorao1994/p/8650859.html
Copyright © 2011-2022 走看看