导向滤波磨皮的对应文献为:Guided Image Filtering,这个算法速度极其之快,比其他的保边缘磨皮算法都快,甚至快上好几倍。这个算法最初来自于何明凯的图像去雾算法中,现在已然被应用封装与matlab图像处理函数库中,可见算法堪称经典。
看以下算法的伪代码:
这儿算法中有大量的用到均值卷积,因此可以用快速积分图的方法,进行简单加速。这个算法也是一种保边缘的滤波算法,然而它的用处远远不仅仅用于滤波,还有其它非常好用的功能,比如可以用于升采样,这个感觉非常爽。在一些抠图算法中,如果对大图直接进行抠图,速度非常慢,比如现在的grub cut 分割算法,这个时候我们可以对图像进行下采样,然后在小图上进行抠图,最后再进行升采样,这样速度就非常快了,这是现在一些大图处理常用的一种思路,因此这个算法的用处可想而知。最后我把我写代码贴出来,以供学习,这个代码没有经过整理优化,只是用了快速积分图进行加速:
float* CGuidedfiler::Guidedfiler(float*inimg,float*guidedimg,int height,int widht,int Radius,float eps)
{
int lenght=height*widht;
float*mult=new float[lenght];
float*oned=new float[lenght];
for (int i=0;i
{
mult[i]=inimg[i]*guidedimg[i];
oned[i]=1;
}
float *covmult=new float[lenght];
float *covone=new float[lenght];
FastGetAVG(covmult,mult,widht,height,Radius);
FastGetAVG(covone,oned,widht,height,Radius);
for (int i=0;i
{
covmult[i]/=covone[i];
}
delete []mult;
delete []oned;
//计算导向图、原图的窗口均值
float *mean_inimg=new float[lenght];
FastGetAVG(mean_inimg,inimg,widht,height,Radius);
float*mean_guideimg=new float[lenght];
FastGetAVG(mean_guideimg,guidedimg,widht,height,Radius);
for (int i=0;i
{
mean_guideimg[i]/=covone[i];
mean_inimg[i]/=covone[i];
}
//计算ak的除数
float *var_guideimg=new float[lenght];
float *sqr_guideimg=new float[lenght];
for (int i=0;i
{
sqr_guideimg[i]=guidedimg[i]*guidedimg[i];
}
FastGetAVG(var_guideimg,sqr_guideimg,widht,height,Radius);
delete []sqr_guideimg;
for (int i=0;i
{
var_guideimg[i]=var_guideimg[i]/covone[i]-mean_guideimg[i]*mean_guideimg[i];
}
//计算ak
float*a=new float[lenght];
for (int i=0;i
{
a[i]=(covmult[i]-mean_guideimg[i]*mean_inimg[i])/(var_guideimg[i]+eps);
}
//计算bk
float*b=new float[lenght];
for (int i=0;i
{
b[i]=mean_inimg[i]-a[i]*mean_guideimg[i];
}
delete []covmult;
delete []mean_guideimg;
delete []mean_inimg;
delete []var_guideimg;
float*mean_a=new float[lenght];
float*mean_b=new float[lenght];
FastGetAVG(mean_a,a,widht,height,Radius);
FastGetAVG(mean_b,b,widht,height,Radius);
for (int i=0;i
{
mean_a[i]/=covone[i];
mean_b[i]/=covone[i];
}
delete []a;
delete []b;
//输出图像
float *outimg=new float[lenght];
for (int i=0;i
{
outimg[i]=mean_a[i]*guidedimg[i]+mean_b[i];
}
delete []mean_a;
delete []mean_b;
return outimg;
}
然后把结果用于磨皮,测一测效果:
原图
美图秀秀智能磨皮
导向滤波磨皮
总的来说美图的磨皮好像边缘细节方面保持的不是很好,据此可以推断,美图的磨皮没有用到其他肤色检测技术,而我是结合了肤色检测技术在里面的,所以在头发细节方面会保持的比较好。美图的磨皮还有:自然磨皮、快速磨皮、普通磨皮,除了普通磨皮、智能磨皮,其它的算法结合了美白技术在里面,而且美白技术好像也没有肤色结合肤色检测技术,好像是对全图进行白偏色处理,感觉美图的美白效果很差,因为我觉得美白应该是只对皮肤进行美白,而不是整幅图像进行美白,这边仅代表我个人观点,如有冒犯,请联系本人。更多资源请关注我的博客:http://blog.csdn.net/hjimce 原创文章,版权所有,转载请保留这两行作者信息