前回に続いてOpening/Closing以外でcv2.morphologyEx()
を用いて処理できるモルフォロジー変換について紹介する。
https://atatat.hatenablog.com//entry/opencv14_morphology2atatat.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として用いる。
2. Gradient, Tophat, Blackhat処理
膨張した画像と収縮した画像の差分をとるGradient処理はcv2.MORPH_GRADIENT
で指定する。輪郭を画像を生成するために用いられる。
kernel = np.ones((5,5),np.uint8) gradient5 = cv2.morphologyEx(src, cv2.MORPH_GRADIENT, kernel) kernel = np.ones((3,3),np.uint8) gradient3 = cv2.morphologyEx(src, cv2.MORPH_GRADIENT, kernel) plt.figure(figsize=(8,5)) plt.subplot(1,3,1) plt.imshow(src) plt.subplot(1,3,2) plt.imshow(gradient5) plt.subplot(1,3,3) plt.imshow(gradient3)
左から元のj文字画像、カーネルサイズ5x5, 3x3の場合の処理結果を示す。カーネルサイズが小さいほど輪郭が細くなることがわかる。
次に元の画像とOpening処理の差を取るトップハット処理はcv2.MORPH_TOPHAT
、逆に元の画像とClosing処理の差を取るブラックハット処理はcv2.MORPH_BLACKHAT
を指定する。
kernel = np.ones((9,9),np.uint8) tophat = cv2.morphologyEx(src, cv2.MORPH_TOPHAT, kernel) blackhat = cv2.morphologyEx(src, cv2.MORPH_BLACKHAT, kernel) plt.figure(figsize=(8,5)) plt.subplot(1,3,1) plt.imshow(src) plt.subplot(1,3,2) plt.imshow(tophat) plt.subplot(1,3,3) plt.imshow(blackhat)
カーネルサイズを9x9として左から元のj文字画像、トップハット処理、ブラックハット処理した画像を示す。
3. カーネル生成
カーネルを生成するためにNumpyのnp.ones()
を利用したが、以下十字型、矩形型、楕円型についてはcv2.getStructuringElement()
を用いて、それぞれcv2.MORPH_CROSS
, cv2.MORPH_RECt
, cv2.MORPH_ELLIPSE
を指定することで生成することができる。
cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5)) >array([[0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [1, 1, 1, 1, 1], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0]], dtype=uint8 cv2.getStructuringElement(cv2.MORPH_RECT,(5,2)) >array([[1, 1, 1, 1, 1], [1, 1, 1, 1, 1]], dtype=uint8) cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5)) >array([[0, 0, 1, 0, 0], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [0, 0, 1, 0, 0]], dtype=uint8)
矩形のようなあるカーネルを用いることで処理に方向性をもたせることができる。例えば5x2の矩形カーネルを用いてGradient処理を行う。
kernel = np.ones((5,5),np.uint8) gradient5 = cv2.morphologyEx(src, cv2.MORPH_GRADIENT, kernel) kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,2)) gradient_rec = cv2.morphologyEx(src, cv2.MORPH_GRADIENT, kernel) plt.figure(figsize=(8,5)) plt.subplot(1,3,1) plt.imshow(src) plt.subplot(1,3,2) plt.imshow(gradient5) plt.subplot(1,3,3) plt.imshow(gradient_rec)
左から元の画像、5x5のカーネル, 5x2の矩形カーネル処理だが、矩形カーネルは縦方向に対してより太い輪郭が描かれていることがわかる。
4. まとめ
今回は、Gradient, Tophat, Blackhat, getStructuringElement()
関数を用いたカーネル生成と効果について消化したい。今回でOpenCVを用いた基本的なモルフォロジー変換について一通り終わった。