opencv学习笔记(二十一) Sobel算子边缘检测

边缘检测

注意,边缘检测对噪声比较敏感,需要先用高斯滤波器对图像进行平滑。
Sobel变换和拉普拉斯变换都是高通滤波器。什么是高通滤波器呢?就是保留图像的高频分量(变化剧烈的部分),抑制图像的低频分量(变化缓慢的部分)。而图像变化剧烈的部分,往往反应的就是图像的边沿信息了。

Sobel算子

一个最重要并且最基本的卷积是导数的计算(或者是其近似值),有许多方法可以做到,但是只有少数方法适合于给定情况。
Sobel算子用于边缘检测
在讨论边缘算子之前,首先给出一些术语的定义:
(1)边缘:灰度或结构等信息的突变处,边缘是一个区域的结束,也是另一个区域的开始,利用该特征可以分割图像。
(2)边缘点:图像中具有坐标[x,y],且处在强度显著变化的位置上的点。
(3)边缘段:对应于边缘点坐标[x,y]及其方位 ,边缘的方位可能是梯度角。

cvSobel()

定义:
void cvSobel(
const CvArr* src,
CvArr* dst,
int xorder,
int yorder,
int aperture_size = 3
);
参数:
src 输入图像

dst 输出图像

xorder
x 方向上的差分阶数

yorder
y 方向上的差分阶数

aperture_size
Sobel 核的大小,必须是 1, 3, 5 或 7。

这里,src和dst分别是输入图像和输出图像,xorder和yorder是求导的阶数。通常只可能用到0,1,最多2。值为0表明在这个方向上没有求导①(①无论是xorder还是yorder,都必须非0),
aperture_size参数是方形滤波器的宽(或高)并且应该是奇数。目前,
aperture_size支持1, 3, 5, 7。如果源图像src是8位的,为避免溢出,目标图像的深度必须是IPL_DEPTH_16S。
——因为以Sobel方式求完导数后会有负值,还有会大于255的值而你建的Sobel的图像是 IPL_DEPTH_8U,也就是8位无符号数,所以Sobel建立的图像位数不够,要16位有符号的,也就是 IPL_DEPTH_16S。

程序实例

#include 
#include 
void main()
{
    IplImage *frame,*gray,*sobel;
    frame=cvLoadImage("b.jpg");//加载图像
    gray=cvCreateImage(cvGetSize(frame),frame->depth,1);
    //分配图像空间
    sobel=cvCreateImage(cvGetSize(frame),IPL_DEPTH_16S,1);
    /*因为以Sobel方式求完导数后会有负值,还有会大于255的值而你建的Sobel的图像是 IPL_DEPTH_8U,也就是8位无符号数,所以Sobel建立的图像位数不够,要16位有符号的,也就是 IPL_DEPTH_16S。*/
    cvNamedWindow("frame");
    cvNamedWindow("gray");
    cvNamedWindow("sobel");
    cvCvtColor(frame,gray,CV_BGR2GRAY);//转为灰度
    cvSobel(gray,sobel,1,0,3);
    IplImage *sobel8u=cvCreateImage(cvGetSize(sobel),IPL_DEPTH_8U,1);
    cvConvertScaleAbs(sobel,sobel8u,1,0);
    //数据转换,IPL_DEPTH_16S变成IPL_DEPTH_8U
    cvShowImage("frame",frame);//显示图像
    cvShowImage("gray",gray);
    cvShowImage("sobel",sobel8u);
    cvWaitKey(0);//等待
    cvReleaseImage(&frame);
    //释放空间(对视频处理很重要,不释放会造成内存泄露)
    cvReleaseImage(&gray);
    cvReleaseImage(&sobel);
    cvDestroyWindow("frame");
    cvDestroyWindow("gray");
    cvDestroyWindow("sobel");
}

Scharr滤波器——Sobel算子的改进

该函数仅作用于大小为3的内核。该函数的运算与Sobel函数一样快,但结果却更加精确。详见下面的博客:
http://www.tuicool.com/articles/Y3q2Mf
这个滤波器怎么用么?对函数cvSobel( )的参数aperture_size,当它为CV_SCHARR (=-1),对应 3×3 Scharr 滤波器。大家可以在上面的程序的基础上改一下,使用一下这个滤波器。

你可能感兴趣的:(opencv)