我正在做一个桌上足球游戏分析项目。项目目标包括跟踪球,检测和增加双方目标。我使用颜色跟踪来跟踪球。我还尝试制定一种算法来检测球是否通过特定的线或矩形(目标区域)并增加计数器。但这有时会增加多个目标。以某种方式,在增加目标后,只有目标检测代码应停止执行3秒钟。我是或其他使代码正常工作的东西。我尝试使用break / continue / time.sleep(s),但无法弄清楚该怎么做。如果有人可以看一下我的代码并告诉我哪里出了问题。
from collections import deque
from imutils.video import VideoStream
import numpy as np
import argparse
import cv2
import imutils
import time
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video",
help="path to the (optional) video file")
ap.add_argument("-b", "--buffer", type=int, default=64,
help="max buffer size")
args = vars(ap.parse_args())
match_score = (0, 0)
greenLower = (36, 25, 25)
greenUpper = (70, 255,255)
pts = deque(maxlen=args["buffer"])
counter = 0
x=0
y=0
if not args.get("video", False):
vs = VideoStream(src=1).start()
else:
vs = cv2.VideoCapture(args["video"])
time.sleep(2.0)
while True:
frame = vs.read()
frame = frame[1] if args.get("video", False) else frame
if frame is None:
break
frame = imutils.resize(frame, width=640, height=480)
blurred = cv2.GaussianBlur(frame, (11, 11), 0)
hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, greenLower, greenUpper)
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
center = None
cv2.rectangle(frame,(0,0),(640,360),(0,255,255),7)
cv2.rectangle(frame,(8,135),(14,225),(255,0,0),2)
cv2.rectangle(frame,(623,140),(630,230),(255,0,0),2)
if len(cnts) > 0:
c = max(cnts, key=cv2.contourArea)
((x, y), radius) = cv2.minEnclosingCircle(c)
M = cv2.moments(c)
center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))
if radius > 5:
cv2.circle(frame, (int(x), int(y)), int(radius),
(0, 255, 255), 2)
cv2.circle(frame, center, 5, (0, 0, 255), -1)
pts.appendleft(center)
for i in range(1, len(pts)):
if pts[i - 1] is None or pts[i] is None:
continue
thickness = int(np.sqrt(args["buffer"] / float(i + 1)) * 2.5)
cv2.line(frame, pts[i - 1], pts[i], (0, 0, 255), thickness)
for i in range(1, len(pts)):
if pts[i - 1] == pts[i] :
if (8 < x < 14 and 135 < y < 225) :
match_score = (match_score[0] + 1, match_score[1])
break
if (623 < x < 630 and 140 < y < 230) :
match_score = (match_score[0], match_score[1] + 1)
break
cv2.putText(frame, "dx: {}, dy: {}".format(dX, dY),
(10, frame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX,
0.5, (0, 0, 255), 1)
cv2.putText(frame, str(x) + " , " + str(y),
(10, frame.shape[0] - 20), cv2.FONT_HERSHEY_SIMPLEX,
0.5, (0, 0, 255), 1)
cv2.putText(frame, str(match_score[0]) + " - " + str(match_score[1]), (260, 60),
cv2.FONT_HERSHEY_SIMPLEX, 1, (120, 255, 50), 2)
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
counter += 1
if key == ord("q"):
break
if not args.get("video", False):
vs.stop()
else:
vs.release()
cv2.destroyAllWindows()
在这里进行测试和工作是我们桌上足球表的一些视频片段。 该剪辑包含正确检测到的右侧目标 https://drive.google.com/open?id=1Y7Dzzfx_V0fsDZRZAC4d0MuEpSnKnodI
这是一个有多个目标的剪辑,如果这段视频中的代码运行良好,那么我很适合实时播放。 https://drive.google.com/open?id=1vtUjw2jpDHvAvo4jI_W1UpJWPT1jYWGr
我也愿意接受任何其他可以满足我的项目目标的技术/算法。
答案 0 :(得分:1)
停止运行x
秒对实时视频流有效,但不适用于预先录制的视频。在后者中,您可能要根据帧数来替换固定时间,具体取决于帧速率。
也就是说,您可以像这样实现时间标记last_goal_time
:
from datetime import datetime, timedelta
# initialization at beginning of code
last_goal_time = datetime.now()
# inside the while loop
while True:
current_time = datetime.now()
# check for time difference, if less than 3 seconds, continue
# you may want to grab the frame before this
if (current_time - last_goal_time).total_seconds() < 3:
continue
# 3 seconds passed
frame = vs.read()
### other code goes here
# here I guess when goal detected
for i in range(1, len(pts)):
if pts[i - 1] == pts[i] :
# update last_goal_time
last_goal_time = current_time
# rest of code is unchanged
if (8 < x < 14 and 135 < y < 225) :
match_score = (match_score[0] + 1, match_score[1])
break
if (623 < x < 630 and 140 < y < 230) :
match_score = (match_score[0], match_score[1] + 1)
break