質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

1662閲覧

画像処理(Python,OpenCV)にて行列→画像の変換が上手くできない(画面が真っ黒になってしまう)

taku0909

総合スコア13

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2018/10/29 11:10

編集2018/10/30 02:52

前提・実現したいこと

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)
ビデオカメラで撮影したサッカーの試合映像

初めて質問させていただきます。

質問の仕方が分かりにくいなど質問中に不備がありましたら教えていただけると幸いです。

加えて

for文による処理には時間が掛かります。他の方法があればぜひ教えて頂きたいです。
###img_labの行列の一部
0の画素が多いですが255も含まれていました

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tiitoi

2018/10/29 11:53

img_lab を print() して0と255がちゃんと含まれていることは確認したのでしょうか?
taku0909

2018/10/29 14:20

質問ありがとうございます。0,255が含まれていることは確認しました。
tiitoi

2018/10/29 14:33

cv2.imshow('pro',img_lab) の直前で確認しましたか?255 の画素がほとんどないため、表示したとき気づかなかったという可能性はないですか?というのもちゃんと値が入っているのに表示だけ全部画素値が0というのは考えづらいからです。
taku0909

2018/10/30 02:45

直前に確認したところ255の画素は含まれておりました。面積を450~600の範囲で設定しているため小さすぎて気が付かないことはないと思います。
taku0909

2018/10/30 03:01

加えて、plt.imshow(img_lab, cmap = 'gray', vmin = 0, vmax = 255, interpolation = 'none')を用いて動画の初めのフレームのみ表示したときはブロブが表示されました。
tiitoi

2018/10/30 03:20 編集

確認ありがとうございます。一つ思い出したのですが、connectedComponents() の返り値 labels は int32 でした。np.uint8 にキャストすると表示できると思います。
guest

回答1

0

ベストアンサー

cv2.connectedComponentsWithStats() の返り値 labels は int32 です。

python

1retval, labels, stats, centroids = cv2.connectedComponentsWithStats(src) 2 3print(labels.shape, labels.dtype) # (362, 420) int32

返り値の labels をそのまま画像として扱う場合は、uint8 にキャストする必要があります。

labels = labels.astype(np.uint8)

これを cv2.imshow('pro',img_lab) の直前に入れてみてはどうでしょうか。

投稿2018/10/30 03:19

tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

taku0909

2018/10/30 05:05

img_lab=img_lab.astype(np.unit8)でできました! データ型が異なっていたから表示されなかったということですね。 理解できました。 ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問