最近遇到一个需求,从相机获取的数据局部区域存在空值,即那些地方没有有效数据,如果直接赋值为0,则很有可能得到错误的结果,如果不填充值,很多算法又无法进行,因此,需要一种填充算法把这些空白区域设置成合适的值。 我想了一下,有几个算法可 能可以解决这个问题:
1、inpainting(修复)算法,Inpainting本身就是一种修复算法,可以从周边领域的信息填充未知区域的值,这个开源的在Opencv里有2种。
但是这个算法的步骤实际上都是迭代算法,一步一步由空值边缘向空值内部慢慢填充,直到填充完成或者达到指定的迭代步数。
2、PS里的智能填充算法或者类似效果,当然PS没开源,不过一个类似的结果就是PatchMatch算法,这个在百度上可以搜到很多。
3、还有一个就是模糊算法,但是如果是直接模糊,很明显一个会破坏那些正常的值,二是空值区域模糊后的值明显偏低很多,因为那个取样可能很多去取到的都是空值。
所以要适当修改模糊算法,一个可行的方法就是当领域的像素是空值时,这个像素不参与模糊。这样,只有那些有用的信息才参与计算。另外,为了不影响正常的值或者说有效区域的数据,只有那些是空值的地方才需要模糊。
通过这样的修改,只要取适当的模糊半径, 就可以利用空值周边有用的信息来填充空值区域了,而且空值处的填充值也是和领域有关的,不是随机值,体现了领域相关性。
带来的问题时,原先高效的均值模糊算法,因为有了空值区域判断,无法在直接使用了,需要考虑适当的修改来解决这个问题。
这个问题的解决方案还是得靠积分图技术:
我们首先可以从原始数据中根据空值的分布得到一副只有0和1元素的蒙版图(假定1表示有效值区域,0表示空值区域),接着我们计算两幅积分图像:
一是 原始数据的积分图,但是注意在做积分图累加时,如果遇到空值,则不进行累加或者说累加值为0.
二是 蒙版图的累加,同样是遇到空值,不累加,遇到有效值累加1。
有了这个基础,下面的求均值的部分和普通的用积分图来求均值的方案是一样的了,这是在求均值时还要加上目标区域是否是空值的判断 。
如下图所示,左图中那些纯黑色的部分(像素值为0)即为空值区域,右图是模糊半径为20的时候的修复效果,无效区域均有了有效值(右图有些边界很明显,这个其实可以通过适当的放款无效点的范围来改进)。
在处理效率上,对于浮点的数据,一份大概1000*1000的单通道数据,任意半径的处理耗时是在8ms左右,还是相当的快的。
感觉这个算法也可以用到小范围的人脸祛痘算法上。