MediaPipe人体姿态估计实战:用Python+OpenCV做个AI健身教练(附完整代码)

张开发
2026/4/17 13:15:36 15 分钟阅读

分享文章

MediaPipe人体姿态估计实战:用Python+OpenCV做个AI健身教练(附完整代码)
MediaPipe人体姿态估计实战用PythonOpenCV打造智能健身教练系统健身房里总能看到有人对着镜子反复调整动作却依然不确定自己的深蹲是否标准。现在我们完全可以用计算机视觉技术解决这个问题——通过MediaPipe的姿态估计功能配合Python和OpenCV打造一个能实时反馈动作标准的AI健身教练。这个系统不仅能识别33个身体关键点还能判断动作完成质量让居家健身也能获得专业指导。1. 环境配置与基础姿态检测在开始构建AI健身教练之前我们需要准备好开发环境。MediaPipe对硬件要求并不高普通笔记本电脑的CPU就能流畅运行基础功能但如果需要处理更高帧率的视频流建议使用配备独立显卡的设备。首先安装必要的Python包pip install mediapipe opencv-python numpy验证安装是否成功的最快方式是运行一个简单的姿态检测脚本import cv2 import mediapipe as mp mp_pose mp.solutions.pose pose mp_pose.Pose(min_detection_confidence0.5, min_tracking_confidence0.5) image cv2.imread(test_image.jpg) image_rgb cv2.cvtColor(image, cv2.COLOR_BGR2RGB) results pose.process(image_rgb) if results.pose_landmarks: print(f检测到{len(results.pose_landmarks.landmark)}个身体关键点) else: print(未检测到人体姿态)MediaPipe的Pose模型会返回33个关键点每个关键点包含以下信息属性描述取值范围x关键点水平位置0.0-1.0相对于图像宽度y关键点垂直位置0.0-1.0相对于图像高度z关键点深度值越小表示离摄像头越远visibility关键点可见性0.0-1.0值越大越可见2. 实时视频流处理与关键点可视化要让系统真正实用必须能够处理实时视频流。OpenCV的VideoCapture类配合MediaPipe可以轻松实现这一功能cap cv2.VideoCapture(0) # 0表示默认摄像头 with mp_pose.Pose( min_detection_confidence0.7, min_tracking_confidence0.7) as pose: while cap.isOpened(): success, image cap.read() if not success: continue # 转换颜色空间并处理 image.flags.writeable False image cv2.cvtColor(image, cv2.COLOR_BGR2RGB) results pose.process(image) # 绘制关键点和连接线 image.flags.writeable True image cv2.cvtColor(image, cv2.COLOR_RGB2BGR) mp.solutions.drawing_utils.draw_landmarks( image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS) cv2.imshow(AI Fitness Coach, image) if cv2.waitKey(5) 0xFF 27: break cap.release()这段代码会打开摄像头并实时显示带有关键点和骨骼连接线的画面。对于健身应用我们特别关注以下几个关键点11,12号点左右肩膀23,24号点左右髋部25,26号点左右膝盖27,28号点左右脚踝29,30号点左右脚跟31,32号点左右脚尖3. 动作标准性判断算法以深蹲为例一个标准的深蹲需要满足以下几个条件下蹲时膝盖不超过脚尖31/32号点与25/26号点的相对位置背部保持挺直11,12号点与23,24号点形成的角度下蹲深度达到要求髋关节低于膝关节实现这些判断需要一些几何计算def check_squat(landmarks, image_width, image_height): # 获取关键点坐标转换为像素值 left_hip get_pixel_coords(landmarks[23], image_width, image_height) right_hip get_pixel_coords(landmarks[24], image_width, image_height) left_knee get_pixel_coords(landmarks[25], image_width, image_height) right_knee get_pixel_coords(landmarks[26], image_width, image_height) left_ankle get_pixel_coords(landmarks[27], image_width, image_height) right_ankle get_pixel_coords(landmarks[28], image_width, image_height) left_toe get_pixel_coords(landmarks[31], image_width, image_height) right_toe get_pixel_coords(landmarks[32], image_width, image_height) # 计算膝盖是否超过脚尖 knee_over_toe_left left_knee[0] left_toe[0] knee_over_toe_right right_knee[0] right_toe[0] # 计算髋关节是否低于膝关节 hip_below_knee_left left_hip[1] left_knee[1] hip_below_knee_right right_hip[1] right_knee[1] # 计算背部角度 shoulder_angle calculate_angle(landmarks[11], landmarks[12], landmarks[23], image_width, image_height) back_straight 160 shoulder_angle 200 feedback [] if knee_over_toe_left or knee_over_toe_right: feedback.append(膝盖超过脚尖了) if not (hip_below_knee_left and hip_below_knee_right): feedback.append(下蹲深度不够) if not back_straight: feedback.append(背部没有保持挺直) return feedback if feedback else [动作标准]角度计算的辅助函数def calculate_angle(point1, point2, point3, image_width, image_height): # 将三个点转换为像素坐标 p1 get_pixel_coords(point1, image_width, image_height) p2 get_pixel_coords(point2, image_width, image_height) p3 get_pixel_coords(point3, image_width, image_height) # 计算向量 vec1 (p1[0]-p2[0], p1[1]-p2[1]) vec2 (p3[0]-p2[0], p3[1]-p2[1]) # 计算角度 dot vec1[0]*vec2[0] vec1[1]*vec2[1] det vec1[0]*vec2[1] - vec1[1]*vec2[0] angle math.degrees(math.atan2(det, dot)) return angle 360 if angle 0 else angle4. 系统集成与用户反馈完整的AI健身教练系统需要将姿态检测、动作分析和用户反馈集成在一起。我们可以通过视觉和听觉两种方式提供反馈def provide_feedback(image, feedback_text, is_goodFalse): # 设置显示参数 font cv2.FONT_HERSHEY_SIMPLEX font_scale 1 thickness 2 color (0, 255, 0) if is_good else (0, 0, 255) # 在图像上添加文本 y_offset 50 for line in feedback_text: cv2.putText(image, line, (50, y_offset), font, font_scale, color, thickness, cv2.LINE_AA) y_offset 40 # 添加语音反馈需要pyttsx3库 try: import pyttsx3 engine pyttsx3.init() for line in feedback_text: engine.say(line) engine.runAndWait() except ImportError: pass return image将以上所有组件整合后的主循环cap cv2.VideoCapture(0) frame_count 0 feedback_interval 10 # 每10帧提供一次反馈 with mp_pose.Pose( min_detection_confidence0.7, min_tracking_confidence0.7) as pose: while cap.isOpened(): success, image cap.read() if not success: continue frame_count 1 provide_feedback_now frame_count % feedback_interval 0 # 处理图像 image.flags.writeable False image cv2.cvtColor(image, cv2.COLOR_BGR2RGB) results pose.process(image) # 绘制关键点 image.flags.writeable True image cv2.cvtColor(image, cv2.COLOR_RGB2BGR) if results.pose_landmarks: mp.solutions.drawing_utils.draw_landmarks( image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS) if provide_feedback_now: feedback check_squat(results.pose_landmarks.landmark, image.shape[1], image.shape[0]) image provide_feedback(image, feedback, feedback[0]动作标准) frame_count 0 cv2.imshow(AI Fitness Coach, image) if cv2.waitKey(5) 0xFF 27: break cap.release() cv2.destroyAllWindows()5. 扩展功能与性能优化基础功能实现后我们可以考虑添加更多实用功能来提升用户体验动作计数功能通过检测髋关节的垂直运动轨迹来判断是否完成了一次完整的深蹲class SquatCounter: def __init__(self): self.count 0 self.hip_positions [] self.down_threshold 0.05 # 髋部下移超过5%图像高度 self.up_threshold 0.03 # 髋部上移超过3%图像高度 self.state up # or down def update(self, hip_y): self.hip_positions.append(hip_y) if len(self.hip_positions) 2: return self.count # 计算移动方向 delta self.hip_positions[-1] - self.hip_positions[-2] if self.state up and delta self.down_threshold: self.state down elif self.state down and delta -self.up_threshold: self.state up self.count 1 return self.count性能优化技巧降低处理分辨率保持检测精度同时提高帧率使用多线程处理视频流和姿态分析对关键点坐标进行平滑滤波减少抖动# 降低分辨率示例 def resize_and_maintain_aspect(image, target_width): h, w image.shape[:2] ratio target_width / float(w) dim (target_width, int(h * ratio)) return cv2.resize(image, dim, interpolationcv2.INTER_AREA) # 在视频循环中使用 image resize_and_maintain_aspect(image, 640)支持更多健身动作通过类似的方法可以实现对其他动作的检测如俯卧撑检测肘部角度和身体高度开合跳检测手脚距离变化平板支撑检测身体直线度和髋部高度def check_pushup(landmarks, image_width, image_height): left_shoulder get_pixel_coords(landmarks[11], image_width, image_height) left_elbow get_pixel_coords(landmarks[13], image_width, image_height) left_wrist get_pixel_coords(landmarks[15], image_width, image_height) elbow_angle calculate_angle(left_shoulder, left_elbow, left_wrist, image_width, image_height) feedback [] if elbow_angle 160: feedback.append(手臂没有完全伸直) elif elbow_angle 90: feedback.append(身体可以再降低一些) return feedback if feedback else [动作标准]在实际项目中我发现MediaPipe在光照条件良好、用户穿着紧身衣物时检测效果最佳。对于健身应用建议用户穿着与背景对比明显的服装并在侧面放置一个辅助光源来减少阴影干扰。

更多文章