Sobel函数原理和应用

用来表达微分的最常用的操作是Sobel微分算子。Sobel算子包含任意阶的微分以及融合偏导。

http://blog.csdn.net/tonyshengtan/article/details/43698711 这个帖关于Sobel的卷积算子怎么推导的有很详细的介绍;

下面我们看一下函数原型

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

其中高src和dst分别是输入图像和输出图像,xorder和yorder是求到的阶数。通常只可能用到0,1,最多是2。值为0表示在这个方向上没有求导。

aperture_size参数是方形滤波器的宽(或高)并且应该是奇数。目前,该参数支持1,3,5,7。

如果愿图像src是八位的。为避免益处,目标图像的深度必须是IPL_DEPTH_16S。

Sobel导数有一个非常好的性质,即可以定义任意大小的核,并且这些核可以用快速且迭代的方式构造。大核对导数有更好的逼近,因为小核对噪声更敏感。

Sobel导数并不是真正的导数,因为Sobel算子定义于一个离散空间上。Sobel算子真正表示的是多项式拟合,也就是说,x方向上的二阶Sobel导数并不是真正的二阶导数。它是对抛物线的拟合。


练习:用一个3✖️3的中孔,对图像运行并显示一阶x和y方向的导数,然后将中孔大小增加到5 ✖️ 5 , 9 ✖️ 9 描述结果;

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>

using namespace std;
using namespace cv;

int main(int argc, const char * argv[]) {
    /*1、加载一幅灰度图像*/
    const char filename[] = "/Users/linwang/Downloads/4.png";
    IplImage * Img = cvLoadImage(filename,CV_LOAD_IMAGE_GRAYSCALE);
    
    /*2、缩小一倍*/
    IplImage *out = cvCreateImage(cvSize(Img->width/2,Img->height/2), Img->depth, Img->nChannels);
    cvResize(Img, out);
    cvShowImage("1/2 Src", out);
    
    /*3、Sobel分别在x方向求导数*/
    IplImage *dst_x = cvCloneImage(out);
    cvSetZero(dst_x);
    cvSobel(out, dst_x, 1, 0, 3);
    cvShowImage("Sobel_X_3", dst_x);
    
    /*4、Sobel分别在y方向求导数*/
    IplImage *dst_y = cvCloneImage(out);
    cvSetZero(dst_y);
    cvSobel(out, dst_y, 0, 1, 5);
    cvShowImage("Sobel_Y_5", dst_y);
    
    /*5、Sobel在x和y同时求导数*/
    IplImage * dst_xy = cvCloneImage(out);
    cvSetZero(dst_xy);
    cvSobel(out, dst_xy, 1, 1 ,9);
    cvShowImage("Sobel_XY_9", dst_xy);
    
    cvWaitKey(0);
    cvReleaseImage(&Img);
    cvReleaseImage(&dst_x);
    cvReleaseImage(&dst_y);
    cvReleaseImage(&dst_xy);
    
    return 0;
}


发布了192 篇原创文章 · 获赞 14 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/u011559236/article/details/78649474
今日推荐