核心函数:cvSobel
程序:
第5个参数使用CV_SCHARR对于第二个原图像的效果:
代码:
#include "cv.h" #include "cxcore.h" #include "highgui.h" #include <iostream> int DerivativeSobel(int argc,char** argv) { IplImage* src=cvLoadImage("e:\\picture\\7.JPG",0); IplImage* dst1=cvCreateImage(cvGetSize(src),IPL_DEPTH_16S,src->nChannels); //注意类型是IPL_DEPTH_16S IplImage* x1=cvCreateImage(cvGetSize(src),8,src->nChannels); IplImage* x2=cvCreateImage(cvGetSize(src),8,src->nChannels); IplImage* y1=cvCreateImage(cvGetSize(src),8,src->nChannels); IplImage* y2=cvCreateImage(cvGetSize(src),8,src->nChannels); IplImage* x1y1=cvCreateImage(cvGetSize(src),8,src->nChannels); IplImage* x2y2=cvCreateImage(cvGetSize(src),8,src->nChannels); cvZero(dst1); cvSobel(src,dst1,1,0,3); //对x求1阶导 cvConvertScale(dst1,x1); cvZero(dst1); cvSobel(src,dst1,2,0,3); //对x求2阶导 cvConvertScale(dst1,x2); cvZero(dst1); cvSobel(src,dst1,0,1,3); //对y求1阶导 cvConvertScale(dst1,y1); cvZero(dst1); cvSobel(src,dst1,0,2,3); //对y求2阶导 cvConvertScale(dst1,y2); cvZero(dst1); cvSobel(src,dst1,1,1,3); //对x和y求1阶导 cvConvertScale(dst1,x1y1); cvZero(dst1); cvSobel(src,dst1,2,2,3); //对x和y求2阶导 cvConvertScale(dst1,x2y2); cvNamedWindow("src"); cvNamedWindow("x1"); cvNamedWindow("x2"); cvNamedWindow("y1"); cvNamedWindow("y2"); cvNamedWindow("x1y1"); cvNamedWindow("x2y2"); cvShowImage("src",src); cvShowImage("x1",x1); cvShowImage("x2",x2); cvShowImage("y1",y1); cvShowImage("y2",y2); cvShowImage("x1y1",x1y1); cvShowImage("x2y2",x2y2); cvWaitKey(0); cvDestroyWindow("src"); cvDestroyWindow("x1"); cvDestroyWindow("x2"); cvDestroyWindow("y1"); cvDestroyWindow("y2"); cvDestroyWindow("x1y1"); cvDestroyWindow("x2y2"); cvReleaseImage(&src); cvReleaseImage(&dst1); cvReleaseImage(&x1); cvReleaseImage(&x2); cvReleaseImage(&y1); cvReleaseImage(&y2); cvReleaseImage(&x1y1); cvReleaseImage(&x2y2); return 0; }
总结:
对x方向的1阶导数是沿着X轴方向的变化程度,对Y方向的1阶导数是沿着Y轴方向的变化程度
1阶导数从低值变化到高值为正,所以可以显示出来白色,而反过来为负,所以显示不出来了,而二阶导数却都为正数,所以都能显示;因此一阶导数常常只能显示内轮廓或者外轮廓(是哪个具体看哪个是从低值到高值),而二阶导数能够同时显示内轮廓和外轮廓
对x和y同时求一阶导数只能x和y方向都有变化的才能显示出来,否则不显示,二阶导数同理