这样,中心点的Y方向导数就求出来了。
X点以Sobel方式求导数ΔX=1×50+2×30+1×50-(1×50+2×30+1×50)=0。这样可以看出这个点不是边界。
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×1或1×3向量而不是一个方阵), 3, 5 或 7。
下面编写一个Sobel边缘检测的程序吧,平台是VS08,建立Win32控制台应用程序。
#include <cv.h>
#include <highgui.h>
void main()
{
IplImage *frame,*gray,*sobel;
frame=cvLoadImage("lena.jpg");//加载图像
gray=cvCreateImage(cvGetSize(frame),frame->depth,1);//分配图像空间
sobel=cvCreateImage(cvGetSize(frame),frame->depth,1);
cvNamedWindow("frame");
cvNamedWindow("gray");
cvNamedWindow("sobel");
cvCvtColor(frame,gray,CV_BGR2GRAY);//转为灰度
cvSobel(gray,sobel,1,0,3);
cvShowImage("frame",frame);//显示图像
cvShowImage("gray",gray);
cvShowImage("sobel",sobel);
cvWaitKey(0);//等待
cvReleaseImage(&frame);//释放空间(对视频处理很重要,不释放会造成内存泄露)
cvReleaseImage(&gray);
cvReleaseImage(&sobel);
cvDestroyWindow("frame");
cvDestroyWindow("gray");
cvDestroyWindow("sobel");
}
运行,你会发现出错,仔细看看没有问题啊。其实,这里是问题的,因为以Sobel方式求完导数后会有负值,还有会大于255的值而你建的Sobel的图像是 IPL_DEPTH_8U,也就是8位无符号数,所以Sobel建立的图像位数不够,要16位有符号的,也就是 IPL_DEPTH_16S。把建立图像这句改为
sobel=cvCreateImage(cvGetSize(frame),IPL_DEPTH_16S,1);运行,发现不报错了,但是Sobel图像显示不出来,这是什么原因呢?原来图像显示是以8位无符号显示的,现在是16位有符号,当然显示会出问题了。所以还要将Sobel转为8位无符号。OpenCv里提供了一个函数,就是cvConvertScaleAbs( const CvArr* src, CvArr* dst, double scale=1, double shift=0 );src:源图像;dst:目标图像;scale:转化前乘的系数;shift转化前加的系数。这样新建一个无符号图像再转换就可以实现了。
IplImage *sobel8u=cvCreateImage(cvGetSize(sobel),IPL_DEPTH_8U,1);
再在显示图像前加上cvConvertScaleAbs(sobel,sobel8u,1,0);这样就可以看到cvSobel的效果了。可以看X方向或Y方向求导是什么效果。
为了方便大家,我把改好后的程序也放上来了。
#include <cv.h>
#include <highgui.h>
void main()
{
IplImage *frame,*gray,*sobel;
frame=cvLoadImage("e:/p1.jpg");//加载图像
gray=cvCreateImage(cvGetSize(frame),frame->depth,1);//分配图像空间
sobel=cvCreateImage(cvGetSize(frame),IPL_DEPTH_16S,1);
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);
cvShowImage("frame",frame);//显示图像
cvShowImage("gray",gray);
cvShowImage("sobel",sobel8u);
cvWaitKey(0);//等待
cvReleaseImage(&frame);//释放空间(对视频处理很重要,不释放会造成内存泄露)
cvReleaseImage(&gray);
cvReleaseImage(&sobel);
cvDestroyWindow("frame");
cvDestroyWindow("gray");
cvDestroyWindow("sobel");
}