转载]Opencv中使用cvSobel算子一点注意
(2012-07-26 09:23:44)X点以Sobel措施求导数ΔX=1×50+2×30+1×50-(1×50+2×30+1×50)=0。这么能够看出这个点不是边界。
好了,打听了大约理论尔后,我们看看OpenCv下的Sobel函数吧,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);
cvCvtColor(frame,gray,CV_BGR2GRAY);//转为灰度
cvSobel(gray,sobel,1,0,3);
cvNamedWindow("frame");
cvNamedWindow("gray");
cvNamedWindow("sobel");
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);
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);
cvNamedWindow("frame");
cvNamedWindow("gray");
cvNamedWindow("sobel");
cvShowImage("frame",frame);//揭示图像
cvShowImage("gray",gray);
cvShowImage("sobel",sobel8u);
cvWaitKey(0);//期待
cvReleaseImage(&frame);//释放空间(对视频处理很重要,不释放会构成内存败露)
cvReleaseImage(&gray);
cvReleaseImage(&sobel);
cvDestroyWindow("frame");
cvDestroyWindow("gray");
cvDestroyWindow("sobel");
}