Morphology (モルフォロジー変換)
モルフォロジー変換とは,2値画像に関して,「膨張」や「収縮」などと言った処理を施す操作のことです [1].モルフォロジーには,入力画像と構造的要素(Kernel)の二つを入力として与えます.
本記事では,膨張や収縮がどのように実装されるのか確認してみます.
本記事では,膨張や収縮がどのように実装されるのか確認してみます.
Part1. 膨張処理
膨張処理はその名前の通り,画素を膨張 させる処理のことです.これは,画像に対する「+」の演算と考えてよいでしょう.
例えば,以下のような2値画像があったとします.
図1. Jが書かれた2値画像
この画像に関して,MorphologyのKernel として,右図のようなものを与えてみましょう.
まず,上の行に注目です.Input として,左上のようなものがあったとき,中央のKernel のものを畳み込むと結果的にOutput のような模様が得られます.注目すべきは,Input に青色があれば,その要素に加えて下と右も塗りつぶされる,ということです.これがMorphology変換の膨張の処理です.なお,図は[2]を参考にしました.
図2. Kernel とそのConvolutionの関係
Python による実装
それでは,上の処理をPythonで実装してみましょう.for 文を使うと簡単ですね.
import cv2 import numpy as np import matplotlib.pyplot as plt
ライブラリインポート.py
img = cv2.imread('j.png') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) thresh =100 max_pixel = 255 gray_thresh = cv2.threshold(gray, thresh, max_pixel, cv2.THRESH_BINARY) j_img = gray_thresh[1]
2値化など.py
plt.gray() plt.imshow(j_img)
プロット.py
## Morphology shp = np.shape(j_img) morph_gray = np.zeros(shp) for row in range(shp[0]): for col in range(shp[1]): if j_img[row,col] == 255: morph_gray[row,col]= 255 morph_gray[row,col+1] = 255 morph_gray[row-1,col] = 255
Morphology.py
plt.gray() plt.imshow(morph_gray)
プロット.py
うーむ,なんとも言えないですね.
Morphology 変換の前と後でどのように変わったのか,差分を調べてみましょう.
Morphology 変換の前と後でどのように変わったのか,差分を調べてみましょう.
plt.gray() plt.imshow(morph_gray - j_img)
差分のプロット.py
なるほど!確かに,右と下にピクセルが増えていることがわかりますね.
全方位で膨張処理を行えば,エッジの検出器にもなりそうです.
全方位で膨張処理を行えば,エッジの検出器にもなりそうです.
## Morphology shp = np.shape(j_img) morph_gray2 = np.zeros(shp) for row in range(shp[0]): for col in range(shp[1]): if j_img[row,col] == 255: morph_gray2[row,col]= 255 morph_gray2[row,col+1] = 255 morph_gray2[row-1,col] = 255 morph_gray2[row+1,col]= 255 morph_gray2[row,col-1] = 255
全方位.py
plt.gray() plt.imshow(morph_gray2 - j_img)
プロット.py
これはMorphology Gradient と呼ばれるようですね.
Part2. 収縮処理
次は収縮処理です.膨張処理が分かれば収縮処理はその逆を行えばよいのです. 全方位の収縮をやってみましょう.前のプログラム同様,Kernel Size は (3,3)です.
## Morphology shp = np.shape(j_img) morph_gray_p = np.zeros(shp) for row in range(shp[0]): for col in range(shp[1]): if j_img[row,col] == 255: morph_gray_p[row,col] += 255 morph_gray_p[row,col+1] += 255 morph_gray_p[row-1,col] += 255 morph_gray_p[row+1,col] += 255 morph_gray_p[row,col-1] += 255 ## 収縮処理で消えるものは,近傍に黒がある場合である.近傍に黒がある場合,その和は含 ## まれないため,255*5 とはならない.その部分は排除する. morph_gray3 = 255*(morph_gray_p == 255*5)
収縮処理.py
plt.gray() plt.imshow(morph_gray3)
表示.py
plt.gray() plt.imshow(j_img - morph_gray4)
差分.py
引用文献
[1] モルフォロジー変換 (OpenCV 公式チュートリアル)
http://lang.sist.chukyo-u.ac.jp/classes/OpenCV/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html
[2] モルフォロジー演算による画像からの人物抽出
http://www.kochi-tech.ac.jp/library/ron/2011/g23/M/1145090.pdf
http://lang.sist.chukyo-u.ac.jp/classes/OpenCV/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html
[2] モルフォロジー演算による画像からの人物抽出
http://www.kochi-tech.ac.jp/library/ron/2011/g23/M/1145090.pdf