【画像処理】空間フィルタリングと畳み込み演算(マスク演算)

画像処理における空間フィルタリングと畳み込み演算(マスク演算)の計算方法についてまとめました。

スポンサーリンク

空間フィルタリングとは

空間フィルタリング (Spatial filtering) とは、入力画像の注目する画素値だけでなく、その近傍(周囲)にある画素値も利用し、出力画像の画素値を計算する処理です。
この計算のことを畳み込み演算、もしくはマスク演算といいます。
空間フィルタリングを利用することで、例えば、以下のように画像から輪郭だけを取り出すことができます。

■入力画像(左)と出力画像(右)

スポンサーリンク

畳み込み演算の計算方法

空間フィルタリングでは、畳み込み演算により出力画像を求めます。
例えば、入力画像IとカーネルKが次のように与えられたします。

(1)   \begin{eqnarray*} I= \left[ \begin{array}{ccccc} I(0, 0) & I(1, 0) & I(2, 0) &  I(3, 0)\\ I(0, 1) & I(1, 1) & I(2, 1) &  I(3, 1)\\ I(0, 2) & I(1, 2) & I(2, 2) &  I(3, 2)\\ I(0, 3) & I(1, 3) & I(2, 3) &  I(3, 3)\\ \end{array} \right], K= \left[ \begin{array}{ccccc} K(0, 0) & K(1, 0) & K(2, 0)\\ K(0, 1) & K(1, 1) & K(2, 1)\\ K(0, 2) & K(1, 2) & K(2, 2)\\ \end{array} \right] \end{eqnarray*}

このとき、出力画像I'端以外の画素値は次のように計算します。

(2)   \begin{eqnarray*} I'= \left[ \begin{array}{ccccc} I'(0, 0) & I'(1, 0) & I'(2, 0) &  I'(3, 0)\\ I'(0, 1) & I'(1, 1) & I'(2, 1) &  I'(3, 1)\\ I'(0, 2) & I'(1, 2) & I'(2, 2) &  I'(3, 2)\\ I'(0, 3) & I'(1, 3) & I'(2, 3) &  I'(3, 3)\\ \end{array} \right] \end{eqnarray*}

■注目画素I(1,1)について

(3)   \begin{eqnarray*} I'(1,1)&=&K(0,0) I(0,0)+K(1,0) I(1,0)+K(2,0) I(2,0)\\ &+&K(0,1) I(0,1)+K(1,1) I(1,1)+K(2,1) I(2,1)\\ &+&K(0,2) I(0,2)+K(1,2) I(1,2)+K(2,2) I(2,2)\\ \end{eqnarray*}

■注目画素I(2,1)について

(4)   \begin{eqnarray*} I'(2,1)&=&K(0,0) I(1,0)+K(1,0) I(2,0)+K(2,0) I(3,0)\\ &+&K(0,1) I(1,1)+K(1,1) I(2,1)+K(2,1) I(3,1)\\ &+&K(0,2) I(1,2)+K(1,2) I(2,2)+K(2,2) I(3,2)\\ \end{eqnarray*}

■注目画素I(1,2)について

(5)   \begin{eqnarray*} I'(1,2)&=&K(0,0) I(0,1)+K(1,0) I(1,1)+K(2,0) I(2,1)\\ &+&K(0,1) I(0,2)+K(1,1) I(1,2)+K(2,1) I(2,2)\\ &+&K(0,2) I(0,3)+K(1,2) I(1,3)+K(2,2) I(2,3) \end{eqnarray*}

■注目画素I(2,2)について

(6)   \begin{eqnarray*} I'(2,2)&=&K(0,0) I(1,1)+K(1,0) I(2,1)+K(2,0) I(3,1)\\ &+&K(0,1) I(1,2)+K(1,1) I(2,2)+K(2,1) I(3,2)\\ &+&K(0,2) I(1,3)+K(1,2) I(2,3)+K(2,2) I(3,3)\\ \end{eqnarray*}

  • カーネルKのサイズ
    • 近傍の画素数(3\times 3なら8近傍)
  • カーネルKの要素
    • 近傍にある画素の重み(目的や用途に応じて変える)
スポンサーリンク

端の画素の処理


入力画像の端の画素を注目画素とした時は、近傍の画素数が不足します。
例えば、I(0,0)に隣接する画素はI(0,1), I(1,0), I(1,1)の3つしかありません。
その場合の処理方法は特に定義されていないため、自分で定義します。

色々なやり方が考えられますが、簡単化のため今回は次のように処理します。

  • 輪郭抽出に使う場合
    • 出力画像の端の画素値は全て0にする
  • 平滑化処理に使う場合
    • 出入力画像の画素値をそのまま出力画像の画素値にする
スポンサーリンク

畳み込み演算の計算式

カーネルサイズが3\times 3の場合、畳み込み演算の計算を定式化すると次のようになります。

(7)   \begin{eqnarray*} I'(x,y)=\sum_{i=-1}^{1}\sum_{j=-1}^{1}K(i, j) I(x+i, y+j) \end{eqnarray*}

スポンサーリンク

畳み込み演算の計算例

入力画像IとカーネルKが次のように与えられたとき、出力画像I'を求めよ。

(8)   \begin{eqnarray*} I= \left[ \begin{array}{ccccc} 11& 12 & 13 &  14\\ 21& 22 & 23 &  24\\ 31& 32 & 33 &  34\\ 41& 42 & 43 &  44\\ \end{array} \right], K= \left[ \begin{array}{ccccc} -1 & -2 & -1\\ 0 & 0 & 0\\ 1 & 2 & 1\\ \end{array} \right] \end{eqnarray*}

解説

入力画像IとカーネルKを畳み込み演算してやると

(9)   \begin{eqnarray*} I'(1,1)&=&(-1\cdot 11)+(-2\cdot 12)+(-1\cdot 13)\\ &+&(0\cdot 21)+(0\cdot 22)+(0\cdot 23)\\ &+&(1\cdot 31)+(2\cdot 32)+(1\cdot 33)\\ &=&80 \end{eqnarray*}

(10)   \begin{eqnarray*} I'(2,1)&=&(-1\cdot 12)+(-2\cdot 13)+(-1\cdot 14)\\ &+&(0\cdot 22)+(0\cdot 23)+(0\cdot 24)\\ &+&(1\cdot 32)+(2\cdot 33)+(1\cdot 34)\\ &=&80 \end{eqnarray*}

(11)   \begin{eqnarray*} I'(1,2)&=&(-1\cdot 21)+(-2\cdot 22)+(-1\cdot 23)\\ &+&(0\cdot 31)+(0\cdot 32)+(0\cdot 33)\\ &+&(1\cdot 41)+(2\cdot 42)+(1\cdot 43)\\ &=&80 \end{eqnarray*}

(12)   \begin{eqnarray*} I'(2,2)&=&(-1\cdot 22)+(-2\cdot 23)+(-1\cdot 24)\\ &+&(0\cdot 32)+(0\cdot 33)+(0\cdot 34)\\ &+&(1\cdot 42)+(2\cdot 43)+(1\cdot 44)\\ &=&80 \end{eqnarray*}

となります。今回、端の画素値は全て0にすることにします。

(13)   \begin{eqnarray*} I'(0,0)&=&I'(0,1)=I'(0,2)=I'(0,3)=I'(1,0)=I'(1,3)=I'(2,0)\\ &=&I'(2,3)=I'(3,0)=I'(3,1)=I'(3,2)=I'(3,3)=0 \end{eqnarray*}

すると、出力画像I'は次のようになります。

(14)   \begin{eqnarray*} I'= \left[ \begin{array}{ccccc} 0 & 0 & 0 &  0\\ 0& 80 & 80 &  0\\ 0& 80 & 80 &  0\\ 0 & 0 & 0 &  0\\ \end{array} \right] \end{eqnarray*}

スポンサーリンク

関連ページ

PythonとOpenCVを用いて空間フィルタリングを実装する方法について以下ページで解説しています。

【Python/OpenCV】空間フィルタリング・畳み込み演算(cv2.filter2d)
PythonとOpenCVを用いて空間フィルタリング処理する方法をソースコード付きで解説します。

PythonとOpenCVを用いた画像処理全般については以下ページで解説しています。

Python版OpenCVで画像処理入門・サンプル集
Python版OpenCVで画像処理プログラミングを行う方法を入門者向けにソースコード付きで解説するページです。

他の画像処理アルゴリズムについては、以下ページでまとめています。

【画像処理入門】アルゴリズム&プログラミング
この記事では、画像処理における基本的なアルゴリズムとその実装例(プログラム)についてまとめました。
画像処理
スポンサーリンク
西住工房

コメント