文章の書き直し
- 本文
実行させた結果が以下の写真となります。  -円を画面から外すと数字の羅列があり、その後また初期状態に戻るようです。原因を探ろうとしたのですが、プログラムを始めて間もないこともあり、突き止めることが出来ませんでした。上記のような症状が出る原因として何が考えられるか教えていただきたいです。 +円を画面から外すと数字の羅列があり、その後また初期状態に戻るようです。原因を探ろうとしたのですが、プログラミングを始めて間もないこともあり、突き止めることが出来ませんでした。上記のような症状が出る原因として何が考えられるか教えていただきたいです。
python-OpenCVによるハフ変換と時間計測について
現在、webカメラによりリアルタイムでハフ変換を行い円を検出、座標により円を区別しそれぞれの円の出現時間を計測するプログラムを作成しています。以下がプログラムコードです。
from datetime import datetime
import math
import numpy as np
import cv2
FIND_DIST = 30
targets = []
id = 1
cap = cv2.VideoCapture(1)
while True:
pts = []
now_time = datetime.now()
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (33,33), 1)
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 60, param1=10, param2=85, minRadius=10, maxRadius=80)
if circles is not None:
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
cv2.circle(frame,(i[0],i[1]),i[2],(255,255,0),2)
cv2.circle(frame,(i[0],i[1]),2,(0,0,255),3)
pt = (i[0],i[1])
pts.append((float(pt[0]), float(pt[1])))
for tgt in targets:
tgt['bIn'] = False
new_tgts = []
for pt in pts:
bIn = False
for tgt in targets:
if math.sqrt( math.pow(pt[0] - tgt['pos'][0], 2) + math.pow(pt[1] - tgt['pos'][1], 2)) <= FIND_DIST:
tgt['bIn'] = True
tgt['pos'] = pt
bIn = True #次フレームでも円が見つかった場合、そのをIDをTrueに変更
if not bIn: #発見された円の座標をlistに追加、状態をTrueにする
new_tgt = {'id':id,'bIn':True,'pos':pt,'in_time':now_time}
new_tgts.append(new_tgt)
id += 1
for tgt in targets:
if tgt['bIn']: #リスト内のTrueのIDをnew_tgtsに加えていく
new_tgts.append(tgt)
else: #リスト内にFalseのIDがあった場合円が消えたと認識、時間を出力
print('{}sec'.format((now_time - tgt['in_time']).total_seconds()))
targets = new_tgts
cv2.imshow('preview', frame)
key = cv2.waitKey(10)
if key == ord("q"):
break
cv2.destroyAllWindows()
コード
上記のプログラムを実際に動かした結果、円を3枚映し続けていても認識出来ず、消えたと判断されてしまうようことが多々ありました。
そこで、
現フレームで見つからなかった残留点について、bInを0からデクリメントしていく。
↓
途中でまた見つかった場合は失踪時間を0に初期化更新して残留リストにも残しておく。
↓
そして(失踪から)5フレームたったら離脱と認定し、残留リストから外す。
というプログラムに書き換えようと考えました。
自分なりに改良したものが以下のコードです。
from datetime import datetime
import math
import numpy as np
import cv2
FIND_DIST = 30
targets = []
id = 1
cap = cv2.VideoCapture(1)
while True:
pts = []
now_time = datetime.now()
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (33,33), 1)
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 60, param1=10, param2=85, minRadius=10, maxRadius=80)
if circles is not None:
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
cv2.circle(frame,(i[0],i[1]),i[2],(255,255,0),2)
cv2.circle(frame,(i[0],i[1]),2,(0,0,255),3)
pt = (i[0],i[1])
pts.append((float(pt[0]), float(pt[1])))
print(pts)
new_tgts = []
for pt in pts:
bIn = 0
print("D")
if not bIn:
new_tgt = {'id':id,'bIn':1,'pos':pt,'in_time':now_time}
new_tgts.append(new_tgt)
id += 1
print("a")
for tgt in targets:
if math.sqrt( math.pow(pt[0] - tgt['pos'][0], 2) + math.pow(pt[1] - tgt['pos'][1], 2)) <= FIND_DIST:
tgt['bIn'] = 1
tgt['pos'] = pt
bIn = 1
print("b")
for tgt in targets:
if tgt['bIn'] > -5 :
new_tgts.append(tgt)
print("c")
elif tgt['bIn'] == -5:
print('{}sec'.format((now_time - tgt['in_time']).total_seconds()))
new_tgts = [tgt for tgt in targets if tgt['bIn'] == 1]
targets = new_tgts
for tgt in targets:
if tgt['bIn'] == 1:
tgt['bIn'] = 0
else:
tgt['bIn'] -= 1
cv2.imshow('preview', frame)
key = cv2.waitKey(10)
if key == ord("q"):
break
cv2.destroyAllWindows()
コード
やりたかったこととしては、円が消えたと判断されたときbInをデクリメント。もし、bInが-5となったら離脱とみなし時間を表示、さらにリスト内のbIn=-5となっている要素を消去するというものです。
実行させた結果が以下の写真となります。
円を画面から外すと数字の羅列があり、その後また初期状態に戻るようです。原因を探ろうとしたのですが、プログラミングを始めて間もないこともあり、突き止めることが出来ませんでした。上記のような症状が出る原因として何が考えられるか教えていただきたいです。
現在、webカメラによりリアルタイムでハフ変換を行い円を検出、座標により円を区別しそれぞれの円の出現時間を計測するプログラムを作成しています。以下がプログラムコードです。 ``` from datetime import datetime import math import numpy as np import cv2 FIND_DIST = 30 targets = [] id = 1 cap = cv2.VideoCapture(1) while True: pts = [] now_time = datetime.now() ret, frame = cap.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) gray = cv2.GaussianBlur(gray, (33,33), 1) circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 60, param1=10, param2=85, minRadius=10, maxRadius=80) if circles is not None: circles = np.uint16(np.around(circles)) for i in circles[0,:]: cv2.circle(frame,(i[0],i[1]),i[2],(255,255,0),2) cv2.circle(frame,(i[0],i[1]),2,(0,0,255),3) pt = (i[0],i[1]) pts.append((float(pt[0]), float(pt[1]))) for tgt in targets: tgt['bIn'] = False new_tgts = [] for pt in pts: bIn = False for tgt in targets: if math.sqrt( math.pow(pt[0] - tgt['pos'][0], 2) + math.pow(pt[1] - tgt['pos'][1], 2)) <= FIND_DIST: tgt['bIn'] = True tgt['pos'] = pt bIn = True #次フレームでも円が見つかった場合、そのをIDをTrueに変更 if not bIn: #発見された円の座標をlistに追加、状態をTrueにする new_tgt = {'id':id,'bIn':True,'pos':pt,'in_time':now_time} new_tgts.append(new_tgt) id += 1 for tgt in targets: if tgt['bIn']: #リスト内のTrueのIDをnew_tgtsに加えていく new_tgts.append(tgt) else: #リスト内にFalseのIDがあった場合円が消えたと認識、時間を出力 print('{}sec'.format((now_time - tgt['in_time']).total_seconds())) targets = new_tgts cv2.imshow('preview', frame) key = cv2.waitKey(10) if key == ord("q"): break cv2.destroyAllWindows() コード ``` 上記のプログラムを実際に動かした結果、円を3枚映し続けていても認識出来ず、消えたと判断されてしまうようことが多々ありました。 そこで、 現フレームで見つからなかった残留点について、bInを0からデクリメントしていく。 ↓ 途中でまた見つかった場合は失踪時間を0に初期化更新して残留リストにも残しておく。 ↓ そして(失踪から)5フレームたったら離脱と認定し、残留リストから外す。 というプログラムに書き換えようと考えました。 自分なりに改良したものが以下のコードです。 ``` from datetime import datetime import math import numpy as np import cv2 FIND_DIST = 30 targets = [] id = 1 cap = cv2.VideoCapture(1) while True: pts = [] now_time = datetime.now() ret, frame = cap.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) gray = cv2.GaussianBlur(gray, (33,33), 1) circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 60, param1=10, param2=85, minRadius=10, maxRadius=80) if circles is not None: circles = np.uint16(np.around(circles)) for i in circles[0,:]: cv2.circle(frame,(i[0],i[1]),i[2],(255,255,0),2) cv2.circle(frame,(i[0],i[1]),2,(0,0,255),3) pt = (i[0],i[1]) pts.append((float(pt[0]), float(pt[1]))) print(pts) new_tgts = [] for pt in pts: bIn = 0 print("D") if not bIn: new_tgt = {'id':id,'bIn':1,'pos':pt,'in_time':now_time} new_tgts.append(new_tgt) id += 1 print("a") for tgt in targets: if math.sqrt( math.pow(pt[0] - tgt['pos'][0], 2) + math.pow(pt[1] - tgt['pos'][1], 2)) <= FIND_DIST: tgt['bIn'] = 1 tgt['pos'] = pt bIn = 1 print("b") for tgt in targets: if tgt['bIn'] > -5 : new_tgts.append(tgt) print("c") elif tgt['bIn'] == -5: print('{}sec'.format((now_time - tgt['in_time']).total_seconds())) new_tgts = [tgt for tgt in targets if tgt['bIn'] == 1] targets = new_tgts for tgt in targets: if tgt['bIn'] == 1: tgt['bIn'] = 0 else: tgt['bIn'] -= 1 cv2.imshow('preview', frame) key = cv2.waitKey(10) if key == ord("q"): break cv2.destroyAllWindows() コード ``` やりたかったこととしては、円が消えたと判断されたときbInをデクリメント。もし、bInが-5となったら離脱とみなし時間を表示、さらにリスト内のbIn=-5となっている要素を消去するというものです。 実行させた結果が以下の写真となります。  円を画面から外すと数字の羅列があり、その後また初期状態に戻るようです。原因を探ろうとしたのですが、プログラミングを始めて間もないこともあり、突き止めることが出来ませんでした。上記のような症状が出る原因として何が考えられるか教えていただきたいです。