Inpainting の実装
① まずInpainting したい領域をはじめに設定しておきます.今回は白く塗りつぶしている領域のInpainting を行いたいため,白の部分のみを取り出します.
import cv2 import numpy as np im_b = cv2.imread('01_b.png',0) mask = im_b == 255 mask = np.array(mask) mask = mask.astype(np.uint8) cv2.imshow('hoge',mask*255) cv2.waitKey(0)
code02.py
② それぞれの重要な値の計算を行います.
\begin{align} \delta L^n (i,j) = (L^n(i+1,j) - L^n (i-1,j), L^n(i,j+1) - L^n (i,j-1)) \end{align}
im_lap = cv2.Laplacian(im_b,cv2.CV_32F) lap_tx = np.zeros((row,col)) lap_ty = np.zeros((row,col)) for i in range(0,row): for j in range(0,col): if mask[i,j] == 1: lap_tx[i,j] = im_lap[i+1,j] - im_lap[i-1,j] lap_ty[i,j] = im_lap[i,j+1] - im_lap[i,j-1]
code03.py
\begin{align} \frac{N}{|N|} = \frac{(-I_y (i,j),I_x(i,j))}{\sqrt{I_x(i,j)^2 + I_y(i,j)^2}} \end{align}
## calculate normal kernelx = np.array([[0, 0, 0], [-1, 0, 1], [0, 0, 0]]) dstx = cv2.filter2D(im_b, cv2.CV_64F, kernelx) kernely = np.array([[0, -1, 0], [0, 0, 0], [0, 1, 0]]) dsty = cv2.filter2D(im_b, cv2.CV_64F, kernely) N_mod = np.power(np.power(dstx,2) + np.power(dstx,2),1/2)
code04.py
③ 以下の更新式に従って更新を行います.
\begin{align} I_t (i,j) = \left(\delta L(i,j) \cdot \frac{N}{|N|} \right) |\nabla I (i,j)| \end{align}
Open CV を使った実装
上の方法で出来るはずなのですが,現状うまく動きませんでした.なので,今回はOpenCVのライブラリを使って代用したいと思います.
OpenCV にはInpainting を実行してくれる関数があります. 元画像とマスク画像を与えるだけです. 以下,サンプルコードになります.
import numpy as np import cv2 img = cv2.imread('01_bb.png') mask = cv2.imread('mask2.png',0) mask = 1- mask/255 dst = cv2.inpaint(img,mask,3,cv2.INPAINT_NS) cv2.imshow('dst',dst) cv2.waitKey(0) cv2.destroyAllWindows()
sample02.py
お.なんかプログラムが動いている感じですね.しかし,やっぱりこの欠損を埋めるのは画像一枚からは難しいのでしょうね.