2019-10-17 opencv计算摄影2-图像修复(2种算法,需要掩膜)

官网https://docs.opencv.org/3.4.1/df/d3d/tutorial_py_inpainting.html

基础

你们中的大多数人家中都有一些退化的老照片,上面会有一些黑点或者画了几笔。你有没有想过如何修复它们?我们不能简单的在画图工具中擦除它们,因为画图工具只是简单的把白色替代了黑色而已,这是没有用的。这种情况就可以使用图像修复技术。它的基本思路很简单:那些污损部分用它邻域像素替代,这样它就看上去和它的邻域一样了。观察下图:
2019-10-17 opencv计算摄影2-图像修复(2种算法,需要掩膜)_第1张图片
有不少算法可以实现图像修复技术,opencv中提供了其中的2个,这2个算法都是通过cv.inpaint()函数来实现的。

第1个算法是基于2004年Alexandru Telea发表的《An Image Inpainting Technique Based on the Fast Marching Method》。从名称就可以了解,它是基于快速行进算法(Fast Marching Method,简称FMM)。假设图像中的一个区域要修补。算法从区域的边界开始,逐渐进入区域内部,首先填充边界的所有像素。它需要选取待修复像素点周围的小邻域。这个待修复像素点的值会被周围小邻域中所有像素点的归一化加权值替代。显然权重的选择就非常重要了。对于那些靠近待修复像素点,靠近正常边界和位于边界轮廓上像素点的权重要给与更高值。一旦这个像素点被修复,FMM会移动到下一个最近的像素点。FMM确保那些靠近已知像素的(坏)像素首先被修复,这样它就像一个手动的启发式操作一样工作。opencv中使用cv.INPAINT_TELEA标志表示使用该算法。

第2个算法是基于2001年Bertalmio, Marcelo, Andrea L. Bertozzi和Guillermo Sapiro发表的《Navier-Stokes, Fluid Dynamics, and Image and Video Inpainting》。该算法是基于流体动力学,并利用的偏微分方程。基本原理是启发式的。它首先沿着正常区域的边缘向待修补区域移动(因为边界是连续的)。它通过匹配待修复区域中的梯度向量来延伸等照度线(isophotes,由灰度值相等的点练成的线。就像等高线连接高度相同的点一样)。为了实现这个目的,使用了流体动力学中的一些方法。完成这一步之后,通过填充颜色来使这个区域内的灰度值变化最小。opencv中使用cv.INPAINT_NS标志表示使用该算法。

实现

我们需要创建一个和原图相同大小的掩膜,待修复区域的像素设置为非0(其他区域为0)。本例中的图像有一些黑色笔画要修复,它是用画笔工具添加上去的。

代码其实很简单

# -*- coding: cp936 -*-
import cv2 
import numpy as np
import glob
from matplotlib import pyplot as plt

img = cv2.imread('home1.jpg')
mask = cv2.imread('mask2.png',0)
dst = cv2.inpaint(img,mask,3,cv2.INPAINT_TELEA)

cv2.imshow('dst',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行结果可以在下图中看到。
第1个是原图,第2个是掩膜。第3个是使用第1个算法的结果,最后1个是使用第2个算法的结果。
2019-10-17 opencv计算摄影2-图像修复(2种算法,需要掩膜)_第2张图片

你可能感兴趣的:(IT,opencv)