![8983d0efccc401a95dc52624c9806d2b.png](https://i-blog.csdnimg.cn/blog_migrate/76a42c201e1233e8174e3e7a35609d1f.jpeg)
本文同步发表在我的微信公众号“计算摄影学”,欢迎扫码关注
![a24f0e60b58cd6a78ba1f2766a36fae6.png](https://i-blog.csdnimg.cn/blog_migrate/04ceaedeeeeab93336121f9606604ebc.png)
【转载请注明来源和作者】
我相信你和我一样都会遇到一种情况,就是在旅游景区想拍个照留影,结果拍下了太多的路人甲路人乙,于是就总想找到一个p图软件,能够把这些不相干的背景人物p掉
但是直接p是不行的,只有填充被抹掉的像素,才能做到天衣无缝。
我们想要的实际上是这样的效果:
![c2ab8e2366b71ac443a29c491677e720.gif](https://i-blog.csdnimg.cn/blog_migrate/1ab0dbc901685ea5327e3a45fabd28be.gif)
看过我之前的文章:19. 纹理合成再谈 - 一种非参数的方法的朋友一定会想,既然我们能合成纹理,甚至能像下图一样恢复纹理图像中的空洞区域,那是否能用同样的思想来达到我们抹去杂乱背景的目的呢?
![1d163f41c7ab8d8a5218ff622e301754.gif](https://i-blog.csdnimg.cn/blog_migrate/20512b9fd6054089a0567452559dd1cc.gif)
今天我就来给你介绍这样的技术,今天所参考的两份文献是:
1. A. Criminisi, P. Perez, K. Toyama. Region filling and object removal by exemplar-based inpainting. In 2004 IEEE Transactions on Image Processing 9 1200-1212.
2. Criminisi et al., “Object removal by exemplar-based inpainting,” CVPR 2003.
两份文献介绍的是同一种技术,即通过类似我们之前讲过的19. 纹理合成再谈 - 一种非参数的方法中的方法来恢复图像中的空洞区域,只不过作者将上述方法做了进一步扩展,使得它可以用于更广泛的自然图像,而不仅仅是纹理图像。
一、效果展示
我相信看到这里你已经很好奇这个算法的质量到底如何了,我们来看看论文中所展示的一些效果
去除大块的前景像素:
![2ef5df624acd069f7d22dff38e1a3375.png](https://i-blog.csdnimg.cn/blog_migrate/49c4f96726d169dbb1ce793bf12007e7.jpeg)
![22f8790c148315a838f07a3e2715ea03.png](https://i-blog.csdnimg.cn/blog_migrate/f759eb6d8e4c8e6b2e6cf42d4af3989c.jpeg)
去除杂乱的信息
![b8610d4febbd5d949e205fdb2d474533.png](https://i-blog.csdnimg.cn/blog_migrate/90eb86efcd187a5f0006baedbf97ea4f.jpeg)
![db3f5bd87792cdbd92a6bce8e4f7ee05.png](https://i-blog.csdnimg.cn/blog_migrate/506cba80186bd30b7c1352ea09d6278c.jpeg)
填充缺失像素
这个技术甚至可以用于填充全景拼接时,由于图像的warp带来的空洞区域,你可以看到下面a图白色区域都是warp带来的空洞,而b图中则用此算法很好的进行了填充。
![9c780a735d2b41e3c8712303a5192bd3.png](https://i-blog.csdnimg.cn/blog_migrate/adbde39b25db1420fa3034e89709c8e2.jpeg)
看起来真是一种神奇的算法,不是吗?现在让我们看看它到底是如何做到的
二、算法原理
看过我文章19. 纹理合成再谈 - 一种非参数的方法一定还记得起,Efros教授的纹理合成有两个关键点:
- 从待填充的像素中,用洋葱皮的顺序搜寻当前需要填充的像素,确保待填充的像素能够最大可能利用已知或已填充的像素信息。
![05fc8dfcddf2fdf29c2524c83959f212.png](https://i-blog.csdnimg.cn/blog_migrate/baf00a737fa4e13309b2a1f827fb0dc4.jpeg)
2. 对于待填充的像素,从已知图像像素中采样,获取源信息:
![6a4daa879651ea3bcdf5ce8c0fd9ef7d.png](https://i-blog.csdnimg.cn/blog_migrate/a2384b18ecea81e05108ad40f07d3aa2.jpeg)
这里提到的方法首先被Efros教授运用到了纹理合成上,而今天这个算法的作者则向我们说明了这个方法不仅仅对填充纹理有效,对填充普通图像中的线性结构也是有效的。例如,在下面的图示中,
![6250455b48c18d6f21d27ab875ef4b44.png](https://i-blog.csdnimg.cn/blog_migrate/8c3f47e27a211cf5e6ab96b4e311ef0f.jpeg)
理解了上面这点后,我们再来看看填充顺序的重要性。相比起Efros所提到的洋葱皮顺序,作者提到了一种梯度敏感的顺序,并认为对梯度敏感的填充顺序才能更好的填充目标区域,得到更好的效果,如下图所示:
![1a3691d1bbd0d9f9db4f87ab242be529.png](https://i-blog.csdnimg.cn/blog_migrate/758058e059a7b575f481f8073a65a852.jpeg)
下面这张图也很典型的说明了洋葱皮顺序会导致缺陷,而保持梯度的填充顺序能很好的回复图像中的空洞:
![7e28da6bc73d1602a934646fc02dfec9.png](https://i-blog.csdnimg.cn/blog_migrate/e86ce8c36e980b917f83dd9635db7a21.jpeg)
那什么是保持梯度的填充顺序呢?
来看看这幅图,首先作者认为应该优先填充已知区域和待填充区域的边界上的像素,即下图中红色线
![eece67cfc8c1696c4ee92cd791df0cf4.png](https://i-blog.csdnimg.cn/blog_migrate/faa508c962f96c34b77ef09f6409ff14.jpeg)
优先级的计算公式如下:
![cb1fb9583f49b0647316e53eeea6c383.png](https://i-blog.csdnimg.cn/blog_migrate/a154b7037d66e42b77eac65c01ff20c5.png)
其中C(p)是p点的置信项,D(p)是p点的数据项,它们的定义如下:
![cc9066ac37057e0b07df7cf083b7530e.png](https://i-blog.csdnimg.cn/blog_migrate/36998707b924abcd8c34b9cc51e1614e.png)
先说C(p)的计算:
- 分母|
|代表邻域窗口的大小,例如9x9的窗口大小就是81.
- 分子是指把
中的已填充的像素的置信度累加起来
因此C(p)其实是通过p的邻域的已填充像素的置信度推导出了p点的置信度。当初始化时,所有已知像素的置信度为1,待填充像素的置信度为0,你可以看到当我们逐渐填充像素时,越是靠近待填充像素内部的点,其置信度越低——这是非常符合我们的直觉的。
再来看看D(p),这里面α是一个归一化参数,对一般的灰度图像,α=255. np是指在p点的法向量,而▽
这里面我还想借用作者的示意图来给大家说下置信项和数据项对填充顺序的影响。下图中,红色轮廓内部是待填充的像素,其他是已知像素。当我们只采用置信度来判断优先级时,可以看到算法会优先填充绿色像素,并且红色像素的优先级最低。于是待填充区域会越来越趋于圆形,突出的尖端会被压制。 而如果只采用数据项,则算法倾向于把已知像素中的结构信息,例如图中的边缘信息,扩散到未知区域中。于是它会逐步填充绿色像素。
如果同时考虑置信项C(p)和数据项D(p),我们就能得到很好的平衡,得到一种很自然的保持结构的填充顺序。
![9df0e35d0dcb26d89a283c29dd702700.png](https://i-blog.csdnimg.cn/blog_migrate/a9fbfe190d53dea80e90bcea22bf0c5f.jpeg)
一旦我们计算出所有像素的优先级,那么就选出优先级最高的像素
![15c22b41af237b260f4df49918e59223.png](https://i-blog.csdnimg.cn/blog_migrate/4ffa462b5f2a466c854e844ba681190a.png)
于此同时,我们还需要填充这些点的置信度,作者的方法很直接,就是用直接拷贝
所以,作者的方法可以用如下的伪代码来总结:
![67c76c0d5ec16a720a0d502817b864c0.png](https://i-blog.csdnimg.cn/blog_migrate/6271dc0e6cb8421e1fbac0494e460576.jpeg)
三、总结
介绍的算法Region filling and object removal by exemplar-based inpainting是在我们介绍过的19. 纹理合成再谈 - 一种非参数的方法基础上的进一步改进,使之可以应用到自然图像上,能够填充被遮挡的直线型结构。其主要的改进点是同时使用置信度和数据项来衡量填充的优先级顺序,然后在已知像素中搜索与待匹配块相符合的区块来进行块填充,并让置信度从空洞的外层逐渐向内漫延降低。
Inpainting的技术出现已经很久,现在有了很多优秀的方法。但在本篇论文发表当时,也是非常重量级的算法,效果很好。
希望这篇文章能够给你带来启发,别忘了给我点赞哦^_^
番外:
Nvidia推出了在线Inpainting应用,第一幅动图就来自于该应用的页面,你也可以自己试试,这应该是一个基于深度学习的算法,对某些图像效果也挺不错的:
https://www.nvidia.com/research/inpainting/
四、参考资料
本文的大部分信息来自于作者上面提到的两篇论文:
1. A. Criminisi, P. Perez, K. Toyama. Region filling and object removal by exemplar-based inpainting. In 2004 IEEE Transactions on Image Processing 9 1200-1212.
2. Criminisi et al., “Object removal by exemplar-based inpainting,” CVPR 2003.
本文还有少量信息来自于:
CMU 2017 Fall Computational Photography Course 15-463, Lecture 9