opencv cvSobel()以及Scharr滤波器

/* Calculates an image derivative using generalized Sobel
   (aperture_size = 1,3,5,7) or Scharr (aperture_size = -1) operator.
   Scharr can be used only for the first dx or dy derivative */
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是8位的,为避免溢出,目标图像的深度必须是IPL_DEPTH_16S


//cvSobel
void sobel(void)
{
	IplImage *src=cvLoadImage("lena.jpg");
	IplImage *dstx_s=cvCreateImage(cvGetSize(src), IPL_DEPTH_16S, src->nChannels);
	IplImage *dsty_s=cvCreateImage(cvGetSize(src), IPL_DEPTH_16S, src->nChannels);
	IplImage *dstx_u=cvCreateImage(cvGetSize(src), IPL_DEPTH_8S, src->nChannels);
	IplImage *dsty_u=cvCreateImage(cvGetSize(src), IPL_DEPTH_8S, src->nChannels);
	if (src == NULL || dstx_s == NULL || dsty_s == NULL || dstx_u == NULL || dsty_u == NULL)
		exit(0);

	cvSobel(src, dstx_s, 1, 0, 3);
	cvSobel(src, dsty_s, 0, 1, 3);

	cvConvertScale(dstx_s, dstx_u, 1.0, 0);
	cvConvertScale(dsty_s, dsty_u, 1.0, 0);

	cvNamedWindow("src");
	cvNamedWindow("dstx");
	cvNamedWindow("dsty");
	cvShowImage("src", src);
	cvShowImage("dstx", dstx_u);
	cvShowImage("dsty", dsty_u);
	cvWaitKey(0);
	cvReleaseImage(&src);
	cvReleaseImage(&dstx_s);
	cvReleaseImage(&dsty_s);
	cvReleaseImage(&dstx_u);
	cvReleaseImage(&dsty_u);
	cvDestroyAllWindows();
}

##################################################

Scharr滤波器

对于小一点的核(3x3)而言,使用Sobel算子近似计算导数的缺点是精度比较低

Scbarr滤波器同sobel滤波器一样快,但是准确率更高,故当你利用3x3滤波器实现图像度量的时候应该使用Scharr滤波器


Scharr滤波器的滤波系数如下:

-3

0

     3      

   -10   

   0   

10

-3

0

3


     -3   

  -10  

    3    

0

0

0

-3

10

3


//Scharr
void scharr(void)
{
	IplImage *src=cvLoadImage("lena.jpg");
	IplImage *dstx_s=cvCreateImage(cvGetSize(src), IPL_DEPTH_16S, src->nChannels);
	IplImage *dsty_s=cvCreateImage(cvGetSize(src), IPL_DEPTH_16S, src->nChannels);
	IplImage *dstx_u=cvCreateImage(cvGetSize(src), IPL_DEPTH_8S, src->nChannels);
	IplImage *dsty_u=cvCreateImage(cvGetSize(src), IPL_DEPTH_8S, src->nChannels);
	if (src == NULL || dstx_s == NULL || dsty_s == NULL || dstx_u == NULL || dsty_u == NULL)
		exit(0);

	cvSobel(src, dstx_s, 1, 0, -1);//aperture_size=-1 表示Scharr滤波器
	cvSobel(src, dsty_s, 0, 1, -1);

	cvConvertScale(dstx_s, dstx_u, 1.0, 0);
	cvConvertScale(dsty_s, dsty_u, 1.0, 0);

	cvNamedWindow("src");
	cvNamedWindow("dstx");
	cvNamedWindow("dsty");
	cvShowImage("src", src);
	cvShowImage("dstx", dstx_u);
	cvShowImage("dsty", dsty_u);
	cvWaitKey(0);
	cvReleaseImage(&src);
	cvReleaseImage(&dstx_s);
	cvReleaseImage(&dsty_s);
	cvReleaseImage(&dstx_u);
	cvReleaseImage(&dsty_u);
	cvDestroyAllWindows();
}


opencv cvSobel()以及Scharr滤波器_第1张图片


###################################################################



针对评论里的问题,我查了一下《learning OpenCV》,因为cvSobel()中使用的X和Y滤波器完全是沿x轴和y轴排列。所以当试图估计图像的方向导数(directional derivative,即,使用y/x滤波器响应的反正切得到的图像梯度的方向)时,难度就会出现。(这段话是学习opencv上看的,我也弄不大懂哈,不过又不理解的可以在《学习OpenCV》上在看一看,里面讲的更详细 具体位置在P171)

你可能感兴趣的:(opencv,图像处理)