PythonとOpenCVを用いて空間フィルタリング処理する方法をソースコード付きで解説します。
空間フィルタリング(畳み込み演算)
空間フィルタリング(畳み込み演算)は、画像処理において輪郭検出やぼかし(ノイズ除去)など広く使用されます。原理と計算式については以下ページで解説しています。

また、OpenCVライブラリでは、cv2.filter2Dメソッドで空間フィルタリングを簡単に実装できます。
今回は、空間フィルタリングの処理を以下の2通りの方法で実装する方法を解説します。
方法①・・・NumPyでアルゴリズムを書いて実装
方法②・・・cv2.filter2Dで実装
解説動画
本ページの内容は以下動画で解説しています。
サンプルコード①OpenCVで実装した場合
サンプルプログラムのソースコードです。
実行結果
■入力画像(左)と出力画像(右)
コード解説
このカーネルは、Sobelフィルタと呼ばれるもので、水平方向の輪郭を検出するために使用されます。
kernel = np.array([[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]])
cv.filter2D
を使用して、入力画像gray
に対してカーネルkernel
を適用して畳み込み演算をします。
第2引数の-1
は、出力画像の深さ(データ型)を入力画像と同じにすることを指定しています。dst
は畳み込み演算後の出力画像す。
dst = cv.filter2D(gray, -1, kernel)
サンプルコード②NumPyで実装した場合
実行結果
■入力画像(左)と出力画像(右)
コード解説
filter2d
関数は、入入力画像src
に対して指定されたカーネルkernel
を使用して畳み込み演算を行い、空間フィルタリングされた画像を生成します。
以下では、カーネルのサイズ(行数m
と列数n
)を取得します。
m, n = kernel.shape
-
カーネルの半径
d
を計算します。これは、畳み込み演算をしない領域の幅となります。
d = int((m-1)/2)
入力画像src
の高さh
と幅w
を取得します。
h, w = src.shape[0], src.shape[1]
出力画像用の2次元配列dst
を入力画像と同じサイズで要素は全て0で初期化します。
dst = np.zeros((h, w))
入力画像の各ピクセルに対して、カーネルを適用して畳み込み演算を行います。
src[y-d:y+d+1, x-d:x+d+1]
は、カーネルのサイズに対応する入力画像の部分領域を取得します。
np.sum(src[y-d:y+d+1, x-d:x+d+1]*kernel)
は、部分領域とカーネルの要素ごとの積の総和を計算し、その値を出力画像dst
の対応するピクセルに設定します。
for y in range(d, h - d):
for x in range(d, w - d):
# 畳み込み演算
dst[y][x] = np.sum(src[y-d:y+d+1, x-d:x+d+1]*kernel)
フィルタリング後の出力画像dst
を返します。
return dst
関連記事


コメント