码迷,mamicode.com
首页 > 其他好文 > 详细

Sobel算子原理与opencv实现

时间:2015-01-13 16:04:56      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:sobel   图像处理   opencv   

       对于一幅图像,假设图像为全白,但是中间有一条黑色的垂直的直线。那么直线所在的位置有何特征呢?

       稍微想想便可以知道,在直线的左边为全白,那么从图像最左边至中间黑色的直线,其像素点的灰度变化率始终是为0的。同理,直线右边也是这种情况。但是,在黑色直线旁边的点,其会度变化率则不为0。如果把黑色直线看成是图像左右两边的分界线,那么只要知道灰度变化率不为的点,就可以找到这个边界的准确位置。边缘检测理论就是是基于这种灰度变化率的思想。

      在数学中,这种灰度变化率是一种抽象的函数关系,那么在计算机中,是怎么实现计算变化率的呢?

      考虑到对与点(x,y)其灰度变化率的表达形式为△f/x(水平方向)或者△f/y(垂直方向)即梯度,则考虑采用一个3X3的模板来与以此点为中心的3X3区域进行卷积。

                                                                             技术分享

       上图给出的模板,就是Prewitt算子。

    对于Prewitt算子模板,拿X方向梯度举例,其点的灰度变化率与左右两侧的了六个点有关,但是相关程度都是一样的,即权值都为1。而且Prewitt算子只能计算水平和垂直方向的边缘变化,如果我想检测45度方向,135方向的边缘情况,在Prewitt算子中是通过水平和垂直方向的梯度叠加来算的,但是这种方法与真实情况下的45度方向梯度变化是不一样的,降低了梯度值。

       sobel算子在Prewitt算子的基础上,给六个点加了不同的权值,因为这个权值的存在就可以表达出对不同方向边缘的敏感度。下面给出不同方向的模板:

                 技术分享

     对比这四个模板,也能更好的理解sobel算子给点不同权值的意义。由于权值的存在,那么周围点对此点的影响程度就是可以变化的。即可以通过调节不同的权值,实现不同方向的影响力。

     opencv实现程序如下:

#include <cv.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace cv;
using namespace std;
void main()
{
IplImage *frame,*sobel;
frame=cvLoadImage("1.jpg",CV_LOAD_IMAGE_GRAYSCALE);//以灰度方式加载图像
sobel=cvCreateImage(cvGetSize(frame),IPL_DEPTH_16S,1);//图像的梯度有正负,且大小可能超过255,
                                                      //故深度选为signed int 
cvNamedWindow("frame");
cvNamedWindow("sobel");

cvSobel(frame,sobel,1,0,3);//sobel算子运算

IplImage *sobel8u=cvCreateImage(cvGetSize(sobel),IPL_DEPTH_8U,1);
cvConvertScaleAbs(sobel,sobel8u,1,0);   //图像显示只能显示无符号8位
                                        //故要将原来的有符号16转换为无符号8位

cvShowImage("frame",frame);
cvShowImage("sobel",sobel8u);

cvWaitKey(0);//等待
cvReleaseImage(&frame);//释放空间
cvReleaseImage(&sobel);
cvDestroyWindow("frame");
cvDestroyWindow("sobel");
}

void cvSobel( const CvArr* src, CvArr* dst, int xorder, int yorder, int aperture_size=3 );

src:源图像;dst:目标图像;xorder方向上的差分阶数;yorder方向上的差分阶数;

aperture_size 扩展 Sobel 核的大小(既窗口阶数),必须是 1(注意这是一个3×11×3向量而不是一个方阵), 3, 5 或 7

void cvConvertScaleAbs( const CvArr* src, CvArr* dst, double scale=1, double shift=0 );

src:源图像;dst:目标图像;scale:转化前乘的系数;shift:转化前加的系数。  这个函数实现有符号的图像到无符号的图像的转化





Sobel算子原理与opencv实现

标签:sobel   图像处理   opencv   

原文地址:http://blog.csdn.net/autocyz/article/details/42676627

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!