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

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

新規登録して質問してみよう
ただいま回答率
85.50%
OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

587閲覧

ラベリング処理を行いたい

退会済みユーザー

退会済みユーザー

総合スコア0

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2017/10/26 02:21

###前提・実現したいこと
こんにちは。
https://youtu.be/CBXrsAJOKhQ
こちらのテニスシーンの映像においてラベリング処理をBackgroundSubtractorMOG
と組み合わせて行い、
面積の大きいもの(選手2名)のみを表示する機能を実装したいと考えております。

https://teratail.com/questions/46863
上記の回答者様のご意見を参考にプログラムを組んでみたのですが、
ウィンドウが真っ暗な画面となってしまいます。(画像1枚のラベリングは可能でした。)

膨大な処理を行う関係上、
映像においてのラベリング処理は不可能なのでしょうか。

よろしくお願いします。

###発生している問題

実行を「CTRL+C」で終了してみると、 毎回この部分の処理に時間がかかっていることがわかりました。 for index in range(len(dst)): if dst[index] == max_index: dst[index] = 255; else: dst[index] = 0;

###該当のソースコード

python

1import numpy as np 2import cv2 3import sys 4 5param = sys.argv 6kernel = np.ones((5, 5), np.uint8) 7 8cap = cv2.VideoCapture('tennis.mp4') 9 10t=0 11 12while(1): 13 ret, frame = cap.read() 14 15 if t==183: ##映像の長さにあわせて終了 16 break 17 18################################################################### 19#ラべリング用に追加 20 src=frame 21 src = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY) 22 height, width = src.shape[:2] 23 24 ret, src = cv2.threshold(src, 105, 255, cv2.THRESH_BINARY) 25 label = cv2.connectedComponentsWithStats(cv2.morphologyEx(src, cv2.MORPH_OPEN, kernel)) 26 27# 2次元ままだと何かと処理しづらいので1次元に落とす 28 dst = label[1].reshape((-1)) 29 30# 背景を除いて1番大きいラベルのみを白にし、その他を黒とする 31 data = np.delete(label[2], 0, 0) 32 max_index = np.argsort(data[:,4])[::-1][0] + 1 33 for index in range(len(dst)): 34 if dst[index] == max_index: 35 dst[index] = 255; 36 else: 37 dst[index] = 0; 38 39# 2次元に戻して画像として出力 40 dst = dst.reshape((height, width)) 41################################################################### 42 43 cv2.imshow('tennis',dst) 44 t = t+1 45 46 k = cv2.waitKey(30) & 0xff 47 if k == 27: 48 break 49 50cap.release() 51cv2.destroyAllWindows()

###補足情報(言語/FW/ツール等のバージョンなど)
ASUS ZenBook™ 3  UX390UA-256G
インテルCore™ i5-7200U プロセッサー 2.5GHz  メモリ8GB
を使用しております。

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

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

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

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

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

guest

回答1

0

ベストアンサー

提示されたコードでは変換後画像データdstをラベル番号が入ったデータlabel[2]から作成していますが、その型はint32です。
一方、元画像データsrcの型はunit8です。
変換後画像データdstsrcから作成するようにすることで正常に描画されると思います。

また、領域数が1個の場合に範囲外参照エラーが発生するため修正が必要でした。
ついでに、面積の大きい上位n個から抽出できるように&抽出候補だった部分を灰色表示してみました。

Python

1import numpy as np 2import cv2 3import sys 4 5kernel = np.ones((5, 5), np.uint8) 6EXTRACT_CNT = 1 # 抽出する領域の個数 7 8cap = cv2.VideoCapture('tennis.mp4') 9t=0 10while(1): 11 ret, frame = cap.read() 12 13 if t==183: ##映像の長さにあわせて終了 14 break 15 16 ################################################################### 17 #ラべリング用に追加 18 src=frame 19 src = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY) 20 height, width = src.shape[:2] 21 22 ret, src = cv2.threshold(src, 105, 255, cv2.THRESH_BINARY) 23 24 label = cv2.connectedComponentsWithStats(cv2.morphologyEx(src, cv2.MORPH_OPEN, kernel)) 25 # [0]=ラベル数,[1]=ラベル付けされた画像,[2]=各ラベルを包括する矩形+面積,[3]=各ラベルの重心 26 27 # 2次元ままだと何かと処理しづらいので1次元に落とす 28 label_idx = label[1].reshape((-1)) # インデックス番号配列 29 dst = src.reshape((-1)) # 画像データ 30 31 # 背景を除いて大きいラベルのみを白にし、その他を黒とする 32 # 領域数=1=背景のみの場合は処理不要 33 if label[0] > 1: 34 data = np.delete(label[2], 0, 0) # 先頭行=背景 が前提の処理 35 36 # 複数の領域を抽出できるように 37 #max_index = np.argsort(data[:,4])[::-1][0] + 1 38 extract_idx = set( np.argsort(data[:,4])[::-1][0:EXTRACT_CNT] + 1) 39 #print('extract_idx:',extract_idx) 40 41 for index in range(len(dst)): 42 if label_idx[index] in extract_idx: 43 dst[index] = 255; # 抽出部分 44 elif label_idx[index] == 0: 45 dst[index] = 0; # 背景 46 else: 47 dst[index] = 64; # 抽出候補だった部分 48 49 # 2次元に戻して画像として出力 50 dst = dst.reshape((height, width)) 51 ################################################################### 52 53 cv2.imshow('tennis',dst) 54 t = t+1 55 56 k = cv2.waitKey(30) & 0xff 57 if k == 27: 58 break 59 60cap.release() 61cv2.destroyAllWindows()

投稿2017/10/26 06:53

編集2017/10/26 07:04
can110

総合スコア38234

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

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

退会済みユーザー

退会済みユーザー

2017/10/26 13:41

ご回答ありがとうございます。 非常に丁寧な説明に加え、さらに質の高い機能まで実装していただき本当に感謝しております。 また機会がありましたら、よろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問