使用Mediapipe和OpenPose进行人体动作分析、计数以及3D姿态估计

 

人体步数统计,俯卧撑计数,仰卧起坐计数,引体向上计数,人体动作分析,动作计数,mediapipe,openpose,人体3d姿态分析,3d姿态估计。

本项目旨在开发一个基于计算机视觉的人体运动分析系统,能够准确地识别和计数诸如步行、俯卧撑、仰卧起坐、引体向上等多种常见体育锻炼动作。系统利用先进的深度学习技术,特别是Mediapipe和OpenPose等开源工具,来实时捕捉和分析人体姿态,从而实现动作的精确计数和分析。

关键技术

  1. Mediapipe
    • 2D姿态估计:使用Mediapipe的Pose模块来检测人体的关键点,包括头部、躯干、四肢等部位。
    • 3D姿态估计:利用深度摄像头或立体视觉技术来获取三维姿态信息,增强动作分析的准确性。

  1. OpenPose
    • 多人姿态检测:能够同时检测多个个体的姿态,适用于健身房等场景。
    • 手部和面部关键点检测:提供额外的手部和面部关键点信息,对于分析复杂的动作非常有用。

功能特点

  • 动作识别:能够准确识别多种体育动作,包括步行、俯卧撑、仰卧起坐和引体向上等。
  • 动作计数:根据动作模式自动计数,无需人工干预。
  • 3D姿态分析:提供3D姿态估计,使动作分析更加精细。
  • 实时反馈:通过视频流实时显示动作分析结果,为用户提供即时反馈。
  • 多平台支持:支持多种设备,包括智能手机、电脑和平板电脑等。

技术实现

  • 数据采集:使用普通摄像头或深度摄像头(如Kinect、Intel RealSense等)来捕获视频流。
  • 姿态估计:Mediapipe和OpenPose分别用于2D和3D姿态估计。
  • 动作识别:基于姿态变化和关键点位置变化来识别特定的动作。
  • 计数逻辑:通过设定阈值和连续帧间的姿态变化来实现计数。
  • 用户界面:开发图形用户界面,显示动作计数和分析结果。

开发流程

  1. 数据准备:收集和标注训练数据,包括各种动作的视频片段。
  2. 模型训练:使用Mediapipe和OpenPose训练姿态估计模型。
  3. 算法开发:开发算法来识别和计数特定动作。
  4. 系统集成:将各个组件整合成一个完整的系统。
  5. 用户界面设计:设计友好的用户交互界面。
  6. 测试与优化:进行全面测试,并根据用户反馈不断优化。

使用案例

  • 健身教练:为个人训练者提供专业指导。
  • 体育训练:帮助运动员监测训练效果。
  • 康复治疗:协助物理治疗师评估患者的康复进度。
  • 智能家居:集成到智能家庭系统中,监测家庭成员的健康活动。

结论

本项目通过结合先进的计算机视觉技术和机器学习方法,实现了对人体动作的有效分析与计数。它不仅能够帮助个人用户监控自己的锻炼情况,还为专业人士提供了有效的工具来评估和改进体育训练。

首先,确保已经安装了必要的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()

这段代码将打开摄像头并实时检测用户的姿态,计算俯卧撑的次数。请注意,简化版的示例,实际应用中可能需要更多的调试和优化来提高精度和稳定性。

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一个基于姿态估计人体动作识别的代码示例,使用OpenPose进行姿态估计动作识别: ```python import cv2 import time import numpy as np from openpose import pyopenpose as op # OpenPose参数 params = dict() params["model_folder"] = "openpose/models/" params["model_pose"] = "BODY_25" params["net_resolution"] = "-1x256" params["number_people_max"] = 1 params["display"] = 0 # OpenPose初始 opWrapper = op.WrapperPython() opWrapper.configure(params) opWrapper.start() # 动作识别模型 model = keras.models.load_model("action_recognition_model.h5") # 动作识别标签 labels = ["jump", "punch", "run", "squat", "walk"] # 视频输入 cap = cv2.VideoCapture("test.mp4") # 帧计数 frame_count = 0 # 帧缓存 frame_buffer = [] while True: # 读取视频帧 ret, frame = cap.read() if not ret: break # 调整帧大小 frame = cv2.resize(frame, (640, 360)) # OpenPose姿态估计 datum = op.Datum() datum.cvInputData = frame opWrapper.emplaceAndPop([datum]) pose = datum.poseKeypoints # 如果没有检测到人物,则跳过 if pose.shape[0] == 0: continue # 将姿态估计结果转换为模型输入 input_data = np.zeros((1, 16, 25)) for i in range(25): if pose[0, i, 2] > 0.5: input_data[0, :, i] = pose[0, i, :2].reshape((-1,)) input_data = input_data / 1000.0 # 将帧添加到帧缓存中 frame_buffer.append(input_data) if len(frame_buffer) < 16: continue # 将帧缓存转换为模型输入 input_data = np.concatenate(frame_buffer, axis=0) input_data = np.expand_dims(input_data, axis=0) # 动作识别 pred = model.predict(input_data)[0] action = labels[np.argmax(pred)] # 在视频帧上绘制动作标签 cv2.putText(frame, action, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 255, 0), 2) # 显示视频帧 cv2.imshow("frame", frame) key = cv2.waitKey(1) & 0xFF if key == ord("q"): break # 帧计数和帧缓存更新 frame_count += 1 if frame_count % 2 == 0: frame_buffer.pop(0) # 清理 cap.release() cv2.destroyAllWindows() ``` 需要安装OpenCV、TensorFlow和Keras库,并下载OpenPose模型和动作识别模型。在运行代码之前,请先按照说明进行安装和配置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值