画像フィルタは,画像のある注目したい画素について,その近傍領域の画素も入力データとして何らかの処理を行い,注目画素の値を出力するものです.様々なフィルタが存在し,フィルタを利用すると画像の何らかの特徴(エッジやコーナーなど)を抽出できるようになります.このようなフィルタは畳み込みニューラルネットワークなどでも利用されています.
まず,平均化フィルタの仕組みを理解しよう.平均化フィルタは注目したい画素の近傍領域(例えば3×3=9画素)の平均値を利用するフィルタです.例えば入力画像の \(x=55\), \(y=85\), 画素値 \(=113\) の画素について,次のように近傍領域の平均値を計算します.
入力画像
平均化フィルタによって得られた画像は次のようになります.
平均化フィルタ
平均化フィルタなどここで考えるフィルタは線形空間フィルタリングと呼ばれます.この線形空間フィルタリングを数学的に定義してみます.入力画像を \(I\),出力画像を \(\tilde{I}\) とします.注目する画素の座標 \((x,y)\) に対する画素値を \(I(x, y)\) とし,近傍領域の大きさを \((2N+1)\times(2N+1)\) とすると線形空間フィルタは次のようになります.
ここで,上の式の \(\boldsymbol{F}\) はカーネルと呼ばれ,\((2N+1)\times(2N+1)\) の行列です.例えば,\(N=1\) の平均化フィルタのカーネルは次のようになります.
それでは平均化フィルタのコードを自作してみよう.なお,あらかじめ「表示関数の定義」ページを参照し,ライブラリのインポートと関数の定義を実行しておいてください.
RGBA形式の png 画像ファイルを RGB 形式に変換したのち,さらにグレースケールに変換して表示します.
ink_img = plt.imread('ink.png')
img = color.rgba2rgb(ink_img)
gray_img = color.rgb2gray(img)
show(gray_img)
繰り返し処理を使って,画素ごとに近傍領域の平均値を計算する処理を記述します.
mean_filter_img = np.copy(gray_img)
h, w = mean_filter_img.shape
for j in range(1, h-1):
for i in range(1, w-1):
mean_filter_img[j, i] = (
gray_img[j-1, i-1] + gray_img[j-1, i] + gray_img[j-1, i+1] +
gray_img[j, i-1] + gray_img[j, i] + gray_img[j, i+1] +
gray_img[j+1, i-1] + gray_img[j+1, i] + gray_img[j+1, i+1]
) / 9.0
show(mean_filter_img)
平均化フィルタを利用すると画像が平滑化することができます.つまり,画像中のノイズを低減することができるようになります.