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

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

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

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

Python 3.x

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

Q&A

1回答

2642閲覧

同色のボールの区別ができません!

退会済みユーザー

退会済みユーザー

総合スコア0

OpenCV

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

Python 3.x

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

0グッド

2クリップ

投稿2018/01/18 12:35

###前提・実現したいこと
◎やりたいこととしてはは、検出したボールをひとつひとつ区別して、ボール1・ボール2・ボール3でそれぞれ違う色の円で囲いたいです。
例えば、ボール1なら赤色の円でずっと追いかけ、ボール2なら青色の――といった感じです。

サンプルを組み合わせただけなのでかなり雑ですが、トラックバーで決めた範囲の色のボールを、円で囲って追いかけるというプログラムです。
今私が使用している動画は、緑色のボールを3つ使ってカスケードをしている動画で、トラックバーの初期値はおおよそ緑色を検出する数値になっています。

調べてみたところ、ユークリッド距離というものを利用するらしいことは分かったのですが、式などが難しく、調べれば調べるほど分からなくなってきてしまいました。
サンプルなどを見てみてはいるのですが、どれをどうやって組み込めばいいのかがわかりません。
どうかよろしくお願いします。

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

import cv2 import numpy as np import math def colorLow(position): global col_l col_l = position def colorUp(position): global col_u col_u = position def saturationLow(position): global sat_l sat_l = position def saturationUp(position): global sat_u sat_u = position def valueLow(position): global val_l val_l = position def valueUp(position): global val_u val_u = position def extract_hsv(frame,col_l,col_u,sat_l,sat_u,val_l,val_u): hsv=cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) h,s,v=cv2.split(hsv) if col_l>col_u: ret,h_mask_1=cv2.threshold(h,col_l,255,cv2.THRESH_BINARY) ret,h_mask_2=cv2.threshold(h,col_u,255,cv2.THRESH_BINARY_INV) mask=cv2.bitwise_or(h_mask_1,h_mask_2) else: ret,mask=cv2.threshold(h,col_l,255,cv2.THRESH_TOZERO) ret,mask=cv2.threshold(mask,col_u,255,cv2.THRESH_TOZERO_INV) ret,mask=cv2.threshold(mask,0,255,cv2.THRESH_BINARY) ret,sat_mask=cv2.threshold(s,sat_l,255,cv2.THRESH_BINARY) ret,val_mask=cv2.threshold(v,val_l,255,cv2.THRESH_BINARY) mask=cv2.bitwise_and(mask,sat_mask) mask=cv2.bitwise_and(mask,val_mask) return mask if __name__=="__main__": col_l=30 col_u=97 sat_l= 120 sat_u= 255 val_l= 80 val_u= 255 cap = cv2.VideoCapture("動画の名前") cv2.namedWindow("colorselect",cv2.WINDOW_NORMAL) cv2.createTrackbar('color(low)', "colorselect", col_l, 255, colorLow) cv2.createTrackbar('Color(up)', "colorselect", col_u, 255, colorUp) cv2.createTrackbar('Saturation(low)',"colorselect", sat_l, 255, saturationLow) cv2.createTrackbar('Saturation(up)', "colorselect", sat_u, 255, saturationUp) cv2.createTrackbar('Value(low)', "colorselect", val_l, 255, valueLow) cv2.createTrackbar('Value(up)',"colorselect", val_u, 255, valueUp) while(1): # フレームを取得 (grabbed,frame) = cap.read() if not grabbed: cap.set(cv2.CAP_PROP_POS_FRAMES,0) continue # フレームをHSVに変換 hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) mask=extract_hsv(frame,col_l,col_u,sat_l,sat_u,val_l,val_u) mask=cv2.erode(mask, None, iterations=2) mask=cv2.dilate(mask, None, iterations=2) # フレーム画像とマスク画像の共通の領域を抽出する。 img_color = cv2.bitwise_and(frame, frame, mask=mask) cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2] center = None cnts3 = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2] center = None # 少なくとも1つの輪郭が見つかった場合 if len(cnts) > 0: for i, contour in enumerate(cnts): #print("{}, {}".format(i, len(contour))) # area:面積 area = cv2.contourArea(contour) if area < 100: continue # moments:重心 M = cv2.moments(contour) if M["m00"] != 0: cx = int(M["m10"] / M["m00"]) cy = int(M["m01"] / M["m00"]) else: cx, cy = 0, 0 # 重心を中心にした円 cv2.circle(frame, (cx, cy), int(math.sqrt(area)), (0,255,0), 2, 8) # pts1.appendleft(center) cv2.imshow("SHOW COLOR IMAGE", img_color) cv2.imshow("SHOW FRAME", frame) # qを押したら終了 k = cv2.waitKey(50) if k == ord('q'): break cap.release() cv2.destroyAllWindows()

###補足情報(言語/FW/ツール等のバージョンなど)
windows7/Anaconda3.4.4/Spyder3(Python3.5)/OpenCV 3.1.0

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

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

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

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

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

guest

回答1

0

https://www.google.co.jp/amp/s/bipuljain.wordpress.com/2011/12/20/multiple-color-tracking-using-opencv-python/amp/
普通は認識しやすくするために色違いのボールを使います。

そうでないのなら運動方程式を解いて、物理法則に反していないようにラベル付けする必要があるのではないでしょうか?
囲んでいる円の中心を質点として高校物理をノイズありで解くのです。
検出精度が悪いと誤差が出ます。
フレームレートが安定しないと誤差が出ます。
それ許容した範疇で区別します。
ボール同士が近付いたりすると区別がつかなくなります。

どれほど真剣なプロジェクトかはわかりませんが、カルマンフィルタで調べてみるとそれなりに実用的なものができるのではないでしょうか。
これなら奥行き方向の重なりは処理できるかもしれません。
ボール同士が衝突した場合は無理です。

投稿2018/01/19 05:15

mkgrei

総合スコア8560

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問