画像認識・物体検出の為の画像前処理
【No.7】実践(opencvを使用) 細かい黒点ノイズ除去
1. 簡単な処理フロー
画像認識や物体検出、文字認識に関して、筆者がおすすめの前処理を3つピックアップし、opencvを使用して実際に処理を行ってみようと思います。
前回は実践1「画像の単純化(物体検出)」を行いました。
今回は実践2「細かい黒点ノイズ除去(文字認識)」を行っていきます。
以下に今回の簡単な処理フローを記載します。
・グレースケール化
・ビット反転処理
・メディアンフィルターでの平滑化処理
2. 細かい黒点ノイズ除去について
おすすめの前処理の2つ目として、文字認識の際のノイズ除去があります。
ノイズ除去といっても多岐に渡ると思いますが、今回は図1の様な「細かい黒点」を除去してみようと思います。
図1の画像は、コピー機でスキャンしたものと想定します。
「結構昔にスキャンしたデータを取りまとめたいが、数が膨大なので、内容を自動解析したい...」みたいなケースを想定しています(筆者が過去扱ったケースをベースにしています)。
「画像内の文字解析をOCR(画像内の文字を認識し、テキストデータとして出力する文字認識機能)する」という処理を想定します。
OCRに関して、もちろん一概には言えませんが、図1の様な細かい黒点によって文字認識の精度が低下しているケースが有ります。画像内に黒点が多く存在する場合要注意です。
処理後は図2のイメージになります。
3. 処理の実装
では、実際に処理を構築していきたいと思います。
今回はPythonのopencvを使用します。opencvについての説明は割愛させていただきます。また、各関数の全ての引数を記載することはしませんのでご了承いただければと思います。
処理フローは以下の様にします。
処理フロー・グレースケール化
・ビット反転処理
・メディアンフィルターでの平滑化処理
一つずつ見ていきます。
グレースケール化
前回の実践1「画像の単純化(物体検出)」に引き続きグレースケール化を行います。画像を軽くする為です。
今回のケースもモノクロ画像で全く問題ないので、本処理を入れます。
import cv2
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ビット反転
ビット反転処理は、デジタル画像の画素値を反転する処理です。
反転とは、例えば画素値が0なら255に、170なら85になります。この処理を施した画像は、モノクロ画像であれば白黒反転、カラー画像であればネガフィルムの様な画像になります。
なぜビット反転をするのかということを説明します。
デジタル画像の画素値は、0から255の値をとりますが、モノクロ画像の場合0が真っ黒、255が真っ白になります。これは黒っぽいものは値が小さく、白っぽいものは値が大きくなるということになります。
ところで、世の中の多くの文字画像(データを含む)というのは、黒い字で描かれていることが多いです。つまり、「文字の部分は黒い=文字の部分は画素値が小さい」となります。
そしてその他の背景は大体白っぽいことが多いです。つまり、「背景の部分は白い=背景の部分は画素値が大きい」となります。
今回のメイン処理は文字認識ですので、文字の部分に注目していきます。その際、注目する部分の値が0に近く、それ以外の関係ない部分の値が大きいというのは、感覚的に分かりずらい気がします。
「注目する部分(文字部分)の値が大きく、それ以外の関係ない部分(背景)の値が0に近い」のほうが感覚的に分かりやすい気がします。
説明が長くなって申し訳ないですが、ビット反転をする理由をまとめると、「感覚的に、やった方が分かりやすいから」ということになります。
「なんだそれ」と思われるかもしれませんが、結構おすすめです。
おすすめの理由は「この後の処理ミスが少なくなるから」です。
この後の演算や処理において、なるべく分かりやすく、ミスを少なくする様に実施するイメージです。
ただし、画像が白黒反転しますので、好き嫌いあると思います。
ビット反転もコード1行でOKです。
import cv2
bwn = cv2.bitwise_not(img)
メディアンフィルターでの平滑化
実際のノイズ除去処理に、メディアンフィルターを使用した平滑化処理を行います。
今回の様なかなりはっきりとした黒点ノイズの場合は、メディアンフィルターがおすすめです。
import cv2
k_size = 3
mblur = cv2.medianBlur(img, k_size)
k_sizeはカーネルサイズです。1以上の奇数を指定します。この値が大きいほど、より「ぼかし」が強くなります。
余談ですが、メディアンフィルターに限らず、平滑化処理のパラメータ設定は、入力画像や目的に応じて手作業で調整が必要となります。
1回1回トライアンドエラーを繰り返します。結構泥臭い作業ですが、大変重要な作業ですので、頑張ります。
今回、例として各k_sizeを設定したフィルター処理をいっぺんに行ってみます。その中で最も効果が出ているもの(=ノイズが除去されており、且つ、エッジもある程度くっきりしているもの)を採用しようと思います。
import cv2
mblur1 = cv2.medianBlur(img, 3)
mblur2 = cv2.medianBlur(img, 5)
mblur3 = cv2.medianBlur(img, 7)
mblur4 = cv2.medianBlur(img, 9)
上記をそれぞれやってみます。
図6〜9をみると、図6(k_size=3)が一番良さげにみえますので、これを採用します。
この様に、基本的に前処理は1回実装して完了とはならないことがほとんどです。
地道な作業ですが、こういった作業が、後工程の精度に関わってきますので、頑張っていきましょう。
以上が、おすすめの2つ目「細かい黒点ノイズ除去」でした。
次回は「画像の水増し処理」を行います。
Link
Search