概要
画像処理の空間フィルタリングについて解説し、OpenCV の filter2D を使ったやり方を紹介します。
空間フィルタリング
入力画像の各画素に対して、対象の画素及びその近傍の画素の画素値の重み付き総和を計算し、出力画像の画素値を計算する処理を空間フィルタリング (spacial filtering) または畳み込み (convolution) といいます。 フィルタリングを行う際の重みはカーネル (kernel) またはフィルタ (filter) といいます。
入力画像の画素を 、サイズが のフィルタの値を としたとき、出力画像の画素 は次のように計算できます。
フィルタリングの例
入力画像とカーネルは以下とします。


このとき、出力画像の各画素値はフィルタをスライドさせながら、カーネルと重なっている画素とカーネルの要素同士を乗算し、総和を取って計算します。

cv2.filter2D
OpenCV では、cv2.filter2D() でフィルタリングが行えます。
引数
名前 | 型 | デフォルト値 |
---|---|---|
src | ndarray | |
入力画像 | ||
ddepth | int | |
出力画像の型。-1 の場合は入力画像と同じ型を使用。 | ||
kernel | ndarray | |
カーネル | ||
anchor | tuple of 2-ints | (-1, -1) |
フィルタを表す行列のアンカー成分。(-1, -1) の場合は行列の中心。 | ||
delta | scalar | 0 |
重み付き総和を計算したあと、この delta を足す | ||
borderType | BorderTypes | cv2.BORDER_DEFAULT |
パディング方法 |
返り値
名前 | 説明 | ||
---|---|---|---|
dst | 出力画像 |
サンプルコード

In [1]:

ddepth – 出力画像の型
総和演算の結果は の範囲に収まらない可能性があり、ddepth
で指定した型で表せる範囲を超えた値はクリップされます。
値 | 意味 |
---|---|
-1 | 入力画像と同じ型 |
cv2.CV_8U | 符号なし8ビット |
cv2.CV_8S | 符号あり8ビット |
cv2.CV_16U | 符号なし16ビット |
cv2.CV_16S | 符号あり16ビット |
cv2.CV_32S | 符号あり32ビット |
cv2.CV_32F | 32ビット浮動小数点数 |
cv2.CV_64F | 64ビット浮動小数点数 |
In [2]:
ddepth=-1 (cv2.CV_8U) 0 239 uint8 ddepth=-1 (cv2.CV_16S) -223 239 int16
delta – オフセット
重み付き総和を計算したあとに delta を足します。
In [3]:


borderType – パディング方法
フィルタリングを行う際に、入力画像の端では画素が存在しない部分が出てくるので、その補完方法を指定します。
値 | 意味 |
---|---|
cv2.BORDER_CONSTANT | 0でパディングする |
cv2.BORDER_REPLICATE | 一番端の値を繰り返してパディングする |
cv2.BORDER_REFLECT | 端で値を反転させてパディングする |
cv2.BORDER_DEFAULT | cv2.BORDER_REFLECT と同じ |
入力画像
1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 |
- borderType=cv2.BORDER_CONSTANT
端は0でパディングします。(例: abcde -> 00|abcde|00)
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 2 | 3 | 4 | 5 | 0 | 0 |
0 | 0 | 6 | 7 | 8 | 9 | 10 | 0 | 0 |
0 | 0 | 11 | 12 | 13 | 14 | 15 | 0 | 0 |
0 | 0 | 16 | 17 | 18 | 19 | 20 | 0 | 0 |
0 | 0 | 21 | 22 | 23 | 24 | 25 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
- borderType=cv2.BORDER_REPLICATE
端の画素を繰り返してパディングします。(例: abcde -> aa|abcde|ee)
1 | 1 | 1 | 2 | 3 | 4 | 5 | 5 | 5 |
1 | 1 | 1 | 2 | 3 | 4 | 5 | 5 | 5 |
1 | 1 | 1 | 2 | 3 | 4 | 5 | 5 | 5 |
6 | 6 | 6 | 7 | 8 | 9 | 10 | 10 | 10 |
11 | 11 | 11 | 12 | 13 | 14 | 15 | 15 | 15 |
16 | 16 | 16 | 17 | 18 | 19 | 20 | 20 | 20 |
21 | 21 | 21 | 22 | 23 | 24 | 25 | 25 | 25 |
21 | 21 | 21 | 22 | 23 | 24 | 25 | 25 | 25 |
21 | 21 | 21 | 22 | 23 | 24 | 25 | 25 | 25 |
- borderType=cv2.BORDER_REFLECT
端で折り返してパディングします。(例: abcde -> ba|abcde|ed)
7 | 6 | 6 | 7 | 8 | 9 | 10 | 10 | 9 |
2 | 1 | 1 | 2 | 3 | 4 | 5 | 5 | 4 |
2 | 1 | 1 | 2 | 3 | 4 | 5 | 5 | 4 |
7 | 6 | 6 | 7 | 8 | 9 | 10 | 10 | 9 |
12 | 11 | 11 | 12 | 13 | 14 | 15 | 15 | 14 |
17 | 16 | 16 | 17 | 18 | 19 | 20 | 20 | 19 |
22 | 21 | 21 | 22 | 23 | 24 | 25 | 25 | 24 |
22 | 21 | 21 | 22 | 23 | 24 | 25 | 25 | 24 |
17 | 16 | 16 | 17 | 18 | 19 | 20 | 20 | 19 |
コメント