当前位置: 首页 > news >正文

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

MediaPipe人体姿态估计实战:用Python+OpenCV打造智能健身教练系统

健身房里总能看到有人对着镜子反复调整动作,却依然不确定自己的深蹲是否标准。现在,我们完全可以用计算机视觉技术解决这个问题——通过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_confidence=0.5, min_tracking_confidence=0.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_confidence=0.7, min_tracking_confidence=0.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. 动作标准性判断算法

以深蹲为例,一个标准的深蹲需要满足以下几个条件:

  1. 下蹲时膝盖不超过脚尖(31/32号点与25/26号点的相对位置)
  2. 背部保持挺直(11,12号点与23,24号点形成的角度)
  3. 下蹲深度达到要求(髋关节低于膝关节)

实现这些判断需要一些几何计算:

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 angle

4. 系统集成与用户反馈

完整的AI健身教练系统需要将姿态检测、动作分析和用户反馈集成在一起。我们可以通过视觉和听觉两种方式提供反馈:

def provide_feedback(image, feedback_text, is_good=False): # 设置显示参数 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_confidence=0.7, min_tracking_confidence=0.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

性能优化技巧

  1. 降低处理分辨率(保持检测精度同时提高帧率)
  2. 使用多线程处理视频流和姿态分析
  3. 对关键点坐标进行平滑滤波(减少抖动)
# 降低分辨率示例 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, interpolation=cv2.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在光照条件良好、用户穿着紧身衣物时检测效果最佳。对于健身应用,建议用户穿着与背景对比明显的服装,并在侧面放置一个辅助光源来减少阴影干扰。

http://www.cnnetsun.cn/news/1736691.html

相关文章:

  • Kandinsky-5.0-I2V-Lite-5s创意作品展:从名画到动态艺术的惊艳转变
  • Godot游戏资源解包终极指南:3分钟掌握专业级资源提取技巧
  • 单页应用如何处理动态内容对SEO的影响
  • Docker容器共享内存不足?3种实战解决方案对比(含K8s适配)
  • C/C++文件操作神器:freopen()函数实战指南(含路径避坑技巧)
  • 记一次千万级订单表分页查询优化:
  • win11 中文家庭版-无法下载更新-说是系统大补丁没有完全导致的-需要等到大补丁到了才可以下载更新
  • 从“僵尸节点”到优雅休眠:深入理解AUTOSAR NM中T_NM_Timeout的协同设计
  • Mac Mouse Fix:让10美元鼠标超越苹果触控板的终极解决方案
  • BUUCTF SQL注入通关秘籍:如何快速定位并利用fl4g表获取flag
  • 保姆级教程:在ZYNQ Ultrascale+ MPSOC上配置PS端DP显示(Vitis 2023.1实测)
  • 39_从工程角度分析:0_钢铁侠战甲的制造可行性
  • 树莓派/软路由必备:让frpc在OpenWrt或Debian系统开机自启的两种方法
  • 探索NomNom:定制《无人深空》游戏体验的全流程指南
  • MySQL实战:主键与外键的5个常见设计误区及优化方案
  • 如何用Listen1实现跨平台音乐播放?告别多平台切换的终极解决方案
  • 如何通过League Akari提升英雄联盟游戏体验:全方位效率工具指南
  • OpenClaw语音控制:Qwen3-4B-Thinking-2507-GPT-5-Codex-Distill-GGUF实现声控自动化
  • 渗透测试发现的Nacos漏洞怎么修?SpringBoot项目实战修复指南
  • 3步实现B站m4s格式转换:跨平台视频解决方案
  • 隐私·效率·低门槛:本地语音转文字工具TMSpeech的场景化指南
  • MiniCPM-V-2_6AR应用赋能:手机摄像头取景框实时图文叠加说明
  • 3分钟搞定抖音内容采集:开源工具如何颠覆传统下载方式?
  • 别再手动拖拽了!用Cursor+Claude 3.5生成Mermaid代码,5分钟搞定产品需求流程图
  • 终极B站视频下载指南:3步解锁4K大会员高清资源
  • 打造专属海拉鲁冒险:塞尔达传说旷野之息个性化存档编辑指南
  • 手把手教你用DeepSeek-OCR:图片文字提取保姆级教程
  • 别再死记命令了!深入理解RIP和OSPF协议差异,一次搞定动态路由配置
  • Node.js后端集成:快速配置环境并调用Qwen3.5-9B-AWQ-4bit模型API
  • 模型切换技巧:OpenClaw动态调用Qwen3-4B-Thinking不同量化版本