《博主简介》
小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。
✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~
👍感谢小伙伴们点赞、关注!
《------往期经典推荐------》
一、AI应用软件开发实战专栏【链接】
项目名称 | 项目名称 |
---|---|
1.【人脸识别与管理系统开发】 | 2.【车牌识别与自动收费管理系统开发】 |
3.【手势识别系统开发】 | 4.【人脸面部活体检测系统开发】 |
5.【图片风格快速迁移软件开发】 | 6.【人脸表表情识别系统】 |
7.【YOLOv8多目标识别与自动标注软件开发】 | 8.【基于YOLOv8深度学习的行人跌倒检测系统】 |
9.【基于YOLOv8深度学习的PCB板缺陷检测系统】 | 10.【基于YOLOv8深度学习的生活垃圾分类目标检测系统】 |
11.【基于YOLOv8深度学习的安全帽目标检测系统】 | 12.【基于YOLOv8深度学习的120种犬类检测与识别系统】 |
13.【基于YOLOv8深度学习的路面坑洞检测系统】 | 14.【基于YOLOv8深度学习的火焰烟雾检测系统】 |
15.【基于YOLOv8深度学习的钢材表面缺陷检测系统】 | 16.【基于YOLOv8深度学习的舰船目标分类检测系统】 |
17.【基于YOLOv8深度学习的西红柿成熟度检测系统】 | 18.【基于YOLOv8深度学习的血细胞检测与计数系统】 |
19.【基于YOLOv8深度学习的吸烟/抽烟行为检测系统】 | 20.【基于YOLOv8深度学习的水稻害虫检测与识别系统】 |
21.【基于YOLOv8深度学习的高精度车辆行人检测与计数系统】 | 22.【基于YOLOv8深度学习的路面标志线检测与识别系统】 |
23.【基于YOLOv8深度学习的智能小麦害虫检测识别系统】 | 24.【基于YOLOv8深度学习的智能玉米害虫检测识别系统】 |
25.【基于YOLOv8深度学习的200种鸟类智能检测与识别系统】 | 26.【基于YOLOv8深度学习的45种交通标志智能检测与识别系统】 |
27.【基于YOLOv8深度学习的人脸面部表情识别系统】 | 28.【基于YOLOv8深度学习的苹果叶片病害智能诊断系统】 |
29.【基于YOLOv8深度学习的智能肺炎诊断系统】 | 30.【基于YOLOv8深度学习的葡萄簇目标检测系统】 |
31.【基于YOLOv8深度学习的100种中草药智能识别系统】 | 32.【基于YOLOv8深度学习的102种花卉智能识别系统】 |
33.【基于YOLOv8深度学习的100种蝴蝶智能识别系统】 | 34.【基于YOLOv8深度学习的水稻叶片病害智能诊断系统】 |
35.【基于YOLOv8与ByteTrack的车辆行人多目标检测与追踪系统】 | 36.【基于YOLOv8深度学习的智能草莓病害检测与分割系统】 |
37.【基于YOLOv8深度学习的复杂场景下船舶目标检测系统】 | 38.【基于YOLOv8深度学习的农作物幼苗与杂草检测系统】 |
39.【基于YOLOv8深度学习的智能道路裂缝检测与分析系统】 | 40.【基于YOLOv8深度学习的葡萄病害智能诊断与防治系统】 |
41.【基于YOLOv8深度学习的遥感地理空间物体检测系统】 | 42.【基于YOLOv8深度学习的无人机视角地面物体检测系统】 |
43.【基于YOLOv8深度学习的木薯病害智能诊断与防治系统】 | 44.【基于YOLOv8深度学习的野外火焰烟雾检测系统】 |
45.【基于YOLOv8深度学习的脑肿瘤智能检测系统】 | 46.【基于YOLOv8深度学习的玉米叶片病害智能诊断与防治系统】 |
47.【基于YOLOv8深度学习的橙子病害智能诊断与防治系统】 | 48.【车辆检测追踪与流量计数系统】 |
49.【行人检测追踪与双向流量计数系统】 | 50.【基于YOLOv8深度学习的反光衣检测与预警系统】 |
51.【危险区域人员闯入检测与报警系统】 |
二、机器学习实战专栏【链接】,已更新31期,欢迎关注,持续更新中~~
三、深度学习【Pytorch】专栏【链接】
四、【Stable Diffusion绘画系列】专栏【链接】
五、YOLOv8改进专栏【链接】,持续更新中~~
六、YOLO性能对比专栏【链接】,持续更新中~
引言
本文主要是基于OpenCV+MediaPipe实现了视频与摄像头中人体俯卧撑实时计数。附完整源码与实现步骤讲解,供小伙伴们学习。感谢大家的点赞关注,更多干活内容持续更新~
实现效果
详细实现步骤讲解
1.导入必要的库
import cv2
import mediapipe as mp
import numpy as np
- cv2:OpenCV库,用于视频处理和图像显示。
- mediapipe:Google开发的用于处理媒体数据的跨平台解决方案。
- numpy:用于科学计算的库,这里用于处理坐标和角度计算。
2.定义计算角度的函数
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
这个函数接收三个点的坐标,计算这三个点构成的夹角,并返回角度值。
3.初始化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)
这部分代码导入MediaPipe的绘图工具和Pose解决方案,并创建一个Pose对象,用于处理姿态检测。
4.开始视频流处理
cap = cv2.VideoCapture('01.mp4')
创建一个VideoCapture对象,从指定的视频文件中读取帧。
5. 初始化俯卧撑计数器变量
counter = 0
stage = None
max_angle = 160
min_angle = 60
定义了用于记录俯卧撑次数的counter,以及当前动作阶段stage,以及判断俯卧撑完成的最小和最大角度阈值。
6. 主循环,处理每一帧视频
while cap.isOpened():
# 读取视频帧
ret, frame = cap.read()
在循环中,处理每一帧视频,进行姿态检测、角度计算和俯卧撑计数。
7.姿态检测和角度计算
# Recolor image to RGB
image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image.flags.writeable = False
# Make detection
results = pose.process(image)
这部分将视频帧转换为RGB格式,以便MediaPipe处理,然后进行姿态检测。
8. 计算关节坐标和角度
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]
从检测结果中提取关键点坐标,计算肘部到肩部的角度。
9.显示角度和更新计数器
if angle > max_angle:
stage = "down"
if angle < min_angle and stage == 'down':
stage = "up"
counter += 1
print(counter)
根据计算出的角度判断当前动作阶段,当达到特定条件时增加俯卧撑计数。
10. 在视频帧上绘制结果和计数信息
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)
在图像上绘制关键点和连接线,同时显示俯卧撑计数和动作阶段
11. 用户退出循环
if cv2.waitKey(10) & 0xFF == ord('q'):
break
如果用户按下’q’键,退出循环。
12. 结束视频处理
cap.release()
cv2.destroyAllWindows()
释放视频资源,关闭所有OpenCV窗口。
2.完整源码
#coding:utf-8
# 导入必要的库
import cv2
import mediapipe as mp
import numpy as np
# 定义计算角度的函数
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)
# 打开视频
cap = cv2.VideoCapture('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()
免费获取方式
本文介绍的完整源码与测试视频均已上传,通过以下方式即可获取,更多精彩内容持续更新中~
关注文末名片G-Z-H:【阿旭算法与机器学习】,发送【开源】即可获取下载方式
好了,这篇文章就介绍到这里,喜欢的小伙伴感谢赞关注,更多精彩内容持续更新~~
更多干货内容,可关注文末G-Z-H: 【阿旭算法与机器学习】,欢迎共同学习交流