文章目录
图像修复
目标
在本章中,
- 我们将学习如何通过一种称为 修复 的方法去除旧照片中的小噪音、笔触等
- 我们将看到 OpenCV 中的修复功能。
基础知识
你们大多数人家里都会有一些旧的劣化照片,上面有一些黑点、一些笔触等。你有没有想过把它恢复过来?我们不能简单地用绘画工具擦除它们,因为它只会用白色结构替换黑色结构,这是没用的。在这些情况下,使用一种称为图像修复的技术。基本思想很简单:用相邻像素替换那些坏标记,使其看起来像邻域。考虑下面显示的图像(取自[Wikipedia](http://en.wikipedia.org/wiki/Inpainting)):
为此目的设计了几种算法,OpenCV 提供了其中两种。这两种算法都可以通过同一个函数 cv.inpaint() 访问。
第一种算法基于 Alexandru Telea 于 2004 年发表的论文 “基于快速行进法的图像修复技术”。它基于快速行进法。考虑图像中要修复的区域。算法从该区域的边界开始,进入该区域,首先逐渐填充边界内的所有内容。它需要修复邻域中像素周围的一个小邻域。该像素被邻域中所有已知像素的归一化加权和替换。权重的选择很重要。靠近点、靠近边界法线和位于边界轮廓上的像素被赋予更大的权重。修复完一个像素后,它会使用快速行进法移动到下一个最近的像素。 FMM 确保首先修复已知像素附近的像素,因此它就像手动启发式操作一样工作。使用标志 cv.INPAINT_TELEA 启用此算法。
第二种算法基于 Bertalmio、Marcelo、Andrea L. Bertozzi 和 Guillermo Sapiro 于 2001 年发表的论文“Navier-Stokes、流体动力学以及图像和视频修复”。该算法基于流体动力学并利用偏微分方程。基本原理是启发式的。它首先沿着边缘从已知区域行进到未知区域(因为边缘应该是连续的)。它继续等光线(连接具有相同强度的点的线,就像轮廓连接具有相同高度的点一样),同时匹配修复区域边界处的梯度矢量。为此,使用了一些流体动力学方法。一旦获得它们,就会填充颜色以减少该区域的最小方差。该算法通过使用标志 cv.INPAINT_NS 来启用。
代码
我们需要创建一个与输入图像大小相同的蒙版,其中非零像素对应于要修复的区域。其他一切都很简单。我的图像被一些黑色笔触(我手动添加)损坏了。我用 Paint 工具创建了相应的笔触。
import numpy as np
import cv2 as cv
img = cv.imread('messi_2.jpg')
mask = cv.imread('mask2.png',0)
dst = cv.inpaint(img,mask,3,cv.INPAINT_TELEA)
cv.imshow('dst',dst)
cv.waitKey(0)
cv.destroyAllWindows()
参见下面的结果。第一张图显示降级的输入。第二张图是掩码。第三张图是第一个算法的结果,最后一张图是第二个算法的结果。
其他资源
-
Bertalmio, Marcelo, Andrea L. Bertozzi 和 Guillermo Sapiro。“Navier-stokes、流体动力学和
图像和视频修复。”《计算机视觉和模式识别》,2001 年。CVPR 2001。
2001 年 IEEE 计算机学会会议论文集,第 1 卷,第 I-355 页。IEEE,2001 年。 -
Telea, Alexandru。“基于快速行进方法的图像修复技术。”《图形工具杂志》9.1(2004 年):23-34。
练习
-
OpenCV 附带一个关于修复的交互式示例,samples/python/inpaint.py,请尝试一下。
-
几个月前,我观看了一段关于 Content-Aware Fill 的视频,这是 Adobe Photoshop 中使用的一种高级修复技术。经过进一步搜索,我发现 GIMP 中已经存在相同的技术,只是名称不同,即“Resynthesizer”(您需要安装单独的插件)。我相信您一定会喜欢这项技术。