мы уже имеем«Python играет с искусственным интеллектом: сколько подтягиваний вы можете сделать? 》и«Python играет с искусственным интеллектом: ваши приседания на должном уровне?» 》, давай сегодня поиграем в отжимания!
1. Подготовка
1.1 Установите Python3.8.x
1.2 Установите PyCharm Community Edition
1.3 Создать проект
1.4 Устанавливаем проект с помощью инструментария
1.1 Загрузите и установите версию Python3.8.x
Прежде всего, нам нужно установить Python3.8.x на наш компьютер. Питон 3.8.х:www.python.org/downloads/
1.2 Загрузите и установите PyCharm Community Edition
PyCharm: woohoo.jet brains.com/py charm/Доу…Конечно, вы также можете использовать свою любимую IDE.
1.3 Создайте проект Python
После установки Python и PyCharm мы можем запустить PyCharm и создать новый проект Python. Выберите место хранения проекта.При создании проекта вы можете попросить PyCharm помочь создать виртуальную среду (virtualenv).Виртуальная среда может пониматься как исключительная среда программирования для этого проекта и не повлияет на другие проекты.
1.4 Инструментарий, используемый для проекта установки
После создания проекта мы открываем окно терминала PyCharm, где мы можем ввести следующую команду для установки набора инструментов, необходимого для этого проекта: opencv-python mediapipe numpy pyautogui. Следующая команда загрузит инструментарий из Интернета и установит его.Если в конце вы увидите английское слово «Успешно установлено...», значит, установка выполнена успешно.
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, получите данные о положении тела человека и вычислите три точки плеч, бедер и коленей в человеческом теле, а также углы, образованные плечами, локтями и запястьями, и оцените, отжимание стандартно под этими двумя углами.
# 导入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 градусов, который можно отрегулировать в соответствии с углом съемки. также корректироваться. При съемке видео или использовании камеры рекомендуется размещать больше сбоку от тела человека, чтобы обнаружение было более точным.