###前提・実現したいこと
◎やりたいこととしてはは、検出したボールをひとつひとつ区別して、ボール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
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。