Sobel函式原理和應用
阿新 • • 發佈:2019-01-03
用來表達微分的最常用的操作是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; }