导向滤波磨皮
原文地址:http://blog.csdn.net/hjimce/article/details/45421299
作者:hjimce
导向滤波磨皮的对应文献为: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<lenght;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<lenght;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<lenght;i++)
- {
- mean_guideimg[i]/=covone[i];
- mean_inimg[i]/=covone[i];
- }
-
-
- float *var_guideimg=new float[lenght];
- float *sqr_guideimg=new float[lenght];
- for (int i=0;i<lenght;i++)
- {
- sqr_guideimg[i]=guidedimg[i]*guidedimg[i];
- }
- FastGetAVG(var_guideimg,sqr_guideimg,widht,height,Radius);
- delete []sqr_guideimg;
- for (int i=0;i<lenght;i++)
- {
- var_guideimg[i]=var_guideimg[i]/covone[i]-mean_guideimg[i]*mean_guideimg[i];
- }
-
- float*a=new float[lenght];
- for (int i=0;i<lenght;i++)
- {
- a[i]=(covmult[i]-mean_guideimg[i]*mean_inimg[i])/(var_guideimg[i]+eps);
- }
-
- float*b=new float[lenght];
- for (int i=0;i<lenght;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<lenght;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<lenght;i++)
- {
- outimg[i]=mean_a[i]*guidedimg[i]+mean_b[i];
- }
- delete []mean_a;
- delete []mean_b;
- return outimg;
然后把结果用于磨皮,测一测效果:
原图
美图秀秀智能磨皮
导向滤波磨皮
总的来说美图的磨皮好像边缘细节方面保持的不是很好,据此可以推断,美图的磨皮没有用到其他肤色检测技术,而我是结合了肤色检测技术在里面的,所以在头发细节方面会保持的比较好。美图的磨皮还有:自然磨皮、快速磨皮、普通磨皮,除了普通磨皮、智能磨皮,其它的算法结合了美白技术在里面,而且美白技术好像也没有肤色结合肤色检测技术,好像是对全图进行白偏色处理,感觉美图的美白效果很差,因为我觉得美白应该是只对皮肤进行美白,而不是整幅图像进行美白,这边仅代表我个人观点,如有冒犯,请联系本人。