赞
踩
在本章中, 将学习
inpainting
的方法清除旧照片中的小噪音等大多数人的家里都会有一些旧化的照片,上面可能有黑点、折痕、笔画等。大多数人都想将其还原成原先的样子。但不能简单地在绘画工具中擦除它们,因为擦除操作只是简单地用白色结构代替黑色结构,这是没有用的。在这些情况下,将使用一种称为图像修复的技术。基本思想很简单:用附近的像素替换那些不良区域,使其看起来和邻近的像素比较协调。考虑下面显示的图像(摘自Wikipedia):
左边是旧化的照片,右边是恢复好的图片。可以看到效果还是挺好的。
基于此目的,OpenCV提供了两种实现方法,二者都可以通过相同的函数进行访问,只是参数不同。函数为cv2.inpaint()
第一种算法基于Alexandru Telea在2004年发表的论文An Image Inpainting Technique Based on the Fast Marching Method
。它是基于Fast Marching Method(FMM)
方法。该方法首先考虑图像中要修复的区域,算法从该区域的边界开始,并进入该区域内部,首先逐渐填充边界中的所有内容。在要修复的邻域上的像素周围需要一个小的邻域,该像素被附近所有已知像素的归一化加权总和所代替。权重的选择很重要,边界法线附近的像素和那些位于边界轮廓线上的像素将获得更大的权重。修复像素后,将使用FFM方法将其移动到下一个最近的像素。FMM确保首先修复已知像素附近的那些像素,以便像手动启发式操作一样工作。通过使用标志cv2.INPAINT_TELEA
启用此算法。
第二种算法基于Bertalmio,Marcelo,Andrea L. Bertozzi和Guillermo Sapiro在2001年发表的论文Navier-Stokes, Fluid Dynamics, and Image and Video Inpainting
。该算法基于流体动力学并利用偏微分方程。基本原理是启发式的,它首先沿着边缘从已知区域移动到未知区域(因为边缘是连续的),它延续了等距线(线连接具有相同强度的点,就像轮廓线连接具有相同高程的点一样),同时在修复区域的边界匹配梯度矢量。为此使用了一些流体动力学方法。获得它们后,将填充颜色以减少该区域的最小差异。通过使用标志cv2.INPAINT_NS
启用此算法。
首先需要创建一个与输入图像大小相同的掩码,其中非零像素对应于要修复的区域。
首先使用绘画工具对测试图像手动添加一些黑色笔画进行旧化:
import cv2 import numpy as np from matplotlib import pyplot as plt img = cv2.imread('messi_2.png') img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) mask = cv2.imread('messi_2_mask.png', 0) dst = cv2.inpaint(img, mask, 3, cv2.INPAINT_TELEA) dst1 = cv2.inpaint(img, mask, 3, cv2.INPAINT_NS) # 3 是每个点染色的圆形邻域的半径 plt.subplot(221) plt.imshow(img) plt.subplot(222) plt.imshow(mask) plt.subplot(223) plt.imshow(dst) plt.subplot(224) plt.imshow(dst1) plt.show()
结果如下:
第一张图像显示旧化的输入图片,第二张图像是掩码,第三个图像是第一个算法的结果,最后一个图像是第二个算法的结果。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。