MediaPipe 0.10.10 姿态识别实战:基于关节夹角的仰卧起坐计数实现
MediaPipe 0.10.10 姿态识别实战基于关节夹角的仰卧起坐计数实现在健身和运动科学领域准确的动作计数对于训练效果评估至关重要。传统的人工计数方式不仅效率低下还容易产生误差。本文将带你使用MediaPipe 0.10.10版本结合Python和OpenCV开发一个能够自动识别并计数仰卧起坐动作的智能系统。1. 环境准备与MediaPipe基础MediaPipe是Google开发的一个跨平台机器学习解决方案库特别适合实时媒体处理。它提供了多种预训练模型包括人体姿态识别这正是我们项目所需要的核心功能。首先我们需要设置开发环境pip install mediapipe0.10.10 opencv-python numpyMediaPipe的姿态识别模型能够检测人体的33个关键点包括面部、躯干和四肢的关节位置。这些关键点以归一化坐标(x,y,z)的形式返回其中x和y坐标在[0,1]范围内表示在图像中的相对位置z坐标表示深度值越小表示离摄像头越近visibility表示关键点在图像中的可见性概率2. 关键点分析与角度计算原理仰卧起坐动作的核心是躯干的弯曲和伸展。通过分析髋关节(23,24号点)、肩关节(11,12号点)和膝关节(25,26号点)之间的角度变化我们可以准确识别动作的完成情况。角度计算采用向量叉积公式def calculate_angle(a, b, c): 计算三个点之间的夹角 a: 第一个点坐标 [x,y] b: 中间点(顶点)坐标 [x,y] c: 第三个点坐标 [x,y] ba np.array([a[0]-b[0], a[1]-b[1]]) bc np.array([c[0]-b[0], c[1]-b[1]]) cosine_angle np.dot(ba, bc) / (np.linalg.norm(ba) * np.linalg.norm(bc)) angle np.arccos(cosine_angle) return np.degrees(angle)下表展示了关键点对应的人体部位关键点编号对应身体部位11左肩12右肩23左髋24右髋25左膝26右膝3. 完整实现代码解析下面是完整的仰卧起坐计数系统实现代码包含关键点检测、角度计算和计数逻辑import cv2 import mediapipe as mp import numpy as np # 初始化MediaPipe姿态识别 mp_pose mp.solutions.pose pose mp_pose.Pose( static_image_modeFalse, model_complexity1, smooth_landmarksTrue, min_detection_confidence0.5, min_tracking_confidence0.5 ) def calculate_angle(a, b, c): 计算三个关键点之间的夹角 a np.array(a) b np.array(b) c np.array(c) radians np.arctan2(c[1]-b[1], c[0]-b[0]) - np.arctan2(a[1]-b[1], a[0]-b[0]) angle np.abs(radians*180.0/np.pi) if angle 180.0: angle 360-angle return angle # 初始化摄像头 cap cv2.VideoCapture(0) counter 0 # 动作计数器 stage None # 动作阶段标识 while cap.isOpened(): ret, frame cap.read() if not ret: continue # 转换颜色空间并处理姿态 image cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) results pose.process(image) # 转换回BGR用于显示 image cv2.cvtColor(image, cv2.COLOR_RGB2BGR) try: landmarks results.pose_landmarks.landmark # 获取需要的关键点坐标 shoulder [landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].x, landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].y] hip [landmarks[mp_pose.PoseLandmark.LEFT_HIP.value].x, landmarks[mp_pose.PoseLandmark.LEFT_HIP.value].y] knee [landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value].x, landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value].y] # 计算角度 angle calculate_angle(shoulder, hip, knee) # 可视化角度 cv2.putText(image, fAngle: {int(angle)}, tuple(np.multiply(hip, [640, 480]).astype(int)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255,255,255), 2, cv2.LINE_AA) # 计数逻辑 if angle 160: stage down if angle 60 and stage down: stage up counter 1 except: pass # 显示计数结果 cv2.putText(image, fCount: {counter}, (10,50), cv2.FONT_HERSHEY_SIMPLEX, 2, (0,0,255), 2, cv2.LINE_AA) # 显示图像 cv2.imshow(Sit-up Counter, image) if cv2.waitKey(10) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()4. 优化与调试技巧在实际应用中你可能会遇到以下问题及解决方案关键点抖动问题启用MediaPipe的smooth_landmarks参数添加简单的移动平均滤波# 在循环外部初始化 angle_history [] # 在角度计算后添加 angle_history.append(angle) if len(angle_history) 5: angle_history.pop(0) smoothed_angle sum(angle_history) / len(angle_history)多人场景处理通过bounding box选择最接近摄像头的人体或者选择运动幅度最大的人体作为主要目标光照条件优化使用自适应直方图均衡化gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) clahe cv2.createCLAHE(clipLimit2.0, tileGridSize(8,8)) enhanced clahe.apply(gray) frame cv2.cvtColor(enhanced, cv2.COLOR_GRAY2BGR)角度阈值调整不同体型的人可能需要不同的角度阈值可以添加校准阶段让用户完成一个标准动作来设置个性化阈值提示在实际部署时考虑添加开始/结束按钮和声音反馈提升用户体验。5. 扩展应用与进阶方向这个基础系统可以进一步扩展为动作质量评估检测腰部是否完全接触地面分析动作速度是否均匀识别代偿动作如颈部过度用力多动作识别系统俯卧撑计数深蹲计数引体向上计数云端数据存储与分析使用Firebase等后端服务存储训练数据生成训练进度图表和趋势分析移动端部署使用MediaPipe的Android/iOS支持开发跨平台Flutter应用下表比较了不同动作识别算法的性能特点方法准确率实时性硬件要求适用场景MediaPipe高极佳低移动端/边缘计算OpenPose很高一般高研究/高精度需求传统CV中佳低简单动作识别深度学习极高差极高专业分析通过这个项目我们不仅实现了一个实用的健身辅助工具还掌握了MediaPipe在姿态识别方面的核心应用。这种基于关节夹角的分析方法可以推广到许多其他动作识别场景为运动科学和健康监测应用开发提供了坚实基础。

相关新闻