Python玩人工智能:你的俯卧撑做对了吗?

news2025/1/16 7:59:46

1. 准备工作

1.1 安装Python3.8.x

1.2 安装PyCharm社区版

1.3 创建项目

1.4 安装项目使用工具包

1.1 下载安装Python3.8.x版本

首先我们的电脑上要安装Python3.8.x。Python 3.8.x : https://www.python.org/downlo...

1.2 下载安装PyCharm社区版

PyCharm: https://www.jetbrains.com/pyc... 当然你也可以使用自己喜欢的IDE。

1.3 创建一个Python项目

安装好Python和PyCharm之后,我们可以启动PyCharm,创建一个新的Python项目。选择项目的存储位置,创建项目时,可以让PyCharm帮忙创建一个虚拟环境(virtualenv),虚拟环境可以理解为这个项目专属的编程环境,不会影响其他的项目。

1.4 安装项目所用的工具包

项目创建好之后,我们打开PyCharm的Terminal窗口,在这里我们可以输入以下命令来安装这个项目所需要的工具包:opencv-python mediapipe numpy pyautogui。下面的命令会从网络上下载工具包并安装,如果你看到最后有“Successfully installed...”这样的英文,表示安装成功了。

pip install opencv-python mediapipe numpy

也可以点开PyCharm的设置,看到项目的Python环境中,是否有以上的工具包,如果有就表示安装成功了。

2. 编写程序

2.1 创建poseutil.py模块

2.2 编写pushup.py

2.3 测试运行

2.1 创建poseutil.py模块

创建一个新的Python文件,取名为poseutil.py,这是我们创建的姿势识别的模块,在这个模块中有一个PoseDetector的姿势识别器类,使用它可以识别人体姿势、获取人体姿势数据以及计算人体姿势相关点的角度。

import cv2
import mediapipe as mp
import math

class PoseDetector():
    '''
    人体姿势检测类
    '''

    def __init__(self,
                 static_image_mode=False,
                 upper_body_only=False,
                 smooth_landmarks=True,
                 min_detection_confidence=0.5,
                 min_tracking_confidence=0.5):
        '''
        初始化
        :param static_image_mode: 是否是静态图片,默认为否
        :param upper_body_only: 是否是上半身,默认为否
        :param smooth_landmarks: 设置为True减少抖动
        :param min_detection_confidence:人员检测模型的最小置信度值,默认为0.5
        :param min_tracking_confidence:姿势可信标记的最小置信度值,默认为0.5
        '''
        self.static_image_mode = static_image_mode
        self.upper_body_only = upper_body_only
        self.smooth_landmarks = smooth_landmarks
        self.min_detection_confidence = min_detection_confidence
        self.min_tracking_confidence = min_tracking_confidence
        # 创建一个Pose对象用于检测人体姿势
        self.pose = mp.solutions.pose.Pose(self.static_image_mode, self.upper_body_only, self.smooth_landmarks,
                                           self.min_detection_confidence, self.min_tracking_confidence)

    def find_pose(self, img, draw=True):
        '''
        检测姿势方法
        :param img: 一帧图像
        :param draw: 是否画出人体姿势节点和连接图
        :return: 处理过的图像
        '''
        imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        # pose.process(imgRGB) 会识别这帧图片中的人体姿势数据,保存到self.results中
        self.results = self.pose.process(imgRGB)
        if self.results.pose_landmarks:
            if draw:
                mp.solutions.drawing_utils.draw_landmarks(img, self.results.pose_landmarks,
                                                          mp.solutions.pose.POSE_CONNECTIONS)
        return img

    def find_positions(self, img):
        '''
        获取人体姿势数据
        :param img: 一帧图像
        :param draw: 是否画出人体姿势节点和连接图
        :return: 人体姿势数据列表
        '''
        # 人体姿势数据列表,每个成员由3个数字组成:id, x, y
        # id代表人体的某个关节点,x和y代表坐标位置数据
        self.lmslist = []
        if self.results.pose_landmarks:
            for id, lm in enumerate(self.results.pose_landmarks.landmark):
                h, w, c = img.shape
                cx, cy = int(lm.x * w), int(lm.y * h)
                self.lmslist.append([id, cx, cy])

        return self.lmslist

    def find_angle(self, img, p1, p2, p3, draw=True):
        '''
        获取人体姿势中3个点p1-p2-p3的角度
        :param img: 一帧图像
        :param p1: 第1个点
        :param p2: 第2个点
        :param p3: 第3个点
        :param draw: 是否画出3个点的连接图
        :return: 角度
        '''
        x1, y1 = self.lmslist[p1][1], self.lmslist[p1][2]
        x2, y2 = self.lmslist[p2][1], self.lmslist[p2][2]
        x3, y3 = self.lmslist[p3][1], self.lmslist[p3][2]

        # 使用三角函数公式获取3个点p1-p2-p3,以p2为角的角度值,0-180度之间
        angle = int(math.degrees(math.atan2(y1 - y2, x1 - x2) - math.atan2(y3 - y2, x3 - x2)))
        if angle < 0:
            angle = angle + 360
        if angle > 180:
            angle = 360 - angle

        if draw:
            cv2.circle(img, (x1, y1), 20, (0, 255, 255), cv2.FILLED)
            cv2.circle(img, (x2, y2), 30, (255, 0, 255), cv2.FILLED)
            cv2.circle(img, (x3, y3), 20, (0, 255, 255), cv2.FILLED)
            cv2.line(img, (x1, y1), (x2, y2), (255, 255, 255, 3))
            cv2.line(img, (x2, y2), (x3, y3), (255, 255, 255, 3))
            cv2.putText(img, str(angle), (x2 - 50, y2 + 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 255, 255), 2)

        return angle
    

2.2 编写pushup.py

编写下面的代码,调用poseutil模块,获取人体姿势数据,并计算人体中肩膀、臀部、膝盖三个点以及肩膀、手肘、手腕构成的角度,通过这2个角度来判断俯卧撑是否标准。

# 导入opencv工具包
import cv2
# 导入numpy
import numpy as np
# 导入姿势识别器
from poseutil import PoseDetector

# 打开视频文件
cap = cv2.VideoCapture('videos/pushup.mp4')
# 姿势识别器
detector = PoseDetector()

# 方向与个数
dir = 0  # 0为下,1为上
count = 0

# 视频宽度高度
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# 录制视频设置
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('videos/pushupoutput.mp4', fourcc, 30.0, (width, height))

while True:
    # 读取摄像头,img为每帧图片
    success, img = cap.read()
    if success:
        h, w, c = img.shape
        # 识别姿势
        img = detector.find_pose(img, draw=True)
        # 获取姿势数据
        positions = detector.find_positions(img)

        if positions:
            # 获取俯卧撑的角度
            angle1 = detector.find_angle(img, 12, 24, 26)
            angle2 = detector.find_angle(img, 12, 14, 16)
            # 进度条长度
            bar = np.interp(angle2, (45, 150), (w // 2 - 100, w // 2 + 100))
            cv2.rectangle(img, (w // 2 - 100, h - 150), (int(bar), h - 100), (0, 255, 0), cv2.FILLED)
            # 角度小于50度认为撑下
            if angle2 <= 50 and angle1 >= 165 and angle1 <= 175:
                if dir == 0:
                    count = count + 0.5
                    dir = 1
            # 角度大于125度认为撑起
            if angle2 >= 125 and angle1 >= 165 and angle1 <= 175:
                if dir == 1:
                    count = count + 0.5
                    dir = 0
            cv2.putText(img, str(int(count)), (w // 2, h // 2), cv2.FONT_HERSHEY_SIMPLEX, 10, (255, 255, 255), 20, cv2.LINE_AA)

        # 打开一个Image窗口显示视频图片
        cv2.imshow('Image', img)

        # 录制视频
        out.write(img)
    else:
        # 视频结束退出
        break

    # 如果按下q键,程序退出
    key = cv2.waitKey(1)
    if key == ord('q'):
        break

# 关闭视频保存器
out.release()
# 关闭摄像头
cap.release()
# 关闭程序窗口
cv2.destroyAllWindows()

2.3 测试运行

在实际运行测试时,我们设置的俯卧撑角度是50度到125度之间,可以根据拍摄角度来调整,另外我们要求臀部角度在165度到175度之间,这个也是可以调整的。建议拍摄视频或者使用摄像头时更多的放在人体的侧上部分,这样检测的会比较准确。

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/156004.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

远程办公与Web3内核高度匹配 将重塑全球劳动力市场格局?

在过去两年半的时间里&#xff0c;全球有45%的工作转为了远程办公模式&#xff0c;不过即使疫情好转&#xff0c;大城市的办公室入驻率仍低于疫情前50%的水平。 这表明&#xff0c;现在越来越多的人更喜欢远程工作的生活方式。“远程办公”从疫情期间的无奈选择&#xff0c;正在…

java基于ssm框架的企业人事管理系统企业工资考勤系统

简介 Java基于ssm开发的企业人事考勤工资系统&#xff0c;员工可以打卡、请假。系统根据员工的打卡情况自动计算工资&#xff08;全勤、请假、旷工、加班、迟到、早退等计算出最终实发工资&#xff09;&#xff0c;员工还可以查看自己的考勤记录工资具体组成等。升级版加了部长…

jedis是什么,为什么是线程不安全的

常用的操作redis的客户端工具 jedis Jedis 是 Redis 官方推荐的 Java 连接开发工具&#xff0c;jedis非线程安全。 但是可以通过JedisPool连接池去管理实例&#xff0c;在多线程情况下让每个线程有自己独立的jedis实例&#xff0c;可变为线程安全。 Lettuce Lettuce 是基于…

嵌入式实时操作系统的设计与开发(七)

内存管理机制 内存管理就是把物理的存储资源用一定的规则和手段管理起来&#xff0c;以供给操作系统和应用程序使用。 主要的操作&#xff1a;内存的分配和内存的回收。 内存的利用率、分配回收的效率和稳定性成为了评价内存管理模块的主要依据。 内存分配又包括静态和动态两种…

Pinely Round 1 (Div. 1 + Div. 2) A. Two Permutations

来写一道*800的题&#xff0c;思路很简单&#xff0c;就是这道题我们应该怎么去严谨地思考Problem - 1761A - Codeforces思路&#xff1a;结论题的分类讨论一定要不重不漏一开始很容易想到&#xff0c;前缀和后缀不能有重合那么有重合部分就判No没有重合的情况&#xff1a;隔1个…

Linux常用命令——xz命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) xz POSIX 平台开发具有高压缩率的工具。 补充说明 xz命令XZ Utils 是为 POSIX 平台开发具有高压缩率的工具。它使用 LZMA2 压缩算法&#xff0c;生成的压缩文件比 POSIX 平台传统使用的 gzip、bzip2 生成的压缩…

多线程进阶(二)Callable接口,JUC下常见类使用及线程安全集合类

目录 前言&#xff1a; Callable接口 代码实现 JUC下常见类使用 ReentrantLock类 代码实现 信号量 代码实现 CountDownLatch类 代码实现 线程安全的集合类 多线程环境下使用ArrayList 多线程环境下使用队列 多线程环境下使用哈希表 小结&#xff1a; 前言&#…

图解24种经典k线图

相信不少国内的老股民心中都藏着一份经典的K线图图解&#xff0c;当中也许有6种、12种或24种能揭示行情方向转变的“K线脸谱”&#xff0c;借由它们的对行情的预知作用&#xff0c;股民度过一次又一次的熊牛更替。其实只要善于变通&#xff0c;它们同样适用于贵金属投资&#x…

再说多线程(一)

世界是并行&#xff01;做过复杂项目的朋友一定遇到过并发的问题&#xff0c;无论是大项目如订票系统&#xff0c;还是小项目中的文件管理都会有并行需求。所以不同于上学时接触的大部分代码&#xff0c;实际的业务往往是为多人提供服务&#xff0c;必然天然的带有并发的需求。…

Mybatis-plus 使用 typeHandler 将 String 拼接字符串转换为 List 列表

一、需求描述 首先说明需求&#xff0c;有三张表&#xff1a; 学生表、角色表、以及一张关联的中间表。 学生可以有多个角色&#xff0c;但是这多个角色我是作为多条记录存储在另外一张表中的&#xff0c;现在想将这多条记录查询出来&#xff0c;注入到Student对象中的一个L…

微服务之JVM调优

一、Xms Xmx Xss等定义及功能 1.Xms 是指设定程序启动时占用内存大小。一般来讲,大点,程序会启动的快一点,但是也可能会导致机器暂时间变慢。 2.Xmx 是指设定程序运行期间最大可占用的内存大小。如果程序运行需要占用更多的内存,超出了这个设置值,就会抛出OutOfMemory异…

易基因|14种全基因组DNA甲基化测序(WGBS)标准分析比对软件的比较| 生信专区

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。全基因组重亚硫酸盐测序&#xff08;WGBS&#xff09;是甲基化研究的重要技术。尽管已经开发了一系列工具来解决由亚硫酸盐处理引起的比对问题&#xff0c;但尚未对最新可用工具的reads比对…

HashMap,Hashtable,ConcurrentHashMap

目录 一、多线程使用HashMap的一些线程安全问题 ①造成数据新增丢失 ②扩容时候&#xff0c;造成链表成环 二、Hashtable和HashMap的区别 ①核心方法加锁 ②其他语法上面的略微差异 三、引入ConcurrentHashMap【重要】 ①ConcurrentHashMap相比于Hashtable的优势 Hashtab…

著名相声艺术家侯耀华,77岁寿宴现场曝光,郭德纲师哥前去祝贺

在中国的相声界&#xff0c;有一条不成文的规定&#xff0c;关于著名相声表演艺术家的判定&#xff0c;从来不是以相声水平高低为标准。只要你有足够长的寿命&#xff0c;只要你能把其他人都熬走熬败&#xff0c;就算你是一个相声小白&#xff0c;也能摇身一变成为艺术家。 不过…

Git介绍与使用

1.集中式版本控制 svn 中央服务器 所有的版本数据都存在服务器上&#xff0c;用户本地只有自己所同步的版本&#xff0c;如果不联网的话&#xff0c;用户就看不到 SVN是集中式版本控制系统&#xff0c;版本库是集中放在中央服务器的 而工作的时候,用的都是自己的电脑,所以首先…

跨境电商物流系统功能框架

随着国内互联网巨头们逐渐将更多注意力投向了跨境电商市场&#xff0c;电商巨头出海也在掀起新的发展高潮。下面是跨境电商物流系统功能框架&#xff0c;供大家参考1、OMS叫做订单管理系统&#xff08;Order Management System&#xff09;&#xff0c;在不同公司&#xff0c;不…

云原生时代的运维体系进化

云原生已经成为数字经济技术的创新基石&#xff0c;并且正在深刻地改变企业上云和用云的方式。云原生的用云方式可以帮助企业最大化获得云价值&#xff0c;也给企业的计算基础设施、应用架构、组织文化和研发流程带来新一轮变革。而业务和技术挑战也催生了新一代云原生运维技术…

设计模式(一)----设计模式概述及UML图解析

1、设计模式概述 1.1 软件设计模式的产生背景 "设计模式"最初并不是出现在软件设计中&#xff0c;而是被用于建筑领域的设计中。 1977年美国著名建筑大师、加利福尼亚大学伯克利分校环境结构中心主任克里斯托夫亚历山大&#xff08;Christopher Alexander&#xf…

Golang开发 02

文章目录一、Golang开发工具二、visual studio code安装(VS code)1、安装window2、安装mac、linux一、Golang开发工具 # 1、Visual studio code &#xff08;常用&#xff09; # 2、Sublime Text(免费) # 3、Vim # 4、Emacs # 5、Eclipes IDE工具&#xff0c;开源免费&#xf…

数据分析-深度学习PytorchDay1

深度学习框架pytorch学习(一)准备环境准备环境一、深度学习框架简介二、Tensorflow与Pytorch的比较三、安装开发环境一、深度学习框架简介1、Google阵营最早的是由加拿大团队开发的theano一个机器学习库&#xff0c;现在已经停止更新。接着Google开发了Tensorflow&#xff0c;并…