首页 > 其他 > 详细

导向滤波(GuidedFilter)

时间:2014-04-08 15:34:05      阅读:863      评论:0      收藏:0      [点我收藏+]

何凯明去雾算法中的导向滤波实现,原文地址导向滤波

#include "cv.h"
#include "highgui.h"

IplImage * cumsum(IplImage *src,int rc);
IplImage * boxFilter(IplImage *src,int r);
IplImage * myGuidedFilter(IplImage * I,IplImage *img_pp,int r, double eps);

#include "myGuidedFilter.h"

IplImage * cumsum(IplImage *src,int rc)
{
	IplImage *Imdst = cvCloneImage(src);
	if (rc==1)
	{
		for(int y=1;y<src->height;y++)
		{
			for(int x=0;x<src->width;x++)
			{
				cvSetReal2D(Imdst,y,x,cvGetReal2D(Imdst,y-1,x)+cvGetReal2D(Imdst,y,x));
			}
		}
	}
	else if (rc==2)
	{
		for(int y=0;y<src->height;y++)
		{
			for(int x=1;x<src->width;x++)
			{
				cvSetReal2D(Imdst,y,x,cvGetReal2D(Imdst,y,x-1)+cvGetReal2D(Imdst,y,x));
			}
		}
	}
	return Imdst;
}
IplImage * boxFilter(IplImage *src,int r)
{
	IplImage *Imdst = cvCloneImage(src);
	int depth=src->depth;
	IplImage *subImage;

	//imCum = cumsum(imSrc, 1);
	IplImage *imCum = cumsum(Imdst,1);

	//imDst(1:r+1, :) = imCum(1+r:2*r+1, :);
	for (int y = 0;y<r;y++)
	{
		for(int x = 0;x<Imdst->width;x++)
		{
			cvSetReal2D(Imdst,y,x,cvGetReal2D(imCum,y+r,x));
		}
	}

	//imDst(r+2:hei-r, :) = imCum(2*r+2:hei, :) - imCum(1:hei-2*r-1, :);
	for (int y = r+1;y<Imdst->height-r-1;y++)
	{
		for(int x = 0;x<Imdst->width;x++)
		{
			cvSetReal2D(Imdst,y,x,(cvGetReal2D(imCum,y+r,x)-cvGetReal2D(imCum,y-r-1,x)));
		}
	}

	//imDst(hei-r+1:hei, :) = repmat(imCum(hei, :), [r, 1]) - imCum(hei-2*r:hei-r-1, :);
	subImage = cvCreateImage(cvSize(Imdst->width,r),depth,1);
	for(int y=0;y<r;y++)
	{
		for(int x=0;x<Imdst->width;x++)
		{
			cvSetReal2D(subImage,y,x,cvGetReal2D(imCum,Imdst->height-1,x));
		}
	}
	for (int y = Imdst->height-r;y<Imdst->height;y++)
	{
		for(int x = 0;x<Imdst->width;x++)
		{
			cvSetReal2D(Imdst,y,x,cvGetReal2D(subImage,y-Imdst->height+r,x)-cvGetReal2D(imCum,y-r-1,x));
		}
	}
	cvReleaseImage(&subImage);
 
	imCum = cumsum(Imdst, 2);
	//imDst(:, 1:r+1) = imCum(:, 1+r:2*r+1);
	for (int y = 0;y<Imdst->height;y++)
	{
		for(int x = 0;x<r;x++)
		{
			cvSetReal2D(Imdst,y,x,cvGetReal2D(imCum,y,x+r));
		}
	}

	//imDst(:, r+2:wid-r) = imCum(:, 2*r+2:wid) - imCum(:, 1:wid-2*r-1);
	for (int y = 0;y<Imdst->height;y++)
	{
		for(int x = r+1;x<Imdst->width-r-1;x++)
		{
			cvSetReal2D(Imdst,y,x,(cvGetReal2D(imCum,y,x+r)-cvGetReal2D(imCum,y,x-r-1)));
		}
	}
	cvReleaseImage(&subImage);
 
	//imDst(:, wid-r+1:wid) = repmat(imCum(:, wid), [1, r]) - imCum(:, wid-2*r:wid-r-1);
	subImage = cvCreateImage(cvSize(r,Imdst->height),depth,1);
	for(int y=0;y<Imdst->height;y++)
	{
		for(int x=0;x<r;x++)
		{
			cvSetReal2D(subImage,y,x,cvGetReal2D(imCum,y,Imdst->width-1));
		}
	}
	for (int y = 0;y<Imdst->height;y++)
	{
		for(int x = Imdst->width-r;x<Imdst->width;x++)
		{
			cvSetReal2D(Imdst,y,x,cvGetReal2D(subImage,y,x-Imdst->width+r)-cvGetReal2D(imCum,y,x-r-1));
		}
	}
	cvReleaseImage(&subImage);

	return Imdst;
}

IplImage * myGuidedFilter(IplImage * I,IplImage *img_pp,int r, double eps)
{
	int height = img_pp->height;
	int width = img_pp->width;
	int depth = IPL_DEPTH_64F;

	IplImage *ones = cvCreateImage(cvSize(width,height),depth,1);
	cvSet(ones,cvRealScalar(1));
	IplImage * N = boxFilter(ones,r);

	//求I的均值
	IplImage * mean_I = cvCreateImage(cvSize(width,height),depth,1);
	cvDiv(boxFilter(I,r),N,mean_I);
	//求P的均值
	IplImage * mean_p = cvCreateImage(cvSize(width,height),depth,1);
	cvDiv(boxFilter(img_pp,r),N,mean_p);
	//求I*P的均值
	IplImage * pr = cvCreateImage(cvSize(width,height),depth,1);
	cvMul(I,img_pp,pr);
	IplImage * mean_Ip = cvCreateImage(cvSize(width,height),depth,1);
	cvDiv(boxFilter(pr,r),N,mean_Ip); 

	//求I与p协方差
	cvMul(mean_I,mean_p,pr);
	IplImage * cov_Ip = cvCreateImage(cvSize(width,height),depth,1);
	cvSub(mean_Ip,pr,cov_Ip);

	//求I的方差
	IplImage * var_I  = cvCreateImage(cvSize(width,height),depth,1);
	cvMul(I,I,pr);
	cvDiv(boxFilter(pr,r),N,var_I);
	cvMul(mean_I,mean_I,pr);
	cvSub(var_I,pr,var_I);
	
	//求a
	IplImage * a = cvCreateImage(cvSize(width,height),depth,1);
	cvAddS(var_I,cvScalar(eps),var_I);
	cvDiv(cov_Ip,var_I,a);
	//求b
	IplImage * b = cvCreateImage(cvSize(width,height),depth,1);
	cvMul(a,mean_I,pr);
	cvSub(mean_p,pr,b);
		 
	//求a的均值
	IplImage * mean_a = cvCreateImage(cvSize(width,height),depth,1);
	cvDiv(boxFilter(a,r),N,mean_a);
	//求b的均值
	IplImage * mean_b = cvCreateImage(cvSize(width,height),depth,1);
	cvDiv(boxFilter(b,r),N,mean_b);
		 
	//求Q
	IplImage * q = cvCreateImage(cvSize(width,height),depth,1);
	cvMul(mean_a,I,a);
	cvAdd(a,mean_b,q);
		 
	cvReleaseImage(&ones);
	cvReleaseImage(&mean_I);
	cvReleaseImage(&mean_p);
	cvReleaseImage(&pr);
	cvReleaseImage(&mean_Ip);
	cvReleaseImage(&cov_Ip);
	cvReleaseImage(&var_I);
	cvReleaseImage(&a);
	cvReleaseImage(&b);
	cvReleaseImage(&mean_a);
	cvReleaseImage(&mean_b);
	return q;
}


导向滤波(GuidedFilter),布布扣,bubuko.com

导向滤波(GuidedFilter)

原文:http://blog.csdn.net/wds555/article/details/23176313

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!