はじめに
画像処理において、ノイズの除去は重要な前処理の一つです。
OpenCVには、効果的なノイズ除去アルゴリズムが実装されており、その中でも特に優れているのがcv2.fastNlMeansDenoising
関数とcv2.fastNlMeansDenoisingColored
関数です。
この記事では、この関数の使い方と特徴について詳しく解説します。
ノイズ除去処理
cv2.fastNlMeansDenoising
関数とcv2.fastNlMeansDenoisingColored
関数が使用されるのは、次のような場面です。
- 写真の品質向上
- デジタルカメラやスマートフォンで撮影した低光量環境下の写真
- 高ISO感度で撮影された画像のノイズ除去
- 医療画像処理
- MRIやCTスキャンなどの医療画像のノイズ除去
- 画像診断の精度向上
- 監視カメラ映像の処理
- 低解像度や低光量環境下での監視カメラ映像の品質向上
- 古い写真や映像の修復
- スキャンした古い写真のノイズやグレイン除去
- デジタル化された古いフィルム映像のクリーニング
また、cv2.fastNlMeansDenoising
関数とcv2.fastNlMeansDenoisingColored
関数は次のような特徴があります。
cv2.fastNlMeansDenoising関数
OpenCVに実装されているノイズ除去アルゴリズムの一つです。
この関数は、Non-Local Means Denoising(非局所平均法)アルゴリズムの高速バージョン(http://www.ipol.im/pub/algo/bcm_non_local_means_denoising/)を実装しています。
主にグレースケール画像のノイズ除去に使用されます。
cv2.fastNlMeansDenoising
関数の引数と戻り値は下の通りです。
引数
名称 | 説明 |
---|---|
入力画像(必須) | グレースケールまたはカラーの入力画像データ。numpy.ndarray オブジェクト。 |
dst(オプション) | 結果がこの変数に格納されます。指定しない場合は、入力画像と同じサイズ・型で新しい配列が作成されて結果が格納され、戻り値として取得できます。 |
h(オプション) | フィルタリングの強さを決定するパラメータ(大きい値ほど強くノイズ除去される) |
templateWindowSize(オプション) | テンプレートパッチのサイズ(奇数、デフォルト:7) |
searchWindowSize(オプション) | 各ピクセル周辺の検索窓サイズ(奇数、デフォルト:21) |
戻り値
ノイズ除去が適用された画像データをnumpy.ndarray
オブジェクトで返します。
使い方
以下にサンプルコードを示します。
ノイズ除去を行うのは下の画像(左)にGIMPでフィルタのRGBノイズを適用した画像(右)を使用しました。
この画像にcv2.fastNlMeansDenoising
関数を適用した結果が以下となります。
引数のh
を10
, 15
, 20
と変化させています。
hの値が大きいほど、ノイズ除去の効果が強く得られていることが確認できます。
h=20でもエッジがしっかり保持されていますが、木材の並びに表れる壁の横線などが消えかかっていることが確認できます。
細部の表現は、hの値が大きいほど消されてしまうことがわかります。
フィルタリングの強さhは画像ごとに調整が必要ですね。
import cv2 # 画像の読み込み image = cv2.imread("gray_noized_image.jpg") # ノイズ除去の実行 denoised_image_h10 = cv2.fastNlMeansDenoising(image, None, h=10, templateWindowSize=5, searchWindowSize=21) denoised_image_h15 = cv2.fastNlMeansDenoising(image, None, h=15, templateWindowSize=5, searchWindowSize=21) denoised_image_h20 = cv2.fastNlMeansDenoising(image, None, h=20, templateWindowSize=5, searchWindowSize=21) # 画像を保存する cv2.imwrite("gray_denoized_h10.jpg", denoised_image_h10) cv2.imwrite("gray_denoized_h15.jpg", denoised_image_h15) cv2.imwrite("gray_denoized_h20.jpg", denoised_image_h20)
cv2.fastNlMeansDenoisingColored関数
cv2.fastNlMeansDenoisingColored
関数はcv2.fastNlMeansDenoising
関数のカラー画像に対応した関数です。
両関数とも、Non-Local Means(NLM)ノイズ除去アルゴリズムの高速実装版を基盤していることについては共通です。
cv2.fastNlMeansDenoisingColored
関数の引数と戻り値は下の通りです。
引数
名称 | 説明 |
---|---|
入力画像(必須) | グレースケールまたはカラーの入力画像データ。numpy.ndarray オブジェクト。 |
dst(オプション) | 結果がこの変数に格納されます。指定しない場合は、入力画像と同じサイズ・型で新しい配列が作成されて結果が格納され、戻り値として取得できます。 |
h(オプション) | 輝度チャンネルに対するフィルタ強度(大きい値ほど強くノイズ除去される) |
hColor(オプション) | 色チャンネルに対するフィルタ強度(デフォルト:3) |
templateWindowSize(オプション) | テンプレートパッチのサイズ(奇数、デフォルト:7) |
searchWindowSize(オプション) | 各ピクセル周辺の検索窓サイズ(奇数、デフォルト:21) |
cv2.fastNlMeansDenoisingColored
関数を使用することで、カラー画像特有の課題に対応した、より高品質で自然なノイズ除去結果を得ることができます。cv2.fastNlMeansDenoising
関数のカラー対応した拡張と最適化が施された関数と言えるのではないでしょうか。
戻り値
ノイズ除去が適用された画像データをnumpy.ndarray
オブジェクトで返します。
使い方
以下にサンプルコードを示します。
ノイズ除去を行うのは、筆者が高ISOで撮影に失敗した夜空の写真です。😅
かなりノイズが入って、ざらついている画像です。
この画像にcv2.fastNlMeansDenoisingColored
関数を適用した結果が以下となります。
引数のh
を10
, 15
, 20
に、hColor
を3
, 7
に変化させています。h
の値が大きいほど、ノイズ除去の効果が強く得られていることが確認できます。h=20
では、小さな星が消えてしまいます。
赤っぽいノイズ、緑っぽいノイズが確認出来ますが、hColor
の値を7
に上げると赤と緑のノイズが除去されますが、他の部分が不自然になることは無いようです。
import cv2 # 画像の読み込み image = cv2.imread("color_noized_image.jpg") # ノイズ除去の実行 denoised_image_h10_hc3 = cv2.fastNlMeansDenoisingColored(image, None, h=10, hColor=3, templateWindowSize=5, searchWindowSize=21) denoised_image_h15_hc3 = cv2.fastNlMeansDenoisingColored(image, None, h=15, hColor=3, templateWindowSize=5, searchWindowSize=21) denoised_image_h20_hc3 = cv2.fastNlMeansDenoisingColored(image, None, h=20, hColor=3, templateWindowSize=5, searchWindowSize=21) denoised_image_h10_hc7 = cv2.fastNlMeansDenoisingColored(image, None, h=10, hColor=7, templateWindowSize=5, searchWindowSize=21) denoised_image_h15_hc7 = cv2.fastNlMeansDenoisingColored(image, None, h=15, hColor=7, templateWindowSize=5, searchWindowSize=21) denoised_image_h20_hc7 = cv2.fastNlMeansDenoisingColored(image, None, h=20, hColor=7, templateWindowSize=5, searchWindowSize=21) # 画像を保存する cv2.imwrite("color_denoised_image_h10_hc3.jpg", denoised_image_h10_hc3) cv2.imwrite("color_denoised_image_h15_hc3.jpg", denoised_image_h15_hc3) cv2.imwrite("color_denoised_image_h20_hc3.jpg", denoised_image_h20_hc3) cv2.imwrite("color_denoised_image_h10_hc7.jpg", denoised_image_h10_hc7) cv2.imwrite("color_denoised_image_h15_hc7.jpg", denoised_image_h15_hc7) cv2.imwrite("color_denoised_image_h20_hc7.jpg", denoised_image_h20_hc7)
おわりに
cv2.fastNlMeansDenoisingColored
関数、cv2.fastNlMeansDenoising
関数のどちらも、CPUでの処理時間はそれなりにかかってしまう印象ですが、GPU処理や並列処理を導入することで、処理速度を向上させることもできます。
バイラテラル フィルタに近い結果が得られますが、ノイズ除去に関しては、これらの関数を使う方が適しているかもしれません。
バイラテラル フィルタはこの記事で紹介しています。
また、両関数とも、使いこなすためには引数に設定する値の最適化が重要となりますので、試行錯誤が必要かもしれませんが、どちらも使い方や特徴はとても似ているので、使い分けは容易ではないかと思います。
ご質問や取り上げて欲しい内容などがありましたら、コメントをお願いします。
最後までご覧いただきありがとうございました。
参考リンク
Image Denoising
You will learn about Non-local Means Denoising algorithm to remove noise in the image. You will see different functions like cv.fastNlMeansDenoising(), cv.fastNlMeansDenoisingColored() etc.
OpenCV: fastNlMeansDenoising
Perform image denoising using Non-local Means Denoising algorithm http://www.ipol.im/pub/algo/bcm_non_local_means_denoising/ with several computational optimizations. Noise expected to be a gaussian white noise.
OpenCV: fastNlMeansDenoisingColored
Modification of fastNlMeansDenoising function for colored images.
■(広告)OpenCVの参考書としてどうぞ!■