人体步数统计,俯卧撑计数,仰卧起坐计数,引体向上计数,人体动作分析,动作计数,mediapipe,openpose,人体3d姿态分析,3d姿态估计。
本项目旨在开发一个基于计算机视觉的人体运动分析系统,能够准确地识别和计数诸如步行、俯卧撑、仰卧起坐、引体向上等多种常见体育锻炼动作。系统利用先进的深度学习技术,特别是Mediapipe和OpenPose等开源工具,来实时捕捉和分析人体姿态,从而实现动作的精确计数和分析。
关键技术
- Mediapipe:
- 2D姿态估计:使用Mediapipe的Pose模块来检测人体的关键点,包括头部、躯干、四肢等部位。
- 3D姿态估计:利用深度摄像头或立体视觉技术来获取三维姿态信息,增强动作分析的准确性。
- OpenPose:
- 多人姿态检测:能够同时检测多个个体的姿态,适用于健身房等场景。
- 手部和面部关键点检测:提供额外的手部和面部关键点信息,对于分析复杂的动作非常有用。
功能特点
- 动作识别:能够准确识别多种体育动作,包括步行、俯卧撑、仰卧起坐和引体向上等。
- 动作计数:根据动作模式自动计数,无需人工干预。
- 3D姿态分析:提供3D姿态估计,使动作分析更加精细。
- 实时反馈:通过视频流实时显示动作分析结果,为用户提供即时反馈。
- 多平台支持:支持多种设备,包括智能手机、电脑和平板电脑等。
技术实现
- 数据采集:使用普通摄像头或深度摄像头(如Kinect、Intel RealSense等)来捕获视频流。
- 姿态估计:Mediapipe和OpenPose分别用于2D和3D姿态估计。
- 动作识别:基于姿态变化和关键点位置变化来识别特定的动作。
- 计数逻辑:通过设定阈值和连续帧间的姿态变化来实现计数。
- 用户界面:开发图形用户界面,显示动作计数和分析结果。
开发流程
- 数据准备:收集和标注训练数据,包括各种动作的视频片段。
- 模型训练:使用Mediapipe和OpenPose训练姿态估计模型。
- 算法开发:开发算法来识别和计数特定动作。
- 系统集成:将各个组件整合成一个完整的系统。
- 用户界面设计:设计友好的用户交互界面。
- 测试与优化:进行全面测试,并根据用户反馈不断优化。
使用案例
- 健身教练:为个人训练者提供专业指导。
- 体育训练:帮助运动员监测训练效果。
- 康复治疗:协助物理治疗师评估患者的康复进度。
- 智能家居:集成到智能家庭系统中,监测家庭成员的健康活动。
结论
本项目通过结合先进的计算机视觉技术和机器学习方法,实现了对人体动作的有效分析与计数。它不仅能够帮助个人用户监控自己的锻炼情况,还为专业人士提供了有效的工具来评估和改进体育训练。
首先,确保已经安装了必要的Python库:
1pip install mediapipe opencv-python
接下来是具体的代码实现:
1. 导入必要的库
1import cv2
2import mediapipe as mp
3import math
2. 初始化姿态检测器
1mp_drawing = mp.solutions.drawing_utils
2mp_pose = mp.solutions.pose
3
4# 初始化姿态检测模型
5pose = mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5)
3. 定义姿态检测和动作计数的函数
1def detect_pose_and_count_pushups(image, pushup_count=0, state=""):
2 # 转换图像格式
3 image.flags.writeable = False
4 image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
5 results = pose.process(image)
6
7 # 绘制姿态检测结果
8 image.flags.writeable = True
9 image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
10 mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS,
11 mp_drawing.DrawingSpec(color=(245,117,66), thickness=2, circle_radius=2),
12 mp_drawing.DrawingSpec(color=(245,66,230), thickness=2, circle_radius=2))
13
14 # 获取关键点坐标
15 landmarks = results.pose_landmarks.landmark
16 if landmarks:
17 shoulder = [landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value].x,landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value].y]
18 elbow = [landmarks[mp_pose.PoseLandmark.RIGHT_ELBOW.value].x,landmarks[mp_pose.PoseLandmark.RIGHT_ELBOW.value].y]
19 wrist = [landmarks[mp_pose.PoseLandmark.RIGHT_WRIST.value].x,landmarks[mp_pose.PoseLandmark.RIGHT_WRIST.value].y]
20
21 # 计算角度
22 angle = calculate_angle(shoulder, elbow, wrist)
23
24 # 角度阈值
25 angle_threshold_up = 160
26 angle_threshold_down = 70
27
28 # 根据角度判断状态
29 if angle > angle_threshold_up:
30 state = "up"
31 if angle < angle_threshold_down and state == "up":
32 state = "down"
33 pushup_count += 1
34
35 # 显示计数和状态
36 cv2.rectangle(image, (0,0), (225,73), (245,117,16), -1)
37 cv2.putText(image, 'PUSH UPS', (15,12),
38 cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0), 1, cv2.LINE_AA)
39 cv2.putText(image, 'COUNT', (10,40),
40 cv2.FONT_HERSHEY_SIMPLEX, 1, (255,255,255), 2, cv2.LINE_AA)
41 cv2.putText(image, str(pushup_count),
42 (10,70),
43 cv2.FONT_HERSHEY_SIMPLEX, 2, (255,255,255), 2, cv2.LINE_AA)
44
45 # 显示状态
46 cv2.rectangle(image, (0,73), (225,163), (245,66,230), -1)
47 cv2.putText(image, 'STATE', (15,110),
48 cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,0,0), 1, cv2.LINE_AA)
49 cv2.putText(image, state.upper(),
50 (10,140),
51 cv2.FONT_HERSHEY_SIMPLEX, 1, (255,255,255), 2, cv2.LINE_AA)
52
53 return image, pushup_count, state
54
55def calculate_angle(a, b, c):
56 a = np.array(a) # 第一个点
57 b = np.array(b) # 中间点
58 c = np.array(c) # 第三个点
59
60 radians = np.arctan2(c[1]-b[1], c[0]-b[0]) - np.arctan2(a[1]-b[1], a[0]-b[0])
61 angle = np.abs(radians*180.0/np.pi)
62
63 if angle > 180.0:
64 angle = 360-angle
65
66 return angle
4. 主函数
1def main():
2 cap = cv2.VideoCapture(0) # 打开默认摄像头
3 pushup_count = 0
4 state = ""
5
6 while cap.isOpened():
7 ret, frame = cap.read()
8
9 if not ret:
10 break
11
12 image, pushup_count, state = detect_pose_and_count_pushups(frame, pushup_count, state)
13
14 # 显示结果
15 cv2.imshow('Pushup Counter', image)
16
17 if cv2.waitKey(10) & 0xFF == ord('q'):
18 break
19
20 # 清理
21 cap.release()
22 cv2.destroyAllWindows()
23 pose.close()
24
25if __name__ == "__main__":
26 main()
这段代码将打开摄像头并实时检测用户的姿态,计算俯卧撑的次数。请注意,简化版的示例,实际应用中可能需要更多的调试和优化来提高精度和稳定性。