导向滤波磨皮 算法的实现

导向滤波磨皮的对应文献为:Guided Image Filtering,这个算法速度极其之快,比其他的保边缘磨皮算法都快,甚至快上好几倍。这个算法最初来自于何明凯的图像去雾算法中,现在已然被应用封装与matlab图像处理函数库中,可见算法堪称经典。

看以下算法的伪代码:

导向滤波磨皮 算法的实现_第1张图片

这儿算法中有大量的用到均值卷积,因此可以用快速积分图的方法,进行简单加速。这个算法也是一种保边缘的滤波算法,然而它的用处远远不仅仅用于滤波,还有其它非常好用的功能,比如可以用于升采样,这个感觉非常爽。在一些抠图算法中,如果对大图直接进行抠图,速度非常慢,比如现在的grub cut 分割算法,这个时候我们可以对图像进行下采样,然后在小图上进行抠图,最后再进行升采样,这样速度就非常快了,这是现在一些大图处理常用的一种思路,因此这个算法的用处可想而知。最后我把我写代码贴出来,以供学习,这个代码没有经过整理优化,只是用了快速积分图进行加速:

[c++]  view plain copy
  1. float* CGuidedfiler::Guidedfiler(float*inimg,float*guidedimg,int height,int widht,int Radius,float eps)  
  2.   
  3. int lenght=height*widht;  
  4. float*mult=new float[lenght];  
  5. float*oned=new float[lenght];  
  6. for (int i=0;i<lenght;i++)  
  7. {  
  8.     mult[i]=inimg[i]*guidedimg[i];  
  9.     oned[i]=1;  
  10. }  
  11. float *covmult=new float[lenght];  
  12. float *covone=new float[lenght];  
  13. FastGetAVG(covmult,mult,widht,height,Radius);  
  14. FastGetAVG(covone,oned,widht,height,Radius);  
  15. for (int i=0;i<lenght;i++)  
  16. {  
  17.     covmult[i]/=covone[i];  
  18. }  
  19. delete []mult;  
  20. delete []oned;  
  21.   
  22.   
  23. //计算导向图、原图的窗口均值  
  24. float *mean_inimg=new float[lenght];  
  25. FastGetAVG(mean_inimg,inimg,widht,height,Radius);  
  26. float*mean_guideimg=new float[lenght];  
  27. FastGetAVG(mean_guideimg,guidedimg,widht,height,Radius);  
  28. for (int i=0;i<lenght;i++)  
  29. {  
  30.     mean_guideimg[i]/=covone[i];  
  31.     mean_inimg[i]/=covone[i];  
  32. }  
  33.   
  34. //计算ak的除数  
  35. float *var_guideimg=new float[lenght];  
  36. float *sqr_guideimg=new float[lenght];  
  37. for (int i=0;i<lenght;i++)  
  38. {  
  39.     sqr_guideimg[i]=guidedimg[i]*guidedimg[i];  
  40. }  
  41. FastGetAVG(var_guideimg,sqr_guideimg,widht,height,Radius);  
  42. delete []sqr_guideimg;  
  43. for (int i=0;i<lenght;i++)  
  44. {  
  45.     var_guideimg[i]=var_guideimg[i]/covone[i]-mean_guideimg[i]*mean_guideimg[i];  
  46. }  
  47. //计算ak  
  48. float*a=new float[lenght];  
  49. for (int i=0;i<lenght;i++)  
  50. {  
  51.     a[i]=(covmult[i]-mean_guideimg[i]*mean_inimg[i])/(var_guideimg[i]+eps);  
  52. }  
  53. //计算bk  
  54. float*b=new float[lenght];  
  55. for (int i=0;i<lenght;i++)  
  56. {  
  57.     b[i]=mean_inimg[i]-a[i]*mean_guideimg[i];  
  58. }  
  59. delete []covmult;  
  60. delete []mean_guideimg;  
  61. delete []mean_inimg;  
  62. delete []var_guideimg;  
  63. float*mean_a=new float[lenght];  
  64. float*mean_b=new float[lenght];  
  65. FastGetAVG(mean_a,a,widht,height,Radius);  
  66. FastGetAVG(mean_b,b,widht,height,Radius);  
  67. for (int i=0;i<lenght;i++)  
  68. {  
  69.     mean_a[i]/=covone[i];  
  70.     mean_b[i]/=covone[i];  
  71. }  
  72. delete []a;  
  73. delete []b;  
  74. //输出图像  
  75. float *outimg=new float[lenght];  
  76. for (int i=0;i<lenght;i++)  
  77. {  
  78.     outimg[i]=mean_a[i]*guidedimg[i]+mean_b[i];  
  79. }  
  80. delete []mean_a;  
  81. delete []mean_b;  
  82. return outimg;  

然后把结果用于磨皮,测一测效果:

导向滤波磨皮 算法的实现_第2张图片

原图

导向滤波磨皮 算法的实现_第3张图片

美图秀秀智能磨皮

导向滤波磨皮 算法的实现_第4张图片

导向滤波磨皮

总的来说美图的磨皮好像边缘细节方面保持的不是很好,据此可以推断,美图的磨皮没有用到其他肤色检测技术,而我是结合了肤色检测技术在里面的,所以在头发细节方面会保持的比较好。美图的磨皮还有:自然磨皮、快速磨皮、普通磨皮,除了普通磨皮、智能磨皮,其它的算法结合了美白技术在里面,而且美白技术好像也没有肤色结合肤色检测技术,好像是对全图进行白偏色处理,感觉美图的美白效果很差,因为我觉得美白应该是只对皮肤进行美白,而不是整幅图像进行美白,这边仅代表我个人观点,如有冒犯,请联系本人。本文地址:http://blog.csdn.net/hjimce/article/details/45421299    作者:hjimce     联系qq:1393852684  更多资源请关注我的博客:http://blog.csdn.net/hjimce                  原创文章,版权所有,转载请保留这两行作者信息

你可能感兴趣的:(导向滤波磨皮算法)