Python版OpenCVでバイラテラルフィルタ(Bilateral Filter)を実装し、画像のノイズを除去する方法をソースコード付きで解説します。
バイラテラルフィルタとは
バイラテラルフィルタ(Bilateral Filter)は、画像の輪郭検出に用いられる空間フィルタの1つです。ノイズ除去を行いつつ輪郭を保持する優れた特性があります。これを実現するために、バイラテラルフィルタは空間的な距離と輝度差の両方に基づいて重み付けを行います。つまり、輝度差の差が大きいところ(輪郭部分)は、フィルタの重みを小さくします。バイラテラルフィルタの原理については、以下ページで別途解説しています。

今回は、Python版OpenCVを用いてバイラテラルフィルタを実装し画像のノイズを除去する方法を解説します。
サンプルコード① cv2.bilateralFilterで実装
OpenCVのcv2.bilateralFilterで実装した例です。
実行結果
以下は、天体写真(オリオン大星雲、M42)に対してサンプルプログラムを実行した結果です。
■入力画像(左)と出力画像(右)
背景ノイズを除去しつつ、星雲の輪郭は保持されています。
コード解説
以下の部分で画像imgにバイラテラルフィルタを適用し、フィルタ処理された画像をfilteredという変数に保存しています。
filtered = cv.bilateralFilter(img, d=9, sigmaColor=75, sigmaSpace=75)
パラメータ | 説明 |
---|---|
d |
フィルタを適用する画素の範囲を直径で指定します。値を大きくするほどノイズ除去の効果が大きくなります。 |
sigmaColor |
画素値の変化量に基づく重み付けを計算する際の空間フィルタの標準偏差。値を大きくするほど、ノイズ除去効果が大きくなります。(輪郭もぼけやすくなる) |
sigmaSpace |
画素の距離に基づく重み付けを計算する際の空間フィルタの標準偏差。値を大きくするほど、広範囲の画素の距離を考慮して重み付けを行い、フィルタの効果が強くなります。 |
サンプルコード② パラメータをスライドバーで調整
以下は、バイラテラルフィルタのパラメータをスライドバーで調整し、リアルタイムで処理結果を表示するサンプルプログラムです。
実行結果
以下は、天体写真(オリオン大星雲、M42)に対してサンプルプログラムを実行した結果です。
コード解説
以下のupdate
関数は、トラックバーの位置に基づいてバイラテラルフィルタのパラメータを取得し、フィルタを適用します。この関数が呼び出されるたびにフィルタが更新され、画像が再表示されます。
def update(val):
# トラックバーの位置に基づいてパラメータを取得
d = cv.getTrackbarPos('d', 'Bilateral Filter')
sigmaColor = cv.getTrackbarPos('sigmaColor', 'Bilateral Filter')
sigmaSpace = cv.getTrackbarPos('sigmaSpace', 'Bilateral Filter')
# バイラテラルフィルタを適用
filtered = cv.bilateralFilter(img, d, sigmaColor, sigmaSpace)
# フィルタ処理後の画像を表示
cv.imshow('Bilateral Filter', filtered)
以下で新しいウィンドウを作成し、3つのトラックバーを追加します。トラックバーはそれぞれd
、sigmaColor
、sigmaSpace
のパラメータを調整するためのものです。
# ウィンドウを作成
cv.namedWindow('Bilateral Filter')
# トラックバーを作成
cv.createTrackbar('d', 'Bilateral Filter', 9, 50, update)
cv.createTrackbar('sigmaColor', 'Bilateral Filter', 75, 200, update)
cv.createTrackbar('sigmaSpace', 'Bilateral Filter', 75, 200, update)
createTrackbarについても引数の役割を簡単に解説します。
cv.createTrackbar('d', 'Bilateral Filter', 9, 50, update)
パラメータ | 説明 |
---|---|
d | ラックバーのラベル(名前)を指定します。このラベルはトラックバーの識別に使用されます。ここでは、d という名前が使われています。 |
9 | トラックバーの初期位置(初期値)を指定します。この場合、トラックバーの初期位置は9です。 |
50 | トラックバーの最大値を指定します。この場合、トラックバーの範囲は0から50までになります。 |
update | トラックバーが変更されたときに呼び出されるコールバック関数を指定します。ここでは、update 関数が指定されています。この関数は、トラックバーの値が変更されるたびに実行され、フィルタのパラメータが更新されます。 |
トラックバーの位置を変更するたびにupdate
関数が呼び出され、トラックバーの新しい位置に基づいてバイラテラルフィルタのパラメータが再計算され、画像に適用されます。
これにより、リアルタイムでd
の値を変更しながらフィルタの効果を確認することができます。sigmaColorやsigmaSpaceのトラックバーについても同様です。
以下は、初期表示とメインループの部分です。最初にupdate
関数が呼び出され、初期表示が行われます。その後、ユーザーがq
キーを押すまでメインループが実行され続け、ループ内でキー入力を待機します。q
キーが押されると、すべてのウィンドウが閉じられ、プログラムが終了します。
# 初期表示
update(0)
# ユーザーが 'q' キーを押すまで待機
while True:
if cv.waitKey(1) & 0xFF == ord('q'):
break
cv.destroyAllWindows()
関連ページ

コメント