Image Algorithms - Bilaterial Filter
https://zhuanlan.zhihu.com/p/25437092
最近发现一些公司有美颜算法的需求,网上查了一下一般会用到磨皮算法,磨皮算法首先是要识别检测出皮肤区域吧,然后对提取出的皮肤区域进行双边滤波,保持图像中的边缘信息,同时减少一些不好看的细节(比如雀斑、皱纹之类的),最后把滤波完成后的图像和背景融合在一起,可能还需要做一些锐化。以上是我的一些理解吧。
然后通过wiki百科和查到的一些paper,学习了一下双边滤波,它的表达式是
是空间的卷积核,
叫做range kernel,原理也挺简单,跟一般的卷积相比,就是把图像中变化比较剧烈的部位(边缘)加一个小的权重,这样在求和式子里的贡献就很小,在边缘的像素点就相当于没有被模糊化,起到了保持边界的作用。
据说双边滤波直接按照公式来实现,效率会比较低,因为它的卷积模板是变化的,每个点的计算增加了额外的计算量,而且和卷积模板的窗口大小也有关系,窗口越大,效率下降得会很厉害。
我看了一些文章,这些文章会对双边滤波的计算方法进行一些优化,思想是把表达式拆分成容易计算的,对窗口大小不那么敏感的部分,然后在汇总到一起。
比如CVPR2009的Real O(1) time bilateral filtering
作者根据双边滤波的表达式,定义了一些量
第九个式子的意思是说,对于某个固定的像素值k,双边滤波后的像素值可以看成是两个普通的卷积图像的比值。而这两个待卷积的图像都特别容易得到,注意一下的话,对于固定的k,他们都是点点操作的计算,这个实现起来效率会非常高。
作者对很多不同的像素采样k都计算了,在计算真正的双边滤波图像的时候,就根据这些
通过线性插值插出来。也就是
这个跟地球物理里面的深度偏移算法相移加插值(PSPI)特别像。
然后我稍微实现了一下这个作者的想法,感觉还是有一些效果,不过觉得自己理解还不深啊,美颜的效果好像还不是特别完美。
实验的感觉是:1. spatial kernel用boxfilter效果会好一些;2. spatial kernel用gaussian kernel,我是用deriche的方法做的,这里在图像的边界会遇到问题,deriche的方法要在边界做处理,具体来说就是把采样点加长。
后面也会看一下opencv里的双边滤波咋实现的,那个还是非常给力的。
另外也有一些其他的实现real time bilateral filtering的办法,在wiki上也有对应的文章,后面会仔细看一下。
总的来说,学了些知识吧,感觉确实隔行如隔山,其他领域里的知识也是非常深入的。
posted on 2018-06-07 09:25 fanbird2008 阅读(190) 评论(0) 收藏 举报
浙公网安备 33010602011771号