SciPyとの連携 -- フィルタカーネルの推定とウィーナフィルタによる画像復元


ブレやぼけなどの劣化を含む画像を入力とし、 ウィーナフィルタによる画像復元を行うサンプルコードです。

劣化は線形フィルタにより生じたことを仮定し、 SciPy を用いて劣化を生じされたフィルタカーネルを推定します。 フィルタカーネルの推定のため、劣化を含む画像に対応する、劣化を含まない理想的な画像を入力として使用します。

本サンプルの実行には予め SciPy と scikit-image をインストールしておく必要があります。 pip コマンドを使用する場合、次のようにインストールしてください。

pip install scipy==1.6.2 scikit-image==0.18.1
import numpy as np
import pyfie
import skimage.util
import scipy.optimize

# 利便のため PyFIE 関数が返すエラーコードに応じて例外を発生させる機能を有効化
pyfie.ctrl.enable_f_err_exception(True)

# 入力画像読み込み
# 理想的な画像
himg_ideal = pyfie.imread("wiener_ideal.png")
# 劣化画像
himg_blurred = pyfie.imread("wiener_blurred.png")

assert himg_ideal.width == himg_blurred.width and himg_ideal.height == himg_blurred.height

# カーネルサイズを設定
kernel_size = (7, 7)

# -- カーネルフィルタ係数算出 --

# フィルタ係数は「理想的な画像にカーネルフィルタ適用した画像」と
# 「劣化画像」の画素値の差の二乗和が最⼩になるような非負の値を設定する。
# 次の最小二乗問題を解くように行列を設定: ideal_mat * coeffs == degraded_mat

# 理想的な画像の行列
# 各y, x座標にて、その画素でフィルタを適用した際に参照される画素を格納したビューを取得
ideal_mat = skimage.util.view_as_windows(himg_ideal.ndarray, kernel_size)
# 窓部分と画像部分をそれぞれ平坦化
ideal_mat = ideal_mat.reshape(-1, kernel_size[0] * kernel_size[1])

# 劣化画像の行列
degraded_mat = himg_blurred.ndarray.astype(float)
# ボーダー部分を除去し、サイズをideal_matと合わせる
degraded_mat = degraded_mat[
    kernel_size[0] // 2:-kernel_size[0] // 2 + 1, kernel_size[1] // 2:-kernel_size[1] // 2 + 1
]
# 平坦化
degraded_mat = degraded_mat.flatten()

# 係数算出
coeffs = scipy.optimize.nnls(ideal_mat, degraded_mat)[0]
coeffs = coeffs.reshape(*kernel_size)

# 係数表示
print("estimated coefficients:")
print(np.array_repr(coeffs, precision=3, suppress_small=True))

# -- 画像復元 --
# フィルタカーネルをFIE形式に変換
kernel = pyfie.F_FILTER_KERNEL_T(
    coeffs, 1.0, kernel_size[1], kernel_size[0], kernel_size[1] // 2, kernel_size[0] // 2)

# 出力画像確保
himg_restored = himg_blurred.empty_like()

# ウィーナフィルタ実行
pyfie.wiener(himg_blurred, himg_restored, kernel, gamma=0.01)

# 結果保存
pyfie.imwrite("wiener_restored.png", himg_restored)

処理結果例

ブレやぼけなどの劣化を含む画像

../../_images/wiener_blurred.png

劣化を含まない理想的な画像

../../_images/wiener_ideal.png

推定したフィルタカーネル

[[0.   , 0.   , 0.   , 0.   , 0.   , 0.001, 0.   ],
 [0.   , 0.199, 0.   , 0.   , 0.   , 0.   , 0.   ],
 [0.   , 0.002, 0.196, 0.002, 0.   , 0.   , 0.   ],
 [0.   , 0.   , 0.   , 0.198, 0.   , 0.001, 0.   ],
 [0.   , 0.   , 0.   , 0.   , 0.199, 0.   , 0.   ],
 [0.   , 0.   , 0.   , 0.   , 0.   , 0.198, 0.   ],
 [0.   , 0.   , 0.   , 0.   , 0.   , 0.001, 0.   ]]

画像復元結果

../../_images/wiener_restored.png

ダウンロード