前提・実現したいこと
Pythonを用いてOpenCVで画像処理をしております。
画像処理では動画を扱っており、行列操作によって画像に変更を加えています。
今回は入力画像を二値化し、ラベリングし、
ラベリングから得られたブロブのdata(左上座標、幅、高さ、面積)を用いて面積が450~600のブロブのみを抽出しようとしております。
ラベリングから得られる「ラベル番号が入った配列データ」行列上で、
ブロブが存在している画素に対し、ブロブの面積が範囲外の場合画素値を0に、範囲内の場合255に変更を加え、出力画像を作成しています。
発生している問題・エラーメッセージ
出力画像として作成したimg_labをimshowで表示しようとするとエラーは発生しないが、画面が真っ黒になってしまう。
該当のソースコード
Python
1# -*- coding: utf-8 -*- 2import cv2 3import math 4import numpy as np 5import sys 6 7 8 9#グレースケール化 10def gray(img): 11 img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 12 return img 13 14#二値化 15def binarization(img): 16 thresh=200#閾値の設定 17 ret,img=cv2.threshold(img,thresh,255,cv2.THRESH_BINARY)#二値化 18 return img 19 20#膨張 21def dilate(img): 22 op=np.array([[1,1,1],[1,1,1],[1,1,1]],np.uint8) 23 img=cv2.dilate(img,op,iterations=1) 24 return img 25 26#ラベリング 27def labeling(mask): 28 #出力(総ラベル数、ラベル番号が入った配列データ、ブロブの画像データ[x,y,w,h,size]、ブロブ中心点) 29 label = cv2.connectedComponentsWithStats(mask) 30 data = np.delete(label[2], 0, 0) # ブロブのデータ(0行目消去) 31 center = np.delete(label[3], 0, 0) # ブロブの中心座標(0行目消去) 32 return data,center,label 33 34 35 36def main(): 37 cv2.namedWindow('pro',cv2.WINDOW_NORMAL) 38 cap = cv2.VideoCapture('c:\2019year\pythonfile\particle_filter\game1.mts') 39 while True: 40 ret, img_src = cap.read() 41 42 #ここに核となる処理を記述 43 img_gray=gray(img_src)#グレースケール化 44 img_bin=binarization(img_gray)#二値化 45 img_bin=dilate(img_bin)#膨張 46 img_bin=dilate(img_bin)#膨張 47 img_bin=dilate(img_bin)#膨張 48 data,center,label=labeling(img_bin)#ラベリング 49 50 #img_labで面積制限結果を表示 51 img_lab=label[1] 52 for i in range(0,label[0]-1): 53 #面積450~600の時ブロブを表示(255)、そうでない時(0) 54 if ((450<=data[i,4])&(data[i,4]<=600)): 55 img_lab=np.where(img_lab==i+1,255,img_lab)#label[1]中のiへ255代入 56 else: 57 img_lab=np.where(img_lab==i+1,0,img_lab)#label[1]中のiへ0代入 58 59 #出力 60 cv2.imshow('pro',img_lab) 61 62 ch=cv2.waitKey(1)#キー入力待ち 63 if ch ==ord('q'): 64 break 65 cap.release() 66 cv2.destroyAllWindows() 67 68if __name__ == "__main__": 69 main()
試したこと
imshowにて表示を試みているimg_labは二値画像であり行列表示をすると画素値が0だけではなく,255も含まれている。
表示画面サイズの変更などしたが真っ黒のままだった。
補足情報(FW/ツールのバージョンなど)
実行環境:
OpenCV3.2.0
Anaconda3-4.2.0
入力動画:
AVCHD ビデオ (.MTS)
ビデオカメラで撮影したサッカーの試合映像
初めて質問させていただきます。
質問の仕方が分かりにくいなど質問中に不備がありましたら教えていただけると幸いです。
加えて
img_lab を print() して0と255がちゃんと含まれていることは確認したのでしょうか?
質問ありがとうございます。0,255が含まれていることは確認しました。
cv2.imshow('pro',img_lab) の直前で確認しましたか?255 の画素がほとんどないため、表示したとき気づかなかったという可能性はないですか?というのもちゃんと値が入っているのに表示だけ全部画素値が0というのは考えづらいからです。
直前に確認したところ255の画素は含まれておりました。面積を450~600の範囲で設定しているため小さすぎて気が付かないことはないと思います。
加えて、plt.imshow(img_lab, cmap = 'gray', vmin = 0, vmax = 255, interpolation = 'none')を用いて動画の初めのフレームのみ表示したときはブロブが表示されました。
確認ありがとうございます。一つ思い出したのですが、connectedComponents() の返り値 labels は int32 でした。np.uint8 にキャストすると表示できると思います。
回答1件
あなたの回答
tips
プレビュー