畳み込みによる画像のノイズ除去

画像などの2次元配列で、周囲に非ゼロの値が存在しないような孤立したピクセル値をゼロにしたいことがある。 例えば、天体画像を N-sigma clipping した際に、ノイズの影響で天体以外の場所に残ってしまった スパイク状のゴミを消去したい場合などである。 この場合、あるピクセルの周囲に非ゼロの値がいくつ存在するかを2次元の畳み込みで求めるのが簡単である。

Python code

2次元のとある NumPy 配列 array があるとする。 このとき、以下のような2次元配列 kernel と畳み込むと、 周囲のピクセル値の和となるような2次元配列を計算できる。

import numpy as np

kernel = np.array([[1, 1, 1],
                   [1, 0, 1],
                   [1, 1, 1]])

これを応用して、非ゼロを True 、それ以外を False とするような 2次元配列に対して同様の操作をすることで、周囲の非ゼロピクセル数が計算できる。

from scipy.signal import convolve2d

# 非ゼロを True で表す
condition = (array != 0)

# 周囲の非ゼロピクセル数を計算する
neighbours = convolve2d(condition, kernel, mode='same',
                        boundary='fill', fillvalue=0)

あとはこれを使って孤立したピクセル (neighbours==0) を処理すれば良い。

# 周囲に非ゼロの値がないピクセル値をゼロにする
array[neighbours==0] = 0

Others

余談だが、この方法を使って Conway’s game of life (ライフゲーム) を簡単に実装することができる。

Licensed under CC BY 4.0
Last updated on 2021-08-15 20:00 +0900
Built with Hugo
Theme Stack designed by Jimmy