OpenCV

[OpenCV] フィルタ処理で画像のノイズを低減する方法

画像からデータを取得して、「」「不良」判定を行ったりAIに識別させたりするときに画像が上手く二値化処理されず精度がなかなか上がらないことがありますよね。

この原因として考えられるものの一つとして、画像上のノイズが考えられます。このノイズを低減することによって、より精度の高い識別が行えるようになるのでフィルタ処理は非常に重要なファクターなのです!

今回は、フィルタ処理を用いて画像のノイズを低減させる方法について解説していきます!

  • 転職のためのスキルアップとして効率的に学びたい
  • 副業としてプログラミングができるようになりたい
  • 独学での勉強に限界を感じている

これらに該当する方はプログラミングスクールがスキルアップの近道です!
是非参考にしてみてください。

【2023年最新】プログラミング上達の近道とは?スクールに通うメリットやおすすめランキングも徹底解説!プログラミングを上達するための近道を紹介しています。また、2023年度に人気の優良プログラミングスクールをランキング形式で紹介しています!特にプログラミングスクールの選び方を難易度、料金、特徴など様々な観点から紹介しています。自分自身の目的に合ったスクール選びの助けとなれば幸いです。...

未経験でも安心!
学生30代の方にもおすすめなプログラミングスクールがあります

画像のノイズとは

画像のノイズとは、画像処理を行う上で不適切に検出されてしまった領域のことを指します。

通常、画像処理を行う際には以下に示すように、前処理として二値化処理を行います。そして、二値化処理された画像の黒あるいは白と検出された領域からデータを取得して画像識別や画像認識などの評価を行います。

filter-processing-image1

このようにしてデータを取得する際には、二値化画像として正確に検出されているほど画像識別や画像判別の精度も上がります。
しかし適切なフィルタ処理を行わないと、以下のように本来検出されてほしくない領域が検出されてしまうことがあります。このとき検出された領域のことをノイズと呼びます。

filter-processing-image2
ノイズの例

ノイズは、画像識別などにおける識別精度の低下を招く恐れがあるため、適切なフィルタ処理を選定し適用する必要があります。

余談
ノイズがどのようなモノか心当たりはあると思います。古い写真や、レンズにゴミが付いていたりすると画像にノイズが乗りやすいですよね、、、

フィルタ処理でノイズを削減する

ブラーフィルタ( Blur filter )

ブラー処理は、画像要素(ピクセル)の平滑化を行うフィルタのことです。以下の図は、カーネルサイズ(処理対象の領域)が3×3とした場合のブラー処理の平滑化手法になります。

処理対象とする画素を、黄色く塗りつぶされた領域とします。この場合、サイズ領域の平均値を計算すると ”” となるので中央の値が “3” に修正されます。

Blur_filter-processing-image1

この処理を画像全体で行う処理をブラー(blur)処理といいます。

Blur処理の効果

画像をぼかすことができるため細かなノイズを削減できる

では実際にプログラムを見てみましょう!
画像にブラー処理を行う場合は、cv2.blur() を用います。

Blur = cv2.blur(image,(a,b))

第一引数
処理対象とする画像を指定

第二引数
平滑化を行うカーネルサイズを指定:カーネルサイズは a × b となる

実際のプログラムを見てみましょう。

import cv2

def main():
    image=cv2.imread("C:\Imagefile\cat-image.jpg")

    blur=cv2.blur(image,(20,20))
    cv2.imshow("Blur filter",blur)

    cv2.waitKey()
    cv2.destroyAllWindows()
if __name__=="__main__":
    main()

(実行結果)

filter-processing-image3

このような結果になります。
対象とするカーネルサイズの領域が大きいほど画像がぼけていることが分かりますね。

メディアンフィルタ( median filter )

メディアンフィルタは、ブラーフィルタと同様に平滑化を行い画像をぼかす処理になります。ブラー処理と異なる部分は、画素の中央値を適用する点です。

処理対象とする画素を黄色く塗りつぶされた領域とします。この場合、サイズ領域の中央値を計算すると ”2” となるので中央の値が “2” に修正されます。

median_filter-processing-image1

では実際にプログラムを見てみましょう!
画像にメディアン処理を行う場合は、cv2.medianBlur() を用います。

Median = cv2.medianBlur(image,size )

第一引数
処理対象とする画像を指定

第二引数
平滑化を行うカーネルサイズを指定。中央値を用いるフィルタリング手法のため必ず奇数である必要があります。

import cv2

def main():
    image=cv2.imread("C:\Imagefile\cat-image.jpg")

    median=cv2.medianBlur(image,9)
    cv2.imshow("median filter",median)

    cv2.waitKey()
    cv2.destroyAllWindows()
if __name__=="__main__":
    main()

(実行結果)

filter-processing-image4

ガウシアンフィルタ( gaussian filter )

ガウシアンフィルタは、ブラーフィルタと同様に平滑化を行い画像をぼかす処理になります。ブラー処理と異なる部分は、単に平均値をとるのではなく、処理対象画素との距離に応じて重みをつけて平滑化を行う点です。

処理対象とする画素を中央の領域とすると、中央に近いほど強い重みを掛け中央から離れる毎に重みが小さくなるようにして、重み付けを行った後で平滑化を行います

gaussian_filter-processing-image1
ガウシアンフィルタの重み付け手法

では実際にプログラムを見てみましょう!
画像にメディアン処理を行う場合は、cv2.GaussianBlur() を用います。

Gaussian = cv2.GaussianBlur(image, ( a, b ), c, d )

第一引数
処理対象とする画像を指定

第二引数
平滑化を行うカーネルサイズを指定:カーネルサイズは a × b となる。(奇数を指定)

第三引数
第三引数は、”SigmaX” (X方向の標準偏差)を指定。

第四引数
第四引数は、”SigmaY” (Y方向の標準偏差)を指定。「0」を指定した場合は、第三引数と同じ値となる。

実際のプログラムを見てみましょう!

import cv2

def main():
    image=cv2.imread("C:\Imagefile\cat-image.jpg")

    gaussina=cv2.GaussianBlur(image,(9,9),10,10)
    cv2.imshow("gaussina filter",gaussina)

    cv2.waitKey()
    cv2.destroyAllWindows()
if __name__=="__main__":
    main()

(実行結果)

filter-processing-image5

おすすめ書籍

オープニング処理( opening processing )

オープニング処理は、二値化後の画像に用いられるノイズ削減手法であり、収縮処理の後で膨張処理をかける処理です。画像上に散らばったノイズや、画像上に写った線などを消す効果があります。

二値化手法は、コチラの記事で解説しています!

膨張処理
処理対象画素に隣接する画素に着目し、1つでも白の領域がある場合には、その画素を白に置き換える処理

収縮処理
処理対象画素に隣接する画素に着目し、1つでも黒の領域がある場合には、その画素を黒に置き換える処理

実際にオープニング処理を用いる場合には、cv2.morphology() を用います。

opening = cv2.morphologyEx ( image, cv2.MORPH_OPEN, ( a, b ))

opening-processing-image1

クロージング処理( closing processing )

クロージング処理は、二値化後の画像に用いられるノイズ削減手法であり、膨張処理の後で収縮処理をかける処理です。画像内の欠損した部分を補うことができます。

二値化手法は、コチラの記事で解説しています!

実際にクロージング処理を用いる場合には、cv2.morphology() を用います。

opening = cv2.morphologyEx ( image, cv2.MORPH_CLOSE, ( a, b ))

opening-processing-image2

まとめ(各フィルタ処理の比較)

各平滑化処理を比較してみると以下のようになります!

プライバシー保護などで画像全体を保護したいときは ”Blur”が良さそうですね。ただ、機械学習に用いるための二値化画像の前処理としてフィルタ処理をかける場合には”Median”もしくは”Gaussian”が良さそうですね!

filter-processing-image6

Blur:画像全体をぼかしたいときに有効

Median:画像のエッジ部をある程度残したままぼかしたい場合に有効

Gaussian:元々の画像に近い形を保ちつつ画像をぼかしたい場合に有効

また、オープニング処理クロージング処理を比較すると以下のようになります。

Opening:散らばったノイズや、線状のノイズを削減する場合に有効

Closing:画像内の欠けた部分を補いたい場合に有効

実際に画像上のノイズを削減したい場合には、STEP1としてフィルタ処理を施して画像を軽くぼかし、STEP2としてあらかじめ平滑化処理を施した画像にオープニング処理あるいはクロージング処理をすることでノイズを効率よく削減することが可能になります

余談ですが、膨張と収縮を活用するとモザイク画像を作成することもできます。コチラの記事で解説していますので参考にしてみて下さい!

参考:[OpenCV] 画像にモザイクをかける方法

以上となります。最後まで見ていただきありがとうございました!