python - 如何在增加值后停止循环 x 秒
问题描述
我正在做一个足球游戏分析项目。项目目标包括跟踪球,检测和增加双方的目标。我使用颜色跟踪来跟踪球。我还尝试制作一种算法来检测球是否通过了特定的线或矩形(目标区域)并增加计数器。但它有时会增加多个目标。不知何故,只有目标检测代码应该在目标增加后停止执行 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
我也对任何其他可以满足我项目目标的技术/算法持开放态度。
解决方案
停止运行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
推荐阅读
- visual-studio-code - 如何在 VSCode 中更改编辑器缩进的颜色
- node.js - 在 Heroku 上上传图像的替代方法
- typescript - 将 Gatsby 与 Typescript 一起使用时,Markdown 图像仍然模糊,我做错了什么?
- salt-stack - 渲染 SLS 'base:test.test1' 失败:Jinja 变量 'list object' 没有属性 'sub1'
- powershell - 使用 powershell 脚本自动登录 SAP GUI
- amazon-web-services - 如何使用 AWS WAF 阻止“user-agent”标头不是“Java/1.8”的请求?
- android-studio - Android UI 故障问题
- database - 我们可以在同一个模式中有两个 Postgres 数据库吗?
- c++ - 背景图像与主菜单项重叠
- python - 如何以 .log 扩展名组合来自 zip 文件的数据并将它们组合起来