前回に続いてOpenCVを用いたモルフォロジー変換を適用する方法について紹介する。
1. ノイズ画像の生成
Google Colabでのサンプル画像読み込み
import cv2 import numpy as np from matplotlib import pyplot as plt from google.colab import files uploaded_file = files.upload() uploaded_file_name = next(iter(uploaded_file)) orig = cv2.imread(uploaded_file_name) src = cv2.cvtColor(orig, cv2.COLOR_BGR2RGB) plt.imshow(src)
以下文字jをテスト画像srcとして用いる。

文字jの画像に白点ノイズを加える処理をする。方法はいろいろあるが、まずRGB画像srcをcv2.cvtColor()を用いてグレー画像grayに変換する。ノイズ生成はnp.random.randint(0,100,np.shape(gray))として0~100の間の乱数行列noise (grayと同じ要素数)を生成してthを越える場合は255、th以下は0を割り当てる。このnoiseとgrayを加えて255を越える要素に対して255を割り当てることで、文字j上はそのままで、背景の部分に白ノイズを加えることができる。なおthの値を小さくすると白ノイズの量が増える。
gray = cv2.cvtColor(src, cv2.COLOR_RGB2GRAY) th=96 noise=np.random.randint(0,100,np.shape(gray)) noise[noise>th]=255 noise[noise<=th]=0 grnoi=gray+noise grnoi[grnoi>255]=255 gray2=grnoi.astype(np.uint8) src2 = cv2.cvtColor(gray2, cv2.COLOR_GRAY2RGB) plt.imshow(src2)
以下のように文字jの黒背景に白点ノイズを加えた画像src2を生成することができた。

次に文字jの内部に黒点ノイズを加える処理をする。白ノイズとほぼ同じ手順になるが、今回は255以外の数値に0を割り当てる。
th=95 noise=np.random.randint(0,100,np.shape(gray)) noise[noise>th]=245 noise[noise<=th]=0 grnoi=gray+noise grnoi[grnoi>255]=0 grnoi[grnoi<255]=0 gray3=grnoi.astype(np.uint8) src3 = cv2.cvtColor(gray3, cv2.COLOR_GRAY2RGB) plt.imshow(src3)
j文字中に黒点ノイズを加えた画像src3を生成することができた。

2. OpeningとClosing処理
Opening処理は前回紹介した収縮処理と膨張処理を連続で行う処理で、収縮処理により白ノイズを潰して、膨張処理で文字の幅を元に戻すことで、白ノイズ除去ができる。またClosing処理は膨張処理と収縮処理を連続で行うため、膨張処理により黒ノイズを潰して、収縮処理で文字幅を元に戻すため黒ノイズ除去ができる。これらの変換を行うにはcv2.morphologyEx()を用いて、モルフォロジー変換の種類を指定する。Opening処理の場合はcv2.morphologyEx(src, cv2.MORPH_OPEN, kernel)でClosing処理はcv2.morphologyEx(src, cv2.MORPH_CLOSE, kernel)とする。kernelは5x5として白ノイズ画像に対してOpeningとClosing処理をした画像を比較する。
kernel = np.ones((5,5),np.uint8) opening = cv2.morphologyEx(src2, cv2.MORPH_OPEN, kernel) closing = cv2.morphologyEx(src2, cv2.MORPH_CLOSE, kernel) plt.figure(figsize=(8,5)) plt.subplot(1,3,1) plt.imshow(src2) plt.subplot(1,3,2) plt.imshow(opening) plt.subplot(1,3,3) plt.imshow(closing)
左から元の白ノイズ画像、Opening処理、Closing処理で、Opening処理により白ノイズは綺麗に消えているが、Closing処理ではノイズが増えている。

今度は逆に黒ノイズ画像に対してOpening, Closing処理をする。
opening = cv2.morphologyEx(src3, cv2.MORPH_OPEN, kernel) closing = cv2.morphologyEx(src3, cv2.MORPH_CLOSE, kernel) plt.figure(figsize=(8,5)) plt.subplot(1,3,1) plt.imshow(src3) plt.subplot(1,3,2) plt.imshow(opening) plt.subplot(1,3,3) plt.imshow(closing)
左から元の黒ノイズ画像、Opening処理、Closing処理で、Closing処理では黒ノイズが消えて、Opening処理ではノイズが増える逆の結果が得られた。

以上のようにOpening処理、Closing処理は2値化画像のノイズ処理として有用だが、白ノイズ、黒ノイズとOpening, Closing処理を適切に選択する必要がある。
3. まとめ
今回は収縮・膨張処理を連続で実行するOpening, Closing処理について紹介した。次回はOpening/Closing以外でcv2.morphologyEx()を用いて処理できるモルフォロジー変換について紹介する。