You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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()

关键细节说明

  1. 状态变量管理:全程靠current_gesture_idx和countdown_start_time跟踪进度,没有任何阻塞逻辑,保证视频流流畅。
  2. 姿态判断替换:你需要把check_TPose和check_DownPose里的逻辑,替换成你自己的TPose_Cal、downPose的判断逻辑,只要返回True表示姿态符合要求即可。
  3. 倒计时显示:用OpenCV的putText实时绘制剩余时间,颜色和位置可根据需求调整。

内容的提问来源于stack exchange,提问作者P47HF1ND3R

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 14:27:02