这篇文章是opencv内inpaint函数(Telea)所对应的论文。在如今深度学习纵横的今天,传统方式在一定程度上依然还有一席之地。
1.算法流程
总所周知,待修复的图像往往会被分为完好的区域和待校正区域,我们记图片的所有区域为,待修复区域为,然后从待修复区域里取一条窄带。之后,图片就可以分为三个区域,分别是完好区域,待修复区域,和窄带区域。随后,我们从窄带中不断选点,并在该点临近的完好区域,修复,并慢慢将窄带往待修复区域内扩张。最终就可以修复所有的待修复区域里的点。
但是,我们是如何在窄带中选点修复的呢?
首先,我们会将三个区域(完好,窄带,待修复)上的点,到窄带和完好区域交界处的距离设为T,在初始化时,将在完好区域内的点的T设置为0,待修复区域内的点的T设置为正无穷(论文中实际代码设置为1e^6),而在窄带内区域的点的T则是需要不断计算更新的,我们每次选取在窄带中T值最小的点做修复。
点已经选好了,那么区域怎么找呢?在论文中,作者说,对于不是太“厚”的区域,我们可以取那个坏点附近完好区域内的6个像素点,如果是比较“厚”的区域,那么就需要取12个像素点。
现在万事俱备,就只剩修复了。我们先看在完好区域内一个点对待修复点的影响。
在这张图上,p是在窄带上待修复的点,q是p点附近完好区域的点,之后的操作如公式所示:
之后,再两个向量对应相乘。
这是对应一个点所需要的操作,下面让我们看看多个点时:
在修复完窄带上的点p后,我们需要更新p点的T,
对应伪代码如下:
而所对应的权重泽等于dir,dst,lev三者相乘
tips:实际实现时,d0和T0都为1.N(p)为q的灰度梯度法向单位向量。
单点修复的伪代码如下: