OpenCV メディアンフィルター

Salman Mehmood 2024年2月15日
OpenCV メディアンフィルター

このデモンストレーションでは、メディアンフィルターとは何かを学習し、OpenCV の 2 種類のメディアンフィルターについて説明します。次に、これらのメディアンフィルターを使用して、画像から塩コショウのノイズを除去する方法についても学習します。

OpenCV のメディアンフィルターを使用して、画像からソルトアンドペッパーノイズを除去する

ノイズ除去、特にソルトアンドペッパータイプのノイズに最適なメディアンフィルターを見てみましょう。中央値についての簡単なレッスンに飛び込む前に、平均はすべての数値の平均と人々が使用する典型的な例に他ならないことを私たちは皆知っています。

たとえば、あなたの家が 350 000、425 000 などの範囲にある近所に住んでいます。おそらく、丘の上のどこかに、220 万、320 万の家の価値がある、2、3 人の金持ちの男が住んでいます。等

これらすべての平均を見て、931500 を見て驚いたとします。おそらく、931500 が平均住宅価格だと思うでしょう。そのため、住宅価格の中央値を常に確認します。

これらの値の中央値を見てください。512 500 になり、平均よりもスプレッドが良くなります。これらは、おそらく 5 年生または 6 年生で学んだ統計です。これについて言及する理由は、この画像でそれらを示すためです。

opencv メディアンフィルターの例 1

下の画像は、塩コショウのノイズを多く人工的に加えたもので、暗いピクセルと明るいピクセルがたくさん見られます。ズームインすると、均一に灰色になっているはずのこの領域を見ることができます。

なぜこれらの塩コショウの音が現れるのですか?多くの理由で、塩コショウノイズの主な原因はそこにあります。特に、アナログからデジタルへの変換に問題がある画像をキャプチャするために使用していた古い電子機器にあります。

opencv メディアンフィルターの例 2

ガウスブラーは問題ありませんが、このタイプのノイズをクリーンアップするのは得意ではありません。技術的には、メディアンフィルターの方がうまくいくはずです。よく見ると、明るいピクセルとして表示されるこの 1つのピクセルを除いて、これらはすべてほぼ均一に灰色です。

3x3 カーネルを適用して中央値を見ると、この中央のピクセルを取り巻くすべてのものが見えます。この赤いボックス内のこれらすべての数値の中央値は 140 です。

255 を 140 に置き換えると、非常に均一で均質な画像が得られます。

opencv メディアンフィルターの例 3

これは簡単な絵のグラフィック表現なので、Python コードに飛び込みましょう。まず、skimage.filters から cv2median をインポートして、両方のパッケージで median を使用する方法を示します。

2つの画像をインポートしています。1つは塩コショウ用で、サイズ変更用です。medianBlur() メソッドを使用してイメージを渡し、カーネルサイズを 3 に設定する必要があります。

import cv2
from skimage.filters import median

SP_IMG = cv2.imread("inp.tif", 0)
IMG = cv2.resize(SP_IMG, (720, 600))

IMG = IMG

Opencv_Median = cv2.medianBlur(IMG, 3)

現在、同じ用語を使用しています。skimage は、カーネルを定義し、ディスクと呼ばれるものを使用することを除いて、非常によく似ています。

skimage パッケージから median() メソッドを呼び出して、画像を渡す必要があります。カーネルサイズの代わりに、ディスクサイズを作成しています。

ディスクを印刷すると、ゼロピクセルにゼロが掛けられたマトリックスが作成されます。ディスクが画像の上を移動すると、これらの 1 ピクセルに 1 が掛けられます。

opencv メディアンフィルターの例 4

ここで、mode 引数を渡します。それは何でもありませんが、このカーネルが画像の最後に到達したときに、最後のピクセルをどのように処理しますか?

右側には何もないため、一定の値でいくつかのピクセルが追加されます。

コード例:

from skimage.morphology import disk
import cv2
from skimage.filters import median

SP_IMG = cv2.imread("inp.tif", 0)
IMG = cv2.resize(SP_IMG, (720, 600))

IMG = IMG

Opencv_Median = cv2.medianBlur(IMG, 3)


print(disk(3))

SK_Median = median(IMG, disk(3), mode="constant", cval=0.0)

cv2.imshow("Original", IMG)
cv2.imshow("cv2 median", Opencv_Median)
cv2.imshow("Using skimage median", SK_Median)

cv2.waitKey(0)
cv2.destroyAllWindows()

3つの出力があり、1つはガウスノイズのある元の画像です。

opencv メディアンフィルター出力 1

2 番目の出力は、OpenCV を使用した画像の中央値です。この出力では、結果は元の画像よりも優れています。

opencv メディアンフィルター出力 2

skimage 中央値を使用して次の出力を見ると、バックグラウンドに何もない、非常にきれいに見えます。

opencv メディアンフィルター出力 3

skimage の中央値は、OpenCV の中央値よりもさらに良く見えることがわかります。これは、カーネルサイズがこの中央値に対して少し小さく、元の画像と比較してあまりきれいではないためです。skimage と OpenCV の中央出力画像が同じに見えないのはなぜですか?

skimage 中央値でディスクサイズを定義し、OpenCV 中央値でカーネルサイズを定義します。

カーネルサイズは異なります。したがって、出力はわずかに異なります。同じカーネルサイズを取得した場合、計算は同じになります。

著者: Salman Mehmood
Salman Mehmood avatar Salman Mehmood avatar

Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.

LinkedIn

関連記事 - Python OpenCV