OpenCVの使い方32 ~ ヒストグラム逆投影法2
今回は前回紹介したヒストグラム逆投影法を用いた領域の切り出しの応用例について紹介する。
1. 輝度による切り出し
前回はHSVのうちH(色相), S(彩度)の2次元ヒストグラムを用いて領域切り出しを行ったが、今回はV(輝度)を使って領域を切り出す。
import cv2 import numpy as np from matplotlib import pyplot as plt import cv2 import numpy as np from matplotlib import pyplot as plt orig = cv2.imread(uploaded_file_name) src = cv2.cvtColor(orig, cv2.COLOR_BGR2RGB) plt.imshow(src) plt.title('Original')
以下のように読み込んだテキスト画像でテキストボードの上下にある明るい部分8か所を切り出す。
明るい部分8か所のうち1か所をヒストグラム計算用の領域として切り出す。
hsvt=cv2.cvtColor(orig, cv2.COLOR_BGR2HSV) roi=src[208:212,5:40,:] plt.imshow(roi)
輝度を用いるためcv2.calcHist
ではカラーチャネルは[2]
, ヒストグラムサイズは255
、範囲は[0,256]
として、cv2.calcBackProject
でも同様の設定とする。
以下前回と同じ流れで処理を実行する。
roi=orig[208:212,5:40,:] hsv=cv2.cvtColor(roi, cv2.COLOR_BGR2HSV) roihist=cv2.calcHist([hsv],[2],None,[255],[0,256]) cv2.normalize(roihist,roihist,0,255,cv2.NORM_MINMAX) dst=cv2.calcBackProject([hsvt],[2],roihist,[0,256],1) disc=cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(2,2)) cv2.filter2D(dst,-1,disc,dst) ret,thresh=cv2.threshold(dst,150,255,0) thresh=cv2.merge((thresh,thresh,thresh)) res=cv2.bitwise_and(src,thresh) res3=np.hstack((src,thresh,res)) plt.figure(figsize=(15,8)) plt.imshow(res3)
テキストボード上下の明るい部分の1か所のヒストグラムのみを用いて8か所を切り出せた。(ただし、他の高い輝度部分も若干切り出されている)
輝度による切り出しは、逆投影法を用いなくても閾値処理などでも十分に機能する。
2. 道路の領域切り出し
前回は標準画像を用いたが、今回は一般的な画像として道路の領域切り出しを行う。自動運転などでは、画像から道路、歩道、建物などの領域識別はよく行われている。
まず道路の領域を一部切り出してヒストグラムを計算する。今回は色相、彩度を用いる。
hsvt=cv2.cvtColor(orig, cv2.COLOR_BGR2HSV) roi=src[350:450,200:300,:] plt.imshow(roi)
roi=orig[350:450,200:300,:] hsv=cv2.cvtColor(roi, cv2.COLOR_BGR2HSV) roihist=cv2.calcHist([hsv],[0,1],None,[180,255],[0,180,0,256]) cv2.normalize(roihist,roihist,0,255,cv2.NORM_MINMAX) dst=cv2.calcBackProject([hsvt],[0,1],roihist,[0,180,0,256],1) disc=cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5)) cv2.filter2D(dst,-1,disc,dst) ret,thresh=cv2.threshold(dst,200,255,0) thresh=cv2.merge((thresh,thresh,thresh)) res=cv2.bitwise_and(src,thresh) res3=np.hstack((src,thresh,res)) plt.figure(figsize=(15,8)) plt.imshow(res3)
切り出し時の閾値を下げると、くっきりと道路領域を切り出すことができる。(ただし、他の領域を切り出す可能性がある)
ret,thresh=cv2.threshold(dst,10,255,0) thresh=cv2.merge((thresh,thresh,thresh)) res4=cv2.bitwise_and(src,thresh) plt.figure(figsize=(12,20)) plt.subplot(1,2,1) plt.imshow(res) plt.subplot(1,2,2) plt.imshow(res4)
左側が閾値200、右側が閾値10で右側の方がきれいに切り出せているが、左側で除外できている白線や道路以外の風景の一部も切り出されている。
3. まとめ
今回は輝度を用いたヒストグラム逆投影法の例と、一般的な画像から道路領域を切り出す例を紹介した。