{"id":16270204,"url":"https://github.com/thomas-yanxin/aitrainer","last_synced_at":"2025-08-02T14:33:20.689Z","repository":{"id":47089082,"uuid":"406212162","full_name":"thomas-yanxin/AItrainer","owner":"thomas-yanxin","description":"使用Paddlehub，基于human_pose_estimation_resnet50_mpii，实现健身过程中杠铃动作标准度的判断并自动计数。","archived":false,"fork":false,"pushed_at":"2021-11-29T17:35:30.000Z","size":762,"stargazers_count":26,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-12-02T08:46:12.630Z","etag":null,"topics":["fitness","opencv","paddlehub","paddlepaddle"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thomas-yanxin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-09-14T03:32:31.000Z","updated_at":"2024-07-16T11:32:11.000Z","dependencies_parsed_at":"2022-08-24T08:40:27.831Z","dependency_job_id":null,"html_url":"https://github.com/thomas-yanxin/AItrainer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomas-yanxin%2FAItrainer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomas-yanxin%2FAItrainer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomas-yanxin%2FAItrainer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomas-yanxin%2FAItrainer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thomas-yanxin","download_url":"https://codeload.github.com/thomas-yanxin/AItrainer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228485031,"owners_count":17927623,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fitness","opencv","paddlehub","paddlepaddle"],"created_at":"2024-10-10T18:09:51.611Z","updated_at":"2024-12-06T15:26:20.331Z","avatar_url":"https://github.com/thomas-yanxin.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AItrainer\n\n## 基于Paddlehub的哑铃抬举检测及自动计数\n\n### PaddleHub 简介\n\n使用Paddlehub能够便捷地获取PaddlePaddle生态下的预训练模型，完成模型的管理和一键预测。配合使用Fine-tune API，可以基于大规模预训练模型快速完成迁移学习，让预训练模型能更好地服务于用户特定场景的应用。\n\n本项目采用Paddlehub, 基于[human_pose_estimation_resnet50_mpii](https://www.paddlepaddle.org.cn/hubdetail?name=human_pose_estimation_resnet50_mpii\u0026en_category=KeyPointDetection)人体关键点检测模型。\n\n```\n# 使用前先安装模型\nhub install human_pose_estimation_resnet50_mpii==1.1.1\n```\n\n### 模型概述\n\n人体骨骼关键点检测(Pose Estimation) 是计算机视觉的基础性算法之一，在诸多计算机视觉任务起到了基础性的作用，如行为识别、人物跟踪、步态识别等相关领域。具体应用主要集中在智能视频监控，病人监护系统，人机交互，虚拟现实，人体动画，智能家居，智能安防，运动员辅助训练等等。 该模型的论文《Simple Baselines for Human Pose Estimation and Tracking》由 MSRA 发表于 ECCV18，使用 MPII 数据集训练完成。\n\n### 项目思路\n\n本项目实现在健身过程的哑铃抬举的过程中，对进行此过程的六个关节点分别检测，即左右手腕、左右手肘、左右肩部，并分别计算以手肘为基点，手腕、手肘、肩部所构成的向量夹角。以夹角为核心 判断哑铃动作是否到位，完成两次的【0°-90°】向量夹角变化算作一次哑铃抬举动作。\n\n### 项目流程\n\n**Step one**\n\n使用human_pose_estimation_resnet50_mpii模型对受众人体关键点进行检测，并从中抽取出项目所需的六个关节点，即：【right_wrist、right_elbow、right_shoulder、left_wrist、left_elbow、left_shoulder】,并将其存放进列表中：\n\n```\ndef aitrainer(picture):\n\n    consequence = []\n    result = pose_estimation.keypoint_detection(images=[cv2.imread(picture)])\n\n    predict = dict(result[0][\"data\"])\n\n    right_wrist = predict['right_wrist']\n    consequence.append(right_wrist)\n\n    right_elbow = predict['right_elbow']\n    consequence.append(right_elbow)\n\n    right_shoulder = predict['right_shoulder']\n    consequence.append(right_shoulder)\n\n    left_shoulder = predict['left_shoulder']\n    consequence.append(left_shoulder)\n\n    left_elbow = predict['left_elbow']\n    consequence.append(left_elbow)\n\n    left_wrist = predict['left_wrist']\n    consequence.append(left_wrist)\n\n    return consequence\n\n```\n\n**Step two**\n\n前文提及，本项目的核心在于【以手肘为中心点，对手腕、手肘、肩部所构成的夹角进行计算，以夹角为判断依据，从而对哑铃抬举动作进行监督并且计数】。\n\n```\ndef Cal_Ang(point_1, point_2, point_3):\n    \"\"\"\n    根据三点坐标计算夹角\n    :param point_1: 点1坐标\n    :param point_2: 点2坐标\n    :param point_3: 点3坐标\n    :return: 点2的夹角(中心点)\n    \"\"\"\n    a=math.sqrt((point_2[0]-point_3[0]) * (point_2[0]-point_3[0])+(point_2[1]-point_3[1]) * (point_2[1]-point_3[1]))\n\n    b=math.sqrt((point_1[0]-point_3[0]) * (point_1[0]-point_3[0])+(point_1[1]-point_3[1]) * (point_1[1]-point_3[1]))\n\n    c=math.sqrt((point_1[0]-point_2[0]) * (point_1[0]-point_2[0])+(point_1[1]-point_2[1]) * (point_1[1]-point_2[1]))\n    \n    B=math.degrees(math.acos((b*b-a*a-c*c)/(-2*a*c)))\n\n    return B\n```\n\n**Step three**\n\n使用OpenCV打开本地摄像头获取动态页面，并将项目检测结果实时展示在页面中：\n```\ncap = cv2.VideoCapture(0)\n\nwhile(1):\n    # get a frame\n    ret, frame = cap.read()\n    frame = cv2.resize(frame, (1280, 720))\n\n    print(\"训练将在5秒后进行，请您做好准备！\")\n\n    for i in range(5):\n        time.sleep(1)\n        m = 5 - i\n        print(m)\n\n    if cv2.waitKey(1) \u0026 0xFF == ord('q'):\n        break  \n    cv2.imwrite(\"camera.jpg\", frame)\n\n    point = aitrainer('camera.jpg')\n\n    if train_content == '左臂':\n\n        left_wrist = point[5]\n        left_elbow = point[4]\n        left_shoulder = point[3]\n\n        angle_left = Cal_Ang(left_wrist,left_elbow,left_shoulder)\n\n        diff = angle_left - angle_last\n\n        if diff \u003e=0 and det_1 == 0:\n            count += 0.5\n            det_1 = 1 \n    \n        if diff \u003c=0 and det_1 ==1:\n            count += 0.5\n            det_1 = 2\n\n        cv2.line(frame, tuple(left_wrist), tuple(left_elbow),(0, 0, 255), 3)\n        cv2.line(frame, tuple(left_elbow), tuple(left_shoulder),(0, 0, 225), 3)\n\n        if count % 1.0 == 0.0:\n            det_1 = 0\n            print(\"count:%.2f\"%count)\n\n            cv2.rectangle(frame, (0, 450), (250, 720), (0, 255, 0), cv2.FILLED)\n            cv2.putText(frame, str(int(count)), (45, 670), cv2.FONT_HERSHEY_PLAIN, 10,\n            (255, 0, 0), 20)\n\n        cv2.imshow('OpenPose using OpenCV', frame)\n\n    if train_content == '右臂':\n\n        right_wrist = point[0]\n        right_elbow = point[1]\n        right_shoulder = point[2]\n\n        angle_right = Cal_Ang(right_wrist,right_elbow,right_shoulder)\n\n        diff = angle_right - angle_last\n\n        if diff \u003e=0 and det_1 == 0:\n            count += 0.5\n            det_1 = 1 \n    \n        if diff \u003c=0 and det_1 ==1:\n            count += 0.5\n            det_1 = 2\n\n        cv2.line(frame, tuple(right_wrist), tuple(right_elbow),(0, 0, 255), 3)\n        cv2.line(frame, tuple(right_elbow), tuple(right_shoulder),(0, 0, 225), 3)\n\n        if count % 1.0 == 0.0:\n            det_1 = 0\n            print(\"count:%.2f\"%count)\n\n            cv2.rectangle(frame, (0, 450), (250, 720), (0, 255, 0), cv2.FILLED)\n            cv2.putText(frame, str(int(count)), (45, 670), cv2.FONT_HERSHEY_PLAIN, 10,\n            (255, 0, 0), 20)\n\n        cv2.imshow('OpenPose using OpenCV', frame)\n\ncap.release()\n```\n【注：这里区分了左臂or右臂】\n\n### 效果展示【[bilibili链接](https://www.bilibili.com/video/BV1cU4y1N7Yo/)】\n\n![image](https://user-images.githubusercontent.com/58030051/133214015-b9211570-4b9f-48a5-9edb-f2dac00b0d18.png)\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomas-yanxin%2Faitrainer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthomas-yanxin%2Faitrainer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomas-yanxin%2Faitrainer/lists"}