はじめに
こんにちは!材料開発におけるデータ解析の効率化を目指す皆さん、お疲れ様です。
顕微鏡で撮影した画像、特に低倍率や低露光で撮影した画像には、どうしてもノイズが乗ってしまいますよね。ザラザラして見えたり、黒や白のポツポツ(ごま塩ノイズ)が現れたり…。これらのノイズは、後の二値化や粒子解析といった工程で大きな誤差を生む原因となり、解析結果の信頼性を著しく低下させてしまいます。
そこで今回は、**画像解析の前処理の第一歩として非常に重要な「フィルタリング」**に焦点を当て、Python(OpenCV)を使ってノイズを除去する実践的なテクニックを徹底解説します。様々な種類のフィルタの特徴と使い分けをマスターし、クリーンで解析しやすい画像を手に入れましょう!
なぜフィルタリングが必要なのか?
フィルタリングは、画像から不要な情報(ノイズ)を取り除き、必要な情報(対象物の輪郭など)を強調するための操作です。
例えば、下の画像を見てください。左が元画像、中央が「ごま塩ノイズ」、右が「ガウシアンノイズ」を付加したものです。
元画像 | ごま塩ノイズ | ガウシアンノイズ |
---|---|---|
![]() | ![]() | ![]() |
このようなノイズがあると、例えば「黒い部分(気孔)の面積を測りたい」と思っても、ノイズを気孔として誤検出してしまい、正確な測定ができません。フィルタリングによってこれらのノイズを平滑化(ぼかす)することで、より正確な解析が可能になるのです。
代表的なフィルタリング手法
ここでは、OpenCVで利用できる代表的な4つのフィルタを紹介します。それぞれのフィルタには得意なノイズと不得意なノイズがあり、画像の特性に合わせて使い分けることが重要です。
- 平均化フィルタ (Averaging Filter)
- ガウシアンフィルタ (Gaussian Filter)
- メディアンフィルタ (Median Filter)
- バイラテラルフィルタ (Bilateral Filter)
1. 平均化フィルタ
概要: カーネル(注目画素の周辺領域)内の全画素の平均値を、注目画素の新しい値とする、最もシンプルなフィルタです。
特徴:
- 計算が高速。
- ノイズだけでなく、エッジ(輪郭)もぼかしてしまう。
Pythonコード:
import cv2 # 画像をグレースケールで読み込み img_sp = cv2.imread('salt_pepper_noise.jpg', cv2.IMREAD_GRAYSCALE) # 5x5のカーネルで平均化フィルタを適用 avg_filtered = cv2.blur(img_sp, (5, 5)) cv2.imwrite('avg_filtered_sp.jpg', avg_filtered)
実行結果 (ごま塩ノイズ):
ノイズ画像 | 平均化フィルタ適用後 |
---|---|
![]() | ![]() |
ごま塩ノイズが全体的にぼやけていますが、輪郭も甘くなっているのが分かります。
2. ガウシアンフィルタ
概要: カーネル内の画素にガウス分布に基づいた重み付けをして平均を計算します。中心画素に近いほど重みが大きくなるのが特徴です。
特徴:
- 平均化フィルタよりも自然なぼかし方で、エッジの保持性が比較的高い。
- ガウシアンノイズの除去に特に効果的。
Pythonコード:
import cv2 # 画像をグレースケールで読み込み img_gaussian = cv2.imread('gaussian_noise.jpg', cv2.IMREAD_GRAYSCALE) # 5x5のカーネルでガウシアンフィルタを適用 gaussian_filtered = cv2.GaussianBlur(img_gaussian, (5, 5), 0) cv2.imwrite('gaussian_filtered_gaussian.jpg', gaussian_filtered)
実行結果 (ガウシアンノイズ):
ノイズ画像 | ガウシアンフィルタ適用後 |
---|---|
![]() | ![]() |
ガウシアンノイズのざらつきが滑らかになっているのが確認できます。
3. メディアンフィルタ
概要: カーネル内の画素値を大きさ順に並べ、その中央値 (Median) を注目画素の新しい値とします。
特徴:
- ごま塩ノイズ(ソルト&ペッパーノイズ)の除去に絶大な効果を発揮します。
- 平均値ではなく中央値を使うため、外れ値であるノイズの影響をほとんど受けません。
- エッジを比較的よく保持します。
Pythonコード:
import cv2 # 画像をグレースケールで読み込み img_sp = cv2.imread('salt_pepper_noise.jpg', cv2.IMREAD_GRAYSCALE) # カーネルサイズ5でメディアンフィルタを適用 median_filtered = cv2.medianBlur(img_sp, 5) cv2.imwrite('median_filtered_sp.jpg', median_filtered)
実行結果 (ごま塩ノイズ):
ノイズ画像 | メディアンフィルタ適用後 |
---|---|
![]() | ![]() |
黒と白の点が非常にきれいに除去されているのが一目瞭然です。
4. バイラテラルフィルタ
概要: ガウシアンフィルタに「輝度の差」の概念を加えたフィルタです。画素間の距離だけでなく、画素値(明るさ)が近い画素に大きな重みを付けます。
特徴:
- エッジを保持したままノイズを除去する能力が非常に高いです。
- 輪郭をぼかしたくない場合に最適です。
- 計算コストが他のフィルタに比べて高い。
Pythonコード:
import cv2 # 画像をグレースケールで読み込み img_gaussian = cv2.imread('gaussian_noise.jpg', cv2.IMREAD_GRAYSCALE) # バイラテラルフィルタを適用 bilateral_filtered = cv2.bilateralFilter(img_gaussian, 9, 75, 75) cv2.imwrite('bilateral_filtered_gaussian.jpg', bilateral_filtered)
実行結果 (ガウシアンノイズ):
ノイズ画像 | バイラテラルフィルタ適用後 |
---|---|
![]() | ![]() |
ノイズは滑らかにしつつ、結晶粒の輪郭がくっきりと保持されているのが分かります。
フィルタの使い分けまとめ
フィルタ名 | 得意なこと | 苦手なこと | おすすめのシーン |
---|---|---|---|
平均化フィルタ | 高速な平滑化 | エッジの保持 | とにかく素早く全体をぼかしたい時 |
ガウシアンフィルタ | ガウシアンノイズ除去、自然なぼかし | エッジの保持(平均化よりはマシ) | 一般的なノイズ除去、前処理の定番 |
メディアンフィルタ | ごま塩ノイズ除去 | 細い線の保持 | 画像に黒・白の点ノイズが目立つ時 |
バイラテラルフィルタ | エッジを保持した平滑化 | 計算コストが高い | 輪郭情報を絶対に失いたくない時 |
まとめ
今回は、画像解析の基本となる4つのフィルタリング手法について解説しました。
- ごま塩ノイズにはメディアンフィルタ
- ざらつき(ガウシアンノイズ)にはガウシアンフィルタ
- 輪郭を絶対に残したいならバイラテラルフィルタ
この3つのポイントを覚えておくだけでも、あなたの画像解析の精度は格段に向上するはずです。
次回は、今回クリーンにした画像を使って、いよいよ対象物を抽出する**「二値化」**という処理に進んでいきます。お楽しみに!
コメント