俯卧撑计数器(Python)
通过 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 - anglereturn 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 += 1print(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 - anglereturn 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 = 60while 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)# 重新转为BGRimage.flags.writeable = Trueimage = 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 += 1print(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()
相关文章:

俯卧撑计数器(Python)
通过 MediaPipe 检测人体姿态,计算俯卧撑角度和计数,并在图像上进行可视化展示 需要有cv2库和mediapipe库 mediapipe库: MediaPipe是Google开源的机器学习框架,用于构建实时音频、视频和多媒体处理应用程序。它提供了一组预训练的…...
UVA12342 Tax Calculator 题解
题目传送门 题目大意 题目描述 某国所得税计算十分复杂。该国政府指定你制作一个自动计算所得税的程序。以下是该国计算所得税的规则: 所得税免征额为 180000 180000 180000 元。应纳税额中不超过 300000 300000 300000 元的所得额,按 10 % 10\% …...
WebKit中Websockets的全面支持:实现高效实时通信
WebKit中Websockets的全面支持:实现高效实时通信 Websockets是一种网络通信协议,它允许在单个TCP连接上进行全双工通信,从而实现服务器与客户端之间的实时数据交换。WebKit作为许多流行浏览器的底层引擎,对Websockets提供了全面的…...

微信小程序的智慧物流平台-计算机毕业设计源码49796
目 录 摘要 1 绪论 1.1 研究背景 1.2 研究意义 1.3研究方法 1.4开发技术 1.4.1 微信开发者工具 1.4.2 Node.JS框架 1.4.3 MySQL数据库 1.5论文结构与章节安排 2系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 用户登录流程 2.2.2 数据删除流程 2.3 系统功能分…...
旅游 | 西岳华山
得到了再失去, 总比从来没有得到更伤人。 ——胡赛尼《追风筝的人》 目录 旅游 | 西岳华山00 | 旅游导图01 | 旅游路线1.1 北上西下(徒步)1.2 北上西下(索道)1.3 西上北下(索道)1.4 西上西下&am…...
如何优化Java中的内存占用?
如何优化Java中的内存占用? 大家好,我是微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 1. 理解Java内存管理机制 Java的内存管理主要由JVM负责,开发人员在编写代码时需要注意如何有效地…...

2024这三家上海闵行装修公司,值得一看
在繁华的上海闵行区,随着居民对生活品质追求的提升,越来越多人开始重视居住环境的打造。然而,面对众多装修公司的选择,不少消费者往往感到迷茫和困惑。今天,我们就来揭晓闵行区口碑与实力兼备的三家装修公司。 1、首先…...

K8S学习教程(三):在PetaExpress KubeSphere 容器部署 Wiki 系统 wiki.js 并启用中文全文检索
背景 wiki.js 是非常优秀的开源 Wiki 系统,尽管在与 xwiki 功能相比 ,还不算完善,但也在不断进步。 常用的功能还是比较实用的,如:Wiki 写 作、分享、权限管理功能还是非常实用的,UI 设计非常的漂亮&#x…...
服务器该如何抵御CC攻击
CC攻击也是分布式拒绝服务攻击的一种类型,同时CC攻击也属于网络流量攻击,但是CC攻击主要是用来攻击网站页面的,向着目标网络服务器发送一些请求,以此来消耗目标网络服务器的资源,导致目标服务器无法响应正常请求&#…...

关于centos7自带的nginx1.20.1开启https后,XP系统的IE6和IE8无法显示网页的问题
CentOS7自带的nginx-1.20.1是支持HTTP/2和TLS1.3的。 软件包名称:nginx-1.20.1-10.el7.x86_64 CentOS7默认开启了HTTP/2,但没有开启TLS1.3,以及IE6和IE8的https访问。 开启方法: ssl_ciphers HIGH:!aNULL:!MD5;改为ssl_ciphers…...

Zotero软件翻译插件Translate for Zotero的API接入方法--百度垂直领域翻译
首先注册通用文本翻译API的token:百度翻译开放平台 (baidu.com)(可以免费认证 升级为高级版) 之后点击管理控制台,选择总览右侧最下方可以看到个人的id和密码 点击文档与支持, 在这里可以选择领域。 支持传入值描述支持语言方向…...

python实现接口自动化
代码实现自动化相关理论 代码编写脚本和工具实现脚本区别是啥? 代码: 优点:代码灵活方便缺点:学习成本高 工具: 优点:易上手缺点:灵活度低,有局限性。 总结: 功能脚本:工…...
如何提问 如何回答
如何提问 如何回答 如何提出一个好问题 1、选择合适的平台或专家:选择合适的论坛,或者能够给你答案的地方或者人 2、清晰描述问题背景:描述问题的背景,清楚明确地表达你的问题以及需求,不需要加过多的语气助词&#…...

计算机图形学入门26:高级光线传播
1.有偏与无偏 在做光线追踪很多方法都是用蒙特卡洛积分去估计,蒙特卡洛积分有些是无偏的(Unbiased),所谓无偏估计就是无论使用多少个样品,所估计的期望值都是正确的。那么,所有其他情况都是有偏的(Biased),就是估计的期…...

STM32蓝牙HID实战:打造低功耗、高性能的客制化键盘
一、项目概述 本项目旨在使用STM32单片机打造一款功能强大的蓝牙客制化键盘,它拥有以下特点: 九键布局,小巧便携: 满足日常使用需求,方便携带。全键可编程: 所有按键和旋钮均可通过电脑软件自定义快捷键,实现个性化功…...
C++ STL容器:序列式容器-队queue,deque
摘要: CC STL(Standard Template Library,标准模板库)在C编程中的重要性不容忽视,STL提供了一系列容器、迭代器、算法和函数对象,这些组件极大地提高了C程序的开发效率和代码质量。 STL 容器 分为 2 大类 …...
简谈设计模式之单例模式
上一篇博客已经介绍了设计模式及其设计原则, 在这篇博客中笔者会介绍一下单例模式, 也是最简单的一种设计模式 单例模式 单例模式属于创建型模式. 它涉及到一个单一的类, 该类负责创建自己的对象, 同时确保只有单个对象被创建, 这个类提供了一种访问其唯一对象的方式, 可以直…...
在Spring Boot中实现多线程任务调度
在Spring Boot中实现多线程任务调度 大家好,我是微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 1. Spring Boot中的任务调度 Spring Boot通过集成Spring框架的Task Execution和Scheduling支持,提供…...
dify/api/models/account.py文件中的数据表
源码位置:dify\api\models\account.py accounts 表结构 字段英文名数据类型字段中文名字备注idStringUUIDIDnameString名称emailString邮箱passwordString密码password_saltString密码盐avatarString头像interface_languageString界面语言interface_themeString界…...
SQLAlchemy迁移数据库
SQLAlchemy迁移数据库 目录 SQLAlchemy迁移数据库安装Alembic配置Alembic编辑 alembic.ini编辑env.py生成迁移文件建表语句示例修改迁移文件命名格式 安装Alembic pip install alembic配置Alembic 执行初始化后会创建一个 alembic 目录,包含Alembic的配置文件 ale…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...

Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...