zoukankan      html  css  js  c++  java
  • Sobel算子及C++实现

    Sobel 算子是一个离散的一阶微分算子,用来计算图像灰度函数的近似梯度。

    在空间域上Sobel算子很容易实现,执行速度快,对部分噪声具有平滑作用,还能够提供较为精确的边缘方向信息,缺点是边缘定位精度不够高。边缘是指一个物体与另一个物体的分界处,一般边缘内外处都会有灰度值上的差异,Sobel算子就是通过像素点空间邻域内上下,左右相邻点的灰度加权运算,求取物体边缘。


    经典Sobel的卷积因子为:



    对于待检测边缘的图像I,分别在水平(X)方向和垂直方向(Y)方向求导,方法是分别图像I与卷积核Gx和Gy进行卷积,公式表述如下:

                                                                      

    之后对求得的水平和垂直方向的梯度图像上的每一点执行:


        

    或更为简单粗暴的:

       

    G即为Sobel求得的梯度图像。


    以下是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(argv[1],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;
    }

    原始的Lena美女;



    X方向梯度:



    Y方向梯度:



    X、Y方向梯度融合效果:



    Opencv Sobel函数效果:



  • 相关阅读:
    layui 表格分页
    MVC View 获取 控制器返回的ViewData和viewBag
    [转]C#编码规范
    [转]11-为什么局部变量是线程安全的?
    [转]C#进程间通讯--共享内存篇
    [转]C# DataGridView绑定数据源
    [转]PropertyGrid自定义控件
    [转]谁说.NET不适合搞大数据,机器学习、人工智能
    [转]Halcon的C#二次开发及经验分享
    [转]图像获取与采集及图像格式与Region介绍——第2讲
  • 原文地址:https://www.cnblogs.com/mtcnn/p/9411980.html
Copyright © 2011-2022 走看看