OpenCVで画像のInpaintingの解説

目次

1.画像のInpaintingの概要
__1.1 画像のInpaintingとは
__1.2 OpenCVのInpainting
__1.3 Navier-Stokesのアルゴリズム vs Fast Marching のアルゴリズム
2. 実験
__2.1 実験1: 兎画像に墨痕の削除
__2.2 実験2: 人の画像にウォーターマークの削除

1.画像のInpaintingの概要

1.1 画像のInpaintingとは

Inpaint は日本語では修復するという意味です。引っかき傷や,画像の上に書かれた文字などがナチュラルに復元される方法です。今回はOpenCVでのinpaintを説明と実験したいと思います。

1.2 OpenCVのInpainting

cv2.inpaint(image, mask, radius, method)
–image:修復作業を行う損傷した写真への道
–mask:写真の損傷部分に対応するマスクへのパス
–radius:デフォルトの修復半径は3ピクセルに設定されています。 この値を調整して、画像復元の範囲を大きくします。
–method:「telea」または「ns」アルゴリズムの選択ができます。アルゴリズムは、以下のようになっています。

Navier-Stokesのアルゴリズム(INPAINT_NS)

流体力学の理論を適用して、コンピュータービジョンの問題を解決します。下の画像の目的は、黒い領域を塗りつぶして、右のような画像を取得する事です。領域内の画像強度を上記の制約で更新する偏微分方程式(partial differential equation - PDE)を用いて補完をおこなっていきます。画像の滑らかさの情報は、画像のラプラシアンによって推定され、等輝度線(強度が等しい輪郭)に沿って伝播されます。 等輝度線は、90度回転した画像勾配によって推定されます。

Fast Marching のアルゴリズム(INPAINT_TELEA)

Fast Marching のアルゴリズムは、異なる手法を使用して補完をしていきます。 滑らかさの推定量として画像ラプラシアンを使用する代わりに、ピクセルの既知の画像近傍の加重平均を使用して修復します。 及び既知の近傍ピクセルと勾配を使用して、修復されるピクセルの色を推定します。逐次的なアルゴリズムであり、ピクセルが修復されると、境界を更新していきます。

長所と短所

理論と論文によれば、Navier-Stokesベースのインペインティングは遅い傾向があり、Fast Marchingベースの方法よりもぼやけた結果を生成する傾向があります。INPAINT_NSはテストでより良い結果を生成し、速度もINPAINT_TELEAよりわずかに優れていました。しかし以下で実験したところそうとは限らないことがわかりました。

アルゴリズムの論文:
cv2.INPAINT_TELEA: An image inpainting technique based on the fast marching method (Telea, 2004)
cv2.INPAINT_NS: Navier-stokes, Fluid dynamics, and image and 

2. 実験

環境:Google Colab
ライブラリ: OpenCV

2.1 実験1: 兎画像に墨痕の削除

入力データ:墨痕ある兎画像
目的:黒い墨痕を削除するという問題を考えていきます。

import numpy as np
import cv2
from google.colab.patches import cv2_imshow

# 画像を読む
img = cv2.imread('img11.png')
mask = cv2.imread('img12.png',0)

# サイズ変更
img = cv2.resize(img, (200, 200))
mask = cv2.resize(mask, (200, 200))

# Inpainting
dst11 = cv2.inpaint(img,mask,0,cv2.INPAINT_TELEA)
dst12 = cv2.inpaint(img,mask,3,cv2.INPAINT_TELEA)
dst13 = cv2.inpaint(img,mask,10,cv2.INPAINT_TELEA)
dst21 = cv2.inpaint(img,mask,0,cv2.INPAINT_NS)
dst22 = cv2.inpaint(img,mask,3,cv2.INPAINT_NS)
dst23 = cv2.inpaint(img,mask,10,cv2.INPAINT_NS)

# 入力データを表示
print("\nOriginal Image")
cv2_imshow(img)
print("\nMasked Image")
cv2_imshow(mask)

# 結果を表示
print("\nOutput (INPAINT_TELEA, radius=0) ")
cv2_imshow(dst11)
print("\nOutput (INPAINT_TELEA, radius=3) ")
cv2_imshow(dst12)
print("\nOutput (INPAINT_TELEA, radius=10) ")
cv2_imshow(dst13)

print("\nOutput (INPAINT_NS, radius=0)")
cv2_imshow(dst21)
print("\nOutput (INPAINT_NS, radius=3)")
cv2_imshow(dst22)
print("\nOutput (INPAINT_NS, radius=10)")
cv2_imshow(dst23)

入力データ ノイズになっている部分のデータ

出力データ
墨痕を削除して兎と草が補完されることができました。TELEA・高いRadiusを設定すると兎はがぼやけります。

2.2 実験2: 人の画像にあるキャプションの削除

入力データ:キャプション付きの人画像
目的:白いキャプションを削除していきます。

import numpy as np
import cv2
from google.colab.patches import cv2_imshow

# 画像を読む
img = cv2.imread('img21.png')
mask = cv2.imread('img22.png',0)

# サイズ変更
img = cv2.resize(img, (200, 200))
mask = cv2.resize(mask, (200, 200))

# Inpainting
dst11 = cv2.inpaint(img,mask,0,cv2.INPAINT_TELEA)
dst12 = cv2.inpaint(img,mask,3,cv2.INPAINT_TELEA)
dst13 = cv2.inpaint(img,mask,10,cv2.INPAINT_TELEA)
dst21 = cv2.inpaint(img,mask,0,cv2.INPAINT_NS)
dst22 = cv2.inpaint(img,mask,3,cv2.INPAINT_NS)
dst23 = cv2.inpaint(img,mask,10,cv2.INPAINT_NS)

# 入力データを表示
print("\nOriginal Image")
cv2_imshow(img)
print("\nMasked Image")
cv2_imshow(mask)

# 結果を表示
print("\nOutput (INPAINT_TELEA, radius=0) ")
cv2_imshow(dst11)
print("\nOutput (INPAINT_TELEA, radius=3) ")
cv2_imshow(dst12)
print("\nOutput (INPAINT_TELEA, radius=10) ")
cv2_imshow(dst13)

print("\nOutput (INPAINT_NS, radius=0)")
cv2_imshow(dst21)
print("\nOutput (INPAINT_NS, radius=3)")
cv2_imshow(dst22)
print("\nOutput (INPAINT_NS, radius=10)")
cv2_imshow(dst23)

入力データ
入力データデータはウォーターマークある人の画像とマーク画像です。

出力データ
キャプションを削除ができましたが、体と髪がボサボサになってしまいました。このように他の領域への影響もあることがあります。