つれづれなる備忘録

日々の発見をあるがままに綴る

OpenCVの使い方14 ~ モルフォロジー変換2

 前回に続いてOpenCVを用いたモルフォロジー変換を適用する方法について紹介する。

atatat.hatenablog.com

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"
文字j

文字jの画像に白点ノイズを加える処理をする。方法はいろいろあるが、まずRGB画像srccv2.cvtColor()を用いてグレー画像grayに変換する。ノイズ生成はnp.random.randint(0,100,np.shape(gray))として0~100の間の乱数行列noise (grayと同じ要素数)を生成してthを越える場合は255、th以下は0を割り当てる。このnoisegrayを加えて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文字画像"
白ノイズj文字画像

次に文字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を生成することができた。

"黒ノイズj文字画像"
黒ノイズj文字画像

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と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処理"
黒ノイズ画像のOpeningとClosing処理

以上のようにOpening処理、Closing処理は2値化画像のノイズ処理として有用だが、白ノイズ、黒ノイズとOpening, Closing処理を適切に選択する必要がある。

3. まとめ

 今回は収縮・膨張処理を連続で実行するOpening, Closing処理について紹介した。次回はOpening/Closing以外でcv2.morphologyEx()を用いて処理できるモルフォロジー変換について紹介する。