当前位置:首页> AI教程> AI技术助力单杠训练

AI技术助力单杠训练

释放双眼,带上耳机,听听看~!
了解如何利用AI技术和mediapipe框架进行单杠训练姿态识别,提高训练效果和标准化训练过程。

AI技术助力单杠训练

我正在参加「掘金·启航计划」

分享一个AI小应用,借助于mediapipe的能力,对人体姿态进行识别,实现自动数单杠。

一、背景

引体向上是反应学生上肢肌肉力量和耐力的常用指标,这个项目简单实用,适用于初中至大学各个年级的同学。数单杠是一门技术活,下来手臂要伸直,上去下巴要过杠,因为主观因素的加入,导致标准不统一。有没有可能使用AI技术来智能判别单杠动作是否标准,直接用机器计数,这样既节省了人力,又统一了标准

前段时间了解学习了一下mediapipe,这是谷歌开源的一个框架,粗略看了一下,十分强大,特别是跨端实现的能力,【姿态估计】MediaPipe部分solution(手势,人体姿态,面部动作)的用法_mp.solutions.pose_Sciengineer-Mike的博客-CSDN博客

二、思路

联想到人体姿态估计的模型正好可以应用在单杠计数上面,因为这个模型可以给出33个人体关节点,几乎所有可以活动的大关节都有识别。

AI技术助力单杠训练

如果用这些点来判断单杠的动作,应该是完全行得通的,我们只要关注手臂的状态以及手臂和嘴巴的相对高度就可以。整个数单杠的功能大概想了一下有这么几步:

  • 启动姿态识别,获取人体的关键点位坐标,主要涉及到(9,11,13,15,16)
  • 一个完整的单杠过程包括:双臂自然伸直 >> 发力引体 >> 下颌过杠 >> 还原至手臂自然悬垂
  • 如此循环至体测结束,显示结果

关于动作的判定是这么考虑的:全程手掌比手腕位置要高,双臂自然伸直的话,手肘的角度(即12-14-16)需要大于150°;下巴过杠的话,需要将左手和右手手腕连线(即15-16)作为水平线,下巴以嘴巴向下偏移x为准(即9),这个x根据实际再做调整。

👉需要注意的地方

需要注意的是,拉单杠是一个连续的过程,但是我们识别都是针对每一帧进行的,需要设置一个标记变量f=0,整个有点类似于斯密特触发器,当f=0时,从手臂悬垂到满足下巴过杠且时,置f=1(即为有效状态),然后等待手臂放下达到手臂悬垂条件时,置f=0,即为完成一个。

AI技术助力单杠训练

三、代码部分

有兴趣的同学可以看看mediapipe官方例子

这里使用python环境,安装mediapipe,pip install mediapipe,就不展开了。

第一步导入模块:

    import mediapipe as mp
    import cv2
    mpPose = mp.solutions.pose  # 检测人体姿态
    pose_mode = mpPose.Pose(min_detection_confidence=0.5,min_tracking_confidence=0.5)  # 模式参数设置
    mpDraw = mp.solutions.drawing_utils  # 绘图
    up=0 #单杠初始值为0

第二步设置循环:

    while True:
            # 读取摄像头
        cap = cv2.VideoCapture('./test.mp4')
        success, img = cap.read()
            # 识别主进程
        results = pose_mode.process(img)
            # 判断是否有结果
        if results.pose_landmarks:
           ...
           ...对结果进行动作判别,绘制识别结果,具体实现看下面步骤
        
        cv2.imshow("img", img)
        if cv2.waitKey(1)&0xFF == ord("q"):
            break
    cap.release()
    cv2.destroyAllWindows()

第三步动作判别并绘制识别结果:

      # 绘制识别的结果
            mpDraw.draw_landmarks(img, results.pose_landmarks,
                                  mpPose.POSE_CONNECTIONS)
      # 这里将手部的水平线用特殊颜色画出来
            cv2.line(img, (points[3][0], points[3][1]),(points[4][0], points[4][1]), (0, 0, 255), 2)
         # 判断 下颌是否超过手部,代表下巴过杠,则是一个合格,这里可以设置一个阈值,用于平衡角度的影响
            distance, degree,angle,wrist_gt_elbow =  pull_up_check(points) 
            if distance > -15 and degree < 10 and wrist_gt_elbow:
                    if biaoji == 1:
                        up += 1
                        i += 1
                        biaoji = 0
                else:
                    # 判断由下巴过杠到手放直的工作
                    if biaoji == 0 and angle > 150:
                        biaoji = 1
              cv2.putText(img, "pull-up:{}".format(up), (10, 50),
                        cv2.FONT_HERSHEY_PLAIN, 3, (0, 0, 255), 3)
    ​
    def pull_up_check(list):
        """
        判断拉上去和放下来
        拉上去的话:满足下颌超过双手连线并且双手连线基本水平,且手掌是比手肘关节高的
        放下来的话:满足手肘关节角度大于一定程度,这里直接返回角度,在主程序中判断
        # 计算3个点的高度比较值,返回下颌-手部的像素值,分别是9-嘴角,15、16-左右手的手掌
        [9, 11, 13,  15, 16, ]
        """
        hands_top = min(list[3][1],list[4][1]) 
        hands_degree = math.fabs(round(tan_2pots(list[3:5] ) ))
        underjaw = list[0][1] | 0
        angle = round(cal_ang(list[1],list[2],list[3]))
        wrist_gt_elbow = list[2][1] > list[3][1]
        return  hands_top - underjaw ,hands_degree,angle,wrist_gt_elbow
    ​
    def tan_2pots(list):
        """
        #根据两个点的坐标,计算两个点连线的斜率
        """
        return math.atan((list[0][1]-list[1][1]) / (list[0][0] - list[1][0]+ 0.01))*57.3
    ​
    ​
    def cal_ang(point_1, point_2, point_3):
        """
        根据三点坐标计算夹角
        :param point_1: 点1坐标
        :param point_2: 点2坐标
        :param point_3: 点3坐标
        :return: 返回任意角的夹角值,这里只是返回点2的夹角
        """
        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]))
        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]))
        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]))
        # A=math.degrees(math.acos((a*a-b*b-c*c)/(-2*b*c)))
        B=math.degrees(math.acos((b*b-a*a-c*c)/(-2*a*c)))
        # C=math.degrees(math.acos((c*c-a*a-b*b)/(-2*a*b)))
        return B

进一步完善

以上就是主要功能的代码实现,为了使用方便,还要再完善一下,添加几个小功能

  1. 一个开始计数的按钮:不用一直开着;
  2. 一个重置计数的按钮:抢杠或者换人的时候;
  3. 一个暂停计数的按钮:结束的时候,需要暂停,将结果保留下来
  4. 保留最后的结果画面
  5. 便于调试,将一些状态量直接显示在屏幕上

本文是通过绑定键盘按键来设置按钮的,当然,你也可以自行实现,添加在画面中。

按键 功能
crtl+a 暂停
crtl+z 重置
space 暂停/运行
crtl+c 保存当前画面
ctrl+f 退出

这部分是用了keyboard这个库,实现起来也不太复杂,就是控制几个标志变量,代码如下

import keyboard
up = 0
pause = 0
over = 0
active = 0
def key_press(arg):
    print(arg)
    global pause, over,active,up
    if arg == 'pause':
        pause = 1 - pause
    elif arg == 'run':
        pause = 0
    elif arg == 'exit':
        over = 1
    elif arg == 'clear':
        up = 0
    elif arg == 'save':
        cv2.imwrite('.output'+str(time.time())+'.jpg', img)
        
    elif arg == 'active':
        active = 1 - active
# 添加热键
keyboard.add_hotkey(hotkey='space', callback=key_press, args=('pause',))
keyboard.add_hotkey(hotkey='ctrl+z', callback=key_press, args=('clear',))
keyboard.add_hotkey(hotkey='ctrl+f', callback=key_press, args=('exit',))
keyboard.add_hotkey(hotkey='ctrl+a', callback=key_press, args=('active',))
keyboard.add_hotkey(hotkey='ctrl+c', callback=key_press, args=('save',))

测试

从小破站借了两个拉单杠的视频,测试了一下,总的效果还是不错的,主要看pull-up值,就是统计的个数:

AI技术助力单杠训练

结语

这个小应用不算复杂,加上一些辅助代码也只有一百多行,特别适合初学者。这次的分享就到这里,希望能帮助到大家。有兴趣的朋友可以进一步封装成一个软件,可以直接在笔记本上运行,只要外接一个usb摄像头就可以考核啦。

完整的测试视频:测试视频1
测试视频2

代码可以直接拷贝到本地运行测试一下:视频链接:https://code.juejin.cn/pen/7247105201889345594

参考资料

Google for Developers Blog – News about Web, Mobile, AI and Cloud (googleblog.com)

GitHub – google/mediapipe: Cross-platform, customizable ML solutions for live and streaming media.

【姿态估计】MediaPipe部分solution(手势,人体姿态,面部动作)的用法_mp.solutions.pose_Sciengineer-Mike的博客-CSDN博客

python 根据三点坐标计算夹角_python给定三个点求夹角_qq_1096260969的博客-CSDN博客

街健腿毛的个人空间_哔哩哔哩_bilibili

能量轰击的个人空间_哔哩哔哩_bilibili

本网站的内容主要来自互联网上的各种资源,仅供参考和信息分享之用,不代表本网站拥有相关版权或知识产权。如您认为内容侵犯您的权益,请联系我们,我们将尽快采取行动,包括删除或更正。
AI教程

Github Copilot: Revolutionizing AI-assisted Programming

2023-12-17 1:36:14

AI教程

Batch_Normalization的理解与应用

2023-12-17 2:16:14

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索