基礎(chǔ)
你們可能家里都會有一些老照片已經(jīng)有黑點啊化戳,劃痕啊等睬澡。你有想過修復(fù)它們么艇拍?我們不能簡單的在繪圖工具里把他們擦除了就完了。因為這樣只是把黑色的東西變成白色的而已骏掀,實際上沒用鸠澈。在這種情況下,會用到一種技術(shù)叫圖像修復(fù)截驮⌒Τ拢基本的思想很簡單:用周圍的像素替換壞掉的像素,這樣看上去就和周圍一樣了葵袭。比如下面這張:
很多算法被設(shè)計來干這個涵妥,OpenCV提供了兩個,可以用同一個函數(shù)來訪問: cv2.inpaint()
第一個算法是基于論文"An Image Inpainting Technique Based on the Fast Marching Method"坡锡。是基于快速匹配方法的蓬网。假設(shè)圖像里的一個區(qū)域要修復(fù)窒所。算法從這個區(qū)域的邊界開始,逐漸地進入?yún)^(qū)域帆锋,把邊界內(nèi)的所有東西填充上吵取。它取要修復(fù)的部分周圍的一個像素周圍的一小片鄰居。這個像素被周圍已知的像素的標準加權(quán)和替換掉窟坐。選擇權(quán)重是很重要的海渊。要修復(fù)的點周圍像素的權(quán)重較高。和正常邊界近的哲鸳,還有在邊界輪廓上的像素的權(quán)重較高臣疑。當像素被修復(fù)以后,它會通過快速匹配方法(FMM)移動到最近的像素徙菠。FMM保證那些已知像素周圍的像素首先被修復(fù)讯沈,所以這個就像人工啟發(fā)式的操作一樣。這個算法使用標志cv2.INPAINT_TELEA開啟婿奔。
第二個算法基于論文"Navier-Stokes, Fluid Dynamics, and Image and Video Inpainting".這個算法基于流體動力學和偏微分方程缺狠。基本原則是啟發(fā)式萍摊。它首從已知區(qū)域先沿著邊緣到未知區(qū)域訪問(由于邊緣應(yīng)該是連續(xù)的)挤茄。在匹配邊要修復(fù)區(qū)域邊界的梯度向量時持續(xù)畫等值線(把相同亮度的點用線連起來,類似于輪廓線)冰木。這時候用到流體動力學穷劈。之后會填充顏色以減小最小方差。這個算法用標志cv2.INPAINT_NS啟用踊沸。
編碼
我們需要創(chuàng)建和輸入圖像相同大小的掩圖歇终,需要修復(fù)的區(qū)域?qū)?yīng)的像素要非0.剩下的就簡單了。我的圖像被一些黑色劃痕給破壞了(實際上是我自己加的)逼龟。我用繪圖工具對應(yīng)的標記出來评凝。
import numpy as np
import cv2img = cv2.imread('messi_2.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()
看下面的結(jié)果。第一個圖片是輸入圖像腺律,第二個是掩圖奕短,第三個是用第一種算法的結(jié)果,最后一張是第二種算法的結(jié)果匀钧。
END