俯卧撑计数器(Python)

news2024/9/28 19:22:40

 

通过 MediaPipe 检测人体姿态,计算俯卧撑角度和计数,并在图像上进行可视化展示

需要有cv2库和mediapipe库

mediapipe库:

MediaPipe是Google开源的机器学习框架,用于构建实时音频、视频和多媒体处理应用程序。它提供了一组预训练的模型和工具,帮助开发人员快速构建和部署计算机视觉和音频处理应用。MediaPipe库的特点包括实时性能、多平台兼容性、灵活性和易用性。

MediaPipe库的主要功能包括:

1. 视频和图像处理:提供了各种预训练的模型和工具,用于视频流分析和处理,例如人脸检测、姿态估计、手势识别等。

2. 音频处理:提供了模型和工具,用于音频流的实时处理,例如语音识别、语音分割、声音增强等。

3. 数据流图:使用数据流图构建和组合多个模块,以实现复杂的音频、视频和多媒体处理应用程序。

4. 跨平台支持:支持多种平台,包括Android、iOS、Linux、Windows等。

5. 开发者工具:提供了一些工具,用于开发和调试MediaPipe应用程序,例如模型训练和调优、性能分析等。

总之,MediaPipe库是一个功能强大的机器学习框架,用于实时音频、视频和多媒体处理应用程序的开发和部署。它提供了丰富的预训练模型和工具,使开发人员能够快速搭建高性能的应用程序。

目录

定义计算角度的函数:

初始化MediaPipe Pose实例: 

 打开视频:

读取视频帧:

计算个数:

 绘制图像:

完整代码: 

定义计算角度的函数:

def calculate_angle(a, b, c):
    # 将输入点转换为numpy数组
    a = np.array(a)
    b = np.array(b)
    c = np.array(c)

    # 计算两个向量的角度差(弧度)
    radians = np.arctan2(c[1] - b[1], c[0] - b[0]) - np.arctan2(a[1] - b[1], a[0] - b[0])

    # 转换为角度(度)
    angle = np.abs(radians * 180.0 / np.pi)

    # 确保角度在0到360度之间
    if angle > 180.0:
        angle = 360 - angle

    return angle

初始化MediaPipe Pose实例: 

# 初始化MediaPipe Pose实例
pose = mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5)
'''
min_detection_confidence:表示检测到人体姿态的最小置信度阈值。当检测到的姿态置信度低于该阈值时,可能会被视为无效检测。
min_tracking_confidence:表示跟踪人体姿态的最小置信度阈值。在跟踪过程中,如果姿态的置信度低于该阈值,可能会重新进行检测。
'''

 打开视频:

cap = cv2.VideoCapture("D:\\桌面\\1.mp4")

读取视频帧:

ret, frame = cap.read()

计算个数:

 # 尝试获取姿态关键点
    try:
        landmarks = results.pose_landmarks.landmark

        # 获取左肩、左肘和左腕的坐标
        shoulder = [landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].x,
                    landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].y]
        elbow = [landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value].x, landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value].y]
        wrist = [landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value].x, landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value].y]

        # 计算并显示肘部到肩部的角度
        angle = calculate_angle(shoulder, elbow, wrist)
        cv2.putText(image, str(angle),
                    tuple(np.multiply(elbow, [640, 480]).astype(int)),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2, cv2.LINE_AA)
        print(angle)

        # 根据角度更新俯卧撑计数
        if angle > max_angle:
            stage = "down"
        if angle < min_angle and stage == 'down':
            stage = "up"
            counter += 1
            print(counter)

    except:
        pass

 

 绘制图像:

 # 在图像上绘制矩形框,用于显示计数和阶段
    cv2.rectangle(image, (0, 0), (225, 73), (245, 117, 16), -1)

    # 在矩形框内显示计数和阶段
    cv2.putText(image, 'COUNTER', (15, 22),
                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1, cv2.LINE_AA)
    cv2.putText(image, str(counter),
                (35, 60),
                cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA)

    cv2.putText(image, 'STAGE', (135, 22),
                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1, cv2.LINE_AA)
    cv2.putText(image, stage,
                (130, 60),
                cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA)

    # 在图像上绘制关键点和连接线
    mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS,
                              mp_drawing.DrawingSpec(color=(245, 117, 66), thickness=2, circle_radius=2),
                              mp_drawing.DrawingSpec(color=(245, 66, 230), thickness=2, circle_radius=2)
                              )

    # 显示处理后的图像
    cv2.imshow('Mediapipe Feed', image)

    # 检查是否按下'q'键退出
    if cv2.waitKey(10) & 0xFF == ord('q'):
        break

完整代码: 

#coding:utf-8
# 导入必要的库
import cv2
import mediapipe as mp  #通过 MediaPipe 检测人体姿态,计算俯卧撑角度和计数,并在图像上进行可视化展示
import numpy as np
import logging

# 配置日志记录
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# 记录日志信息
logging.info('这是一条信息日志')
logging.warning('这是一条警告日志')
logging.error('这是一条错误日志')

# 定义计算角度的函数
"""
    计算三个点之间的角度

    参数:
    a (list):第一个点的坐标
    b (list):第二个点的坐标
    c (list):第三个点的坐标

    返回:
    float:三个点之间的角度(度)
    """
def calculate_angle(a, b, c):
    # 将输入点转换为numpy数组
    a = np.array(a)
    b = np.array(b)
    c = np.array(c)

    # 计算两个向量的角度差(弧度)
    radians = np.arctan2(c[1] - b[1], c[0] - b[0]) - np.arctan2(a[1] - b[1], a[0] - b[0])

    # 转换为角度(度)
    angle = np.abs(radians * 180.0 / np.pi)

    # 确保角度在0到360度之间
    if angle > 180.0:
        angle = 360 - angle

    return angle

# 导入MediaPipe的绘图工具和Pose解决方案
mp_drawing = mp.solutions.drawing_utils
mp_pose = mp.solutions.pose

# 初始化MediaPipe Pose实例
pose = mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5)
'''
min_detection_confidence:表示检测到人体姿态的最小置信度阈值。当检测到的姿态置信度低于该阈值时,可能会被视为无效检测。
min_tracking_confidence:表示跟踪人体姿态的最小置信度阈值。在跟踪过程中,如果姿态的置信度低于该阈值,可能会重新进行检测。
'''

# 打开视频
cap = cv2.VideoCapture("D:\\桌面\\1.mp4")

# 计数器变量
counter = 0
# 当前动作阶段
stage = None
# 完成俯卧撑的最大角度
max_angle = 160
# 准备开始俯卧撑的最小角度
min_angle = 60

while cap.isOpened():
    # 读取视频帧
    ret, frame = cap.read()

    # BGR图像转为RGB,便于MediaPipe处理
    image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    image.flags.writeable = False

    # 使用MediaPipe进行姿态检测
    results = pose.process(image)

    # 重新转为BGR
    image.flags.writeable = True
    image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)

    # 尝试获取姿态关键点
    try:
        landmarks = results.pose_landmarks.landmark

        # 获取左肩、左肘和左腕的坐标
        shoulder = [landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].x,
                    landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].y]
        elbow = [landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value].x, landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value].y]
        wrist = [landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value].x, landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value].y]

        # 计算并显示肘部到肩部的角度
        angle = calculate_angle(shoulder, elbow, wrist)
        cv2.putText(image, str(angle),
                    tuple(np.multiply(elbow, [640, 480]).astype(int)),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2, cv2.LINE_AA)
        print(angle)

        # 根据角度更新俯卧撑计数
        if angle > max_angle:
            stage = "down"
        if angle < min_angle and stage == 'down':
            stage = "up"
            counter += 1
            print(counter)

    except:
        pass

    # 在图像上绘制矩形框,用于显示计数和阶段
    cv2.rectangle(image, (0, 0), (225, 73), (245, 117, 16), -1)

    # 在矩形框内显示计数和阶段
    cv2.putText(image, 'COUNTER', (15, 22),
                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1, cv2.LINE_AA)
    cv2.putText(image, str(counter),
                (35, 60),
                cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA)

    cv2.putText(image, 'STAGE', (135, 22),
                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1, cv2.LINE_AA)
    cv2.putText(image, stage,
                (130, 60),
                cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA)

    # 在图像上绘制关键点和连接线
    mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS,
                              mp_drawing.DrawingSpec(color=(245, 117, 66), thickness=2, circle_radius=2),
                              mp_drawing.DrawingSpec(color=(245, 66, 230), thickness=2, circle_radius=2)
                              )

    # 显示处理后的图像
    cv2.imshow('Mediapipe Feed', image)

    # 检查是否按下'q'键退出
    if cv2.waitKey(10) & 0xFF == ord('q'):
        break

# 释放视频资源,关闭所有OpenCV窗口
cap.release()
cv2.destroyAllWindows()

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

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

相关文章

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 7月9日,星期二

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年7月9日 星期二 农历六月初四 1、 最高检&#xff1a;对小摊小贩、小微企业处以高额罚款不符合法律精神。 2、 公安部&#xff1a;全国机动车保有量达4.4亿辆&#xff0c;驾驶人达5.32亿人。 3、 科技部&#xff1a;严禁将…

Echarts:渲染成Canvas还是SVG,该如何抉择?

ECharts 从初始一直使用 Canvas 绘制图表。而 ECharts v4.0 发布了 SVG 渲染器&#xff0c;从而提供了一种新的选择。在初始化图表实例时&#xff0c;只需设置 renderer 参数 为 canvas 或 svg 即可指定渲染器&#xff0c;比较方便。贝格前端工场带领大家看下如何选择。 一、C…

2024年【低压电工】最新解析及低压电工复审考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 低压电工最新解析根据新低压电工考试大纲要求&#xff0c;安全生产模拟考试一点通将低压电工模拟考试试题进行汇编&#xff0c;组成一套低压电工全真模拟考试试题&#xff0c;学员可通过低压电工复审考试全真模拟&…

为什么要学习Go?

目录 前言 一、Go 语言的发展史 Robert Griesemer Rob Pike Ken Thompson 二、Go语言全面分析 主要优势 主要挑战 三、Go 语言最佳实践 1. 云原生开发 2. 网络服务开发 3. 系统工具和实用程序 4. 数据处理和分析 四、哪些知名公司使用 Go 语言&#xff1f; Google …

16 - Python语言进阶

Python语言进阶 数据结构和算法 算法&#xff1a;解决问题的方法和步骤 评价算法的好坏&#xff1a;渐近时间复杂度和渐近空间复杂度。 渐近时间复杂度的大O标记&#xff1a; - 常量时间复杂度 - 布隆过滤器 / 哈希存储 - 对数时间复杂度 - 折半查找&#xff08;二分查找&am…

重点区域分布式无人机探测防御系统详解

重点区域分布式无人机探测防御系统采用模块化设计&#xff0c;结合先进的传感技术、通信技术和数据处理技术&#xff0c;实现对无人机的高效探测与防御。系统架构由无人机探测模块、数据分析中心、防御与反制模块以及用户交互界面四大部分组成。系统特点包括分布式部署、高灵敏…

在audio DSP中如何做软件固化

在audio DSP中&#xff0c; 软件的code和data主要放在3种不同的memory上&#xff0c;分别是片内的ITCM、DTCM和片外的memory&#xff08;比如DDR&#xff09;上。ITCM只能放code&#xff0c;DTCM只能放data&#xff0c;片外的memory既能放code也能放data。在写代码时要规划好哪…

【Java开发实训】day01

目录 1.Java开发步骤 2.目录的三个表达方法 3.Java的三种注释方法 4.文档注释的作用 &#x1f308;嗨&#xff01;我是Filotimo__&#x1f308;。很高兴与大家相识&#xff0c;希望我的博客能对你有所帮助。 &#x1f4a1;本文由Filotimo__✍️原创&#xff0c;首发于CSDN&…

UML中用例之间的可视化表示

用例除了与参与者有关联关系外&#xff0c;用例之间也存在着一定的关系&#xff0c;如泛化关系、包含关系、扩展关系等。 4.2.1 包含关系 包含关系指的是两个用例之间的关系&#xff0c;其中一个用例&#xff08;称为基本用例&#xff0c;Base Use Case&#xff09;的行为包…

从零开始读RocketMq源码(二)Message的发送详解

目录 前言 准备 消息发送方式 深入源码 消息发送模式 选择发送方式 同步发送消息 校验消息体 获取Topic订阅信息 高级特性-消息重投 选择消息队列-负载均衡 装载消息体发送消息 压缩消息内容 构造发送message的请求的Header 更新broker故障信息 异步发送消息 …

根据空格、制表符、回车符等分割字符串re.split

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 根据空格、制表符、 回车符等分割字符串 re.split [太阳]选择题 根据给定的Python代码&#xff0c;哪个选项是正确的&#xff1f; import re pattern r\s print(f"【显示】pattern{…

软件工程面向对象 超市管理系统 需求分析 系统设计 课程设计报告

1、引言 系统简述 超市管理系统的功能主要有前台管理和后台管理两个大块。其使用对象 有超市管理人员和超市销售人员两类。超市管理系统主要为了实现商品输 入、 输出管理数据的自动化&#xff0c; 提高商品统计信息的实时性&#xff0c; 减轻人工劳动强 度从而节省人力成本。实…

国产操作系统安装配置auditd审计工具 _ 统信 _ 麒麟 _ 中科方德

原文链接&#xff1a;国产操作系统安装配置auditd审计工具 | 统信 | 麒麟 | 中科方德 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇在国产桌面操作系统上部署auditd审计工具的文章。auditd是Linux审计系统的核心守护进程&#xff0c;用于记录系统安全相关的事件和…

Java根据经纬度获取两点之间的距离

Java根据经纬度获取两点之间的距离&#xff0c;最近在实现类似于钉钉打卡签到的需求&#xff0c;因为对精度要求不是很高&#xff0c;所以可以通过一个球面距离的公式来求两点距离&#xff0c;这里将地球当成一个球体&#xff0c;实际上地球是一个不规则的球体&#xff0c;所以…

14-22 剑和远方2 - 深度神经网络中的学习机制

概论 在第一部分中&#xff0c;我们深入探讨了人工智能的兴衰简史以及推动人工智能发展的努力。我们研究了一个简单的感知器&#xff0c;以了解其组件以及简单的 ANN 如何处理数据和权重层。在简单的 ANN 中&#xff0c;不会对数据执行特定操作。ANN 中的激活函数是一个线性函…

模拟考试小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;科目管理&#xff0c;复习资料管理&#xff0c;参考文献管理&#xff0c;用户管理&#xff0c;留言板管理&#xff0c;论坛管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;复习资料&#xf…

搭建ASP+Mssql站点

SQL Server 2022 链接&#xff1a;https://pan.baidu.com/s/1U2zkXacbjOVNsAq-JQ80tA?pwdgosm 提取码&#xff1a;gosm MSSQLi-labs 链接&#xff1a;https://pan.baidu.com/s/1K6rCIaeSzaBBtQKD9Uk1fw?pwdveyn 提取码&#xff1a;veyn SQL Server 2022下载安装 安装成功…

【前端从入门到精通:第十一课: JS基本语法】

独闯JavaScript 了解JavaScript 为什么学习JavaScript JavaScript 是 web 开发者必学的三种语言之一&#xff1a; HTML 定义网页的内容 CSS 规定网页的布局 JavaScript 对网页行为进行编程 我们学习 JavaScript&#xff0c;以及 JavaScript 如何与 HTML 和 CSS 协同工作的知…

重大更新!800GB谷歌倾斜摄影最新OSGB数据免费大放送

自3月20日谷歌倾斜摄影OSGB转换工具V0.1版本发布以来&#xff0c;期间更新了V0.2、V1.0、V1.1、V1.2共4个版本&#xff0c;目前V1.2版本功能已经比较完善和稳定&#xff0c;实现了的当初产品规划的绝大部分功能。基于此&#xff0c;我将之前免费分享的数据重新下载和生成&#…

MyBatis框架学习笔记(二):原生API 的调用 和 注解的使用

1 MyBatis原生API 1.1 原生API 快速入门需求 在笔记一案例的基础上将增删改查&#xff0c;使用 MyBatis 原生的 API 完成&#xff0c;就是直接通过SqlSession 接口的方法来完成 1.2 原生API 快速入门-代码实现 创建 src\test\java\com\hspedu\mapper\MyBatisNativeTest.jav…