滤波c语言,c++滤波算法
pˇk,即做了一个加权均值滤波;而在变化大的区域,一个近似于1,b近似于0,对图像的滤波效果很弱,有助于保持边缘。而
的作用就是界定什么是变化大,什么是变化小。在窗口大小不变的情况下,随着e的增大,滤波效果越明显。
在滤波效果上,引导滤波和双边滤波差不多,然后在一些细节上,引导滤波较好(在附言(同后记);警官(警长)的磨皮美白中,经过亲生实践,效果更好)。引导滤波最大的优势在于,可以写出时间复杂度与窗口大小无关的算法,因此在使用大窗口处理图片时,其效率更高。
伪代码
C代码实现在别人博客上找了个代码,自己实现的不知道为什么滤波后只剩下图像的轮廓了,分析下原因,写出自己的代码再放上来。
Mat getimage(Mat a)
{
int hei=a . rows
int wid=a . cols
Mat I(hei,wid,CV _ 64fc 1);
//将图像深度转换为CV_64F
a.convertTo(I,CV_64FC1,1.0/255.0);
//将像素归一化为0~1
/*
for(int I=0;我黑;i ){
double *p=I.ptr double
for(int j=0;j widj ){
p[j]=p[j]/255.0;
}
}
*/
返回我;
}
Mat cumsum(Mat imSrc,int rc)
{
如果(!imSrc.data)
{
cout 没有数据输入!\ n结束
}
int hei=im src。行;
int wid=im src。cols
mat im cum=im src。clone();
如果(rc==1)
{
for(int I=1;我黑;我)
{
for(int j=0;j widj)
{
imCum.at double (i,j)=imCum.at double (i-1,j);
}
}
}
如果(rc==2)
{
for(int I=0;我黑;我)
{
for(int j=1;j widj)
{
imCum.at double (i,j)=imCum.at double (i,j-1);
}
}
}
返回imCum
}
Mat boxfilter(Mat imSrc,int r)
{
int hei=im src。行;
int wid=im src。cols
Mat imDst=Mat:zeros( hei,wid,CV _ 64fc 1);
//imCum=cumsum(imSrc,1);
Mat imCum=cumsum(imSrc,1);
//imDst(1:r 1,)=imCum(1 r:2*r 1,);
for(int I=0;我我)
{
for(int j=0;j j)
{
imDst.at double (i,j)=imCum.at double (i r,j);
}
}
//imDst(r 2:hei-r,)=imCum(2*r 2:hei,)- imCum(1:hei-2*r-1,);
for(int I=r 1;I hei-r;我)
{
for(int j=0;j j)
{
imDst.at double (i,j)=imCum.at double (i r,j)-imCum.at double (i-r-1,j);
}
}
//imDst(hei-r 1:hei,)=repmat(imCum(hei,),[r,1]) - imCum(hei-2*r:hei-r-1,);
for(int I=hei-r;我黑;我)
{
for(int j=0;j widj)
{
imDst.at double (i,j)=imCum.at double (hei-1,j)-imCum.at double (i-r-1,j);
}
}
imCum=cumsum(imDst,2);
//imDst(:1:r 1)=imCum(:1 r:2 * r 1);
for(int I=0;我我)
{
for(int j=0;j j)
{
imDst.at double (i,j)=imCum.at double (i,j r);
}
}
//imDst(:r 2:wid-r)=imCum(:2*r 2:wid) - imCum(:1:wid-2 * r-1);
for(int I=0;我我)
{
for(int j=r 1;j wid-r;j)
{
imDst.at double (i,j)=imCum.at double (i,j r)-imCum.at double (i,j-r-1);
}
}
//imDst(:wid-r 1:wid)=repmat(imCum(:wid),[1,r]) - imCum(:wid-2 * r:wid-r-1);
for(int I=0;我黑;我)
{
for(int j=wid-r;j j)
{
imDst.at double (i,j)=imCum.at double (i,wid-1)-imCum.at double (i,j-r-1);
}
}
返回imDst
}
Mat guidedfilter( Mat I,Mat p,int r,double eps)
{
int hei=I . rows
int wid=I . cols
//N=boxfilter(ones(hei,wid),r);
Mat one=Mat:ones(hei,wid,CV _ 64fc 1);
Mat N=boxfilter(one,r);
//mean_I=boxfilter(I,r)./N;
Mat mean_I(hei,wid,CV _ 64fc 1);
divide(boxfilter(I,r),N,mean _ I);
//mean_p=boxfilter(p,r)./N;
Mat mean_p(hei,wid,CV _ 64fc 1);
divide(boxfilter(p,r),N,mean _ p);
//mean_Ip=boxfilter(I.*p,r)./N;
Mat mul_Ip(hei,wid,CV _ 64fc 1);
Mat mean_Ip(hei,wid,CV _ 64fc 1);
multiply(I,p,mul _ Ip);
divide(boxfilter(mul_Ip,r),N,mean _ Ip);
//cov _ Ip=mean _ Ip-mean _ I . * mean _ p
//这是(第一页)在每个局部面片的协方差。
Mat mul_mean_Ip(hei,wid,CV _ 64fc 1);
Mat cov_Ip(hei,wid,CV _ 64fc 1);
multiply(mean_I,mean_p,mul _ mean _ Ip);
subtract(mean_Ip,mul_mean_Ip,cov _ Ip);
//mean_II=boxfilter(I.*I,r)./N;
Mat mul_II(hei,wid,CV _ 64fc 1);
Mat mean_II(hei,wid,CV _ 64fc 1);
multiply(I,I,mul _ II);
divide(boxfilter(mul_II,r),N,mean _ II);
//var _ I=mean _ II-mean _ I . * mean _ I;
Mat mul_mean_II(hei,wid,CV _ 64fc 1);
Mat var_I(hei,wid,CV _ 64fc 1);
multiply(mean_I,mean_I,mul _ mean _ II);
subtract(mean_II,mul_mean_II,var _ I);
//a=cov_Ip ./(var _ I EPS);
Mat a(hei,wid,CV _ 64fc 1);
for(int I=0;我黑;i ){
double *p=var_I.ptr double
for(int j=0;j widj ){
p[j]=p[j]EPS;
}
}
divide(cov_Ip,var_I,a);
//b=mean _ p-a。* mean _ I;
Mat a_mean_I(hei,wid,CV _ 64fc 1);
Mat b(hei,wid,CV _ 64fc 1);
multiply(a,mean_I,a _ mean _ I);
减法(mean_p,a_mean_I,b);
//mean_a=boxfilter(a,r)./N;
Mat mean_a(hei,wid,CV _ 64fc 1);
divide(boxfilter(a,r),N,mean _ a);
//mean_b=boxfilter(b,r)./N;
Mat mean_b(hei,wid,CV _ 64fc 1);
divide(boxfilter(b,r),N,mean _ b);
//q=mean _ a . * I mean _ b;
Mat mean_a_I(hei,wid,CV _ 64fc 1);
Mat q(hei,wid,CV _ 64fc 1);
乘法(mean_a,I,mean _ a _ I);
add(mean_a_I,mean_b,q);
返回q;
}
/*****************
http://research.microsoft.com/en-us/um/people/kahe/eccv10/
推酷上的一篇文章:
http://www.tuicool.com/articles/Mv2iiu
************************/
cv:Mat guidedFilter2(cv:Mat I,cv:Mat p,int r,double eps)
{
/*
% GUIDEDFILTER O(1)时间导向过滤器的实现。
%
% -引导图像:我(应为灰度/单通道图像)
% -过滤输入图像:p(应为灰度/单通道图像)
% -本地窗口半径:r
% -正则化参数:eps
*/
cv:Mat _ I;
I.convertTo(_I,CV _ 64fc 1);
我=_ I
cv:Mat _ p;
p.convertTo(_p,CV _ 64fc 1);
p=_ p
//[hei,wid]=size(I);
int hei=I . rows
int wid=I . cols
//N=boxfilter(ones(hei,wid),r);%每个本地补丁的大小;N=(2r 1)^2,边界像素除外。
cv:Mat N;
CV:box filter(CV:Mat:ones(hei,wid,I.type()),N,CV_64FC1,cv:Size(r,r));
//mean_I=boxfilter(I,r)./N;
cv:Mat mean _ I;
cv:boxFilter(I,mean_I,CV_64FC1,cv:Size(r,r));
//mean_p=boxfilter(p,r)./N;
cv:Mat mean _ p;
cv:boxFilter(p,mean_p,CV_64FC1,cv:Size(r,r));
//mean_Ip=boxfilter(I.*p,r)./N;
cv:Mat mean _ Ip;
cv:boxFilter(I.mul(p),mean_Ip,CV_64FC1,cv:Size(r,r));
//cov _ Ip=mean _ Ip-mean _ I . * mean _ p;%这是每个局部面片中(第一页)的协方差。
cv:Mat cov _ Ip=mean _ Ip-mean _ I . mul(mean _ p);
//mean_II=boxfilter(I.*I,r)./N;
cv:Mat mean _ II;
cv:boxFilter(I.mul(I),mean_II,CV_64FC1,cv:Size(r,r));
//var _ I=mean _ II-mean _ I . * mean _ I;
cv:Mat var _ I=mean _ II-mean _ I . mul(mean _ I);
//a=cov_Ip ./(var _ I EPS);% Eqn .(5)在论文中;
cv:Mat a=cov _ Ip/(var _ I EPS);
//b=mean _ p-a。* mean _ I;% Eqn .(6)在论文中;
cv:Mat b=mean _ p-a。mul(mean _ I);
//mean_a=boxfilter(a,r)./N;
cv:Mat mean _ a;
cv:boxFilter(a,mean_a,CV_64FC1,cv:Size(r,r));
mean _ a=mean _ a/N;
//mean_b=boxfilter(b,r)./N;
cv:Mat mean _ b;
cv:boxFilter(b,mean_b,CV_64FC1,cv:Size(r,r));
均值_b=均值_ b/N;
//q=mean _ a . * I mean _ b;% Eqn .(8)在论文中;
cv:Mat q=均值_ a . mul(I)均值_ b;
返回q;
}
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。