基于MediaPipe的姿态检测时序约束实现问题求助
姿态检测时序约束与倒计时实现方案
你的问题核心是不能阻塞视频流的主循环——不管是time.sleep()还是空while循环,都会让程序停在原地,没法读取新的视频帧,自然会导致画面卡死。下面给你一套非阻塞的实现方案,同时满足「完成Pose1后3秒内完成下一个姿态」的要求,还能实时显示倒计时。
核心思路
- 用状态变量跟踪当前进度:当前要检测的姿态索引、上一个姿态完成的时间戳、是否处于倒计时阶段
- 主循环每帧处理视频流,异步检查时间条件,绝不阻塞帧读取
- 用OpenCV把倒计时实时画在画面上
完整实现代码
import cv2 import mediapipe as mp import time # 初始化MediaPipe姿态检测 mp_pose = mp.solutions.pose pose = mp_pose.Pose(static_image_mode=False, min_detection_confidence=0.5, min_tracking_confidence=0.5) mp_drawing = mp.solutions.drawing_utils # 替换成你自己的姿态判断逻辑 def check_TPose(landmarks): # 示例T-Pose判断:肩膀与肘部基本水平,手臂伸直 left_shoulder = landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value] right_shoulder = landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value] left_elbow = landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value] right_elbow = landmarks[mp_pose.PoseLandmark.RIGHT_ELBOW.value] return abs(left_shoulder.y - left_elbow.y) < 0.1 and abs(right_shoulder.y - right_elbow.y) < 0.1 def check_DownPose(landmarks): # 示例低头姿态判断:鼻子位置低于髋部 nose = landmarks[mp_pose.PoseLandmark.NOSE.value] left_hip = landmarks[mp_pose.PoseLandmark.LEFT_HIP.value] return nose.y > left_hip.y # 姿态序列配置 gesture_sequence = [ {"name": "T-Pose", "check_func": check_TPose}, {"name": "Down Look", "check_func": check_DownPose} ] current_gesture_idx = 0 # 当前要检测的姿态索引 countdown_start_time = None # 第一个姿态完成的时间戳 countdown_duration = 3 # 要求的3秒时限 # 启动视频流 cap = cv2.VideoCapture(0) while cap.isOpened(): success, image = cap.read() if not success: print("无法读取视频帧") break # MediaPipe处理图像(转RGB格式) image = cv2.cvtColor(cv2.flip(image, 1), cv2.COLOR_BGR2RGB) results = pose.process(image) image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) # 绘制姿态关键点 if results.pose_landmarks: mp_drawing.draw_landmarks( image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS) landmarks = results.pose_landmarks.landmark # 状态机逻辑 if current_gesture_idx < len(gesture_sequence): current_gesture = gesture_sequence[current_gesture_idx] # 检查当前姿态是否满足 if current_gesture["check_func"](landmarks): if current_gesture_idx == 0: # 第一个姿态完成,启动倒计时 print(f"{current_gesture['name']} 已完成,3秒内请完成下一个姿态") countdown_start_time = time.time() current_gesture_idx += 1 elif current_gesture_idx == 1: # 第二个姿态完成,检查是否超时 elapsed = time.time() - countdown_start_time if elapsed <= countdown_duration: print(f"{current_gesture['name']} 已完成,用时{elapsed:.1f}秒,符合要求") else: print(f"{current_gesture['name']} 完成超时,用时{elapsed:.1f}秒,不符合要求") current_gesture_idx += 1 # 完成序列,可重置或退出 # 实时显示倒计时 if countdown_start_time is not None and current_gesture_idx == 1: elapsed = time.time() - countdown_start_time remaining = max(countdown_duration - elapsed, 0) # 把倒计时画在画面左上角 cv2.putText(image, f"倒计时: {remaining:.1f}s", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2, cv2.LINE_AA) # 倒计时结束未完成的处理 if remaining <= 0: print("倒计时结束,未完成下一个姿态") current_gesture_idx += 1 # 显示画面 cv2.imshow('Pose Detection', image) if cv2.waitKey(5) & 0xFF == 27: break # 释放资源 cap.release() cv2.destroyAllWindows()
关键细节说明
- 状态变量管理:全程靠
current_gesture_idx和countdown_start_time跟踪进度,没有任何阻塞逻辑,保证视频流流畅。 - 姿态判断替换:你需要把
check_TPose和check_DownPose里的逻辑,替换成你自己的TPose_Cal、downPose的判断逻辑,只要返回True表示姿态符合要求即可。 - 倒计时显示:用OpenCV的
putText实时绘制剩余时间,颜色和位置可根据需求调整。
内容的提问来源于stack exchange,提问作者P47HF1ND3R
相关产品推荐
相关产品推荐

