AI 视觉人体姿态关键点实时跟踪 Python 代码
基于 MediaPipe 和 OpenCV 实现人体姿态关键点的实时跟踪检测。文章介绍了安装依赖、Pose 类参数配置、关键点绘制及坐标提取方法。通过 VideoCapture 读取视频流,转换颜色空间后调用 pose.process 处理,利用 drawing_utils 绘制连线与标记点。支持平滑处理、置信度阈值调整,并演示如何将归一化坐标转换为像素坐标进行保存与可视化显示。

基于 MediaPipe 和 OpenCV 实现人体姿态关键点的实时跟踪检测。文章介绍了安装依赖、Pose 类参数配置、关键点绘制及坐标提取方法。通过 VideoCapture 读取视频流,转换颜色空间后调用 pose.process 处理,利用 drawing_utils 绘制连线与标记点。支持平滑处理、置信度阈值调整,并演示如何将归一化坐标转换为像素坐标进行保存与可视化显示。

本文分享如何使用 MediaPipe 完成人体姿态关键点的实时跟踪检测。
# 安装 opencv
pip install opencv-contrib-python
# 安装 mediapipe
pip install mediapipe
# pip install mediapipe --user #有 user 报错的话试试这个
# 安装之后导入各个包
import cv2 #opencv
import mediapipe as mp
import time
人体姿态检测相关说明见官方文档:Pose - mediapipe (google.github.io) MediaPipe Pose 中的地标模型预测了 33 个姿势地标的位置。
从 mediapipe 中导入检测方法,使用 mediapipe.solutions.pose。
mediapipe.solutions.hands # 手部关键点检测
mediapipe.solutions.pose # 人体姿态检测
mediapipe.solutions.face_mesh # 人脸网状检测
mediapipe.solutions.face_detection # 人脸识别
参数:
返回值:具有 "pose_landmarks" 字段的 NamedTuple 对象,其中包含检测到的最突出人物的姿势坐标。
参数:
使用 cv2.VideoCapture() 读取视频文件时,文件路径最好不要出现中文,防止报错。 变量.read() 每次执行就从视频中提取一帧图片,需要循环来不断提取。用 success 来接收是否能打开,返回 True 表示可以打开。img 保存返回的每一帧图像。 由于读入视频图像通道一般为 RGB,而 opencv 中图像通道的格式为 BGR,因此需要 cv2.cvtColor() 函数将 opencv 读入的视频图像转为 RGB 格式 cv2.COLOR_BGR2RGB。 在绘制人体关键点时 mpDraw.draw_landmarks();results.pose_landmarks 获取所有关键点信息;如果不传入参数 mpPose.POSE_CONNECTIONS,那么就不会绘制关键点之间的连线。
import cv2
import mediapipe as mp
import time
# 导入姿态跟踪方法
mpPose = mp.solutions.pose # 姿态识别方法
pose = mpPose.Pose(static_image_mode=False, # 静态图模式,False 代表置信度高时继续跟踪,True 代表实时跟踪检测新的结果
#upper_body_only=False, # 是否只检测上半身
smooth_landmarks=True, # 平滑,一般为 True
min_detection_confidence=0.5, # 检测置信度
min_tracking_confidence=0.5) # 跟踪置信度
# 检测置信度大于 0.5 代表检测到了,若此时跟踪置信度大于 0.5 就继续跟踪,小于就沿用上一次,避免一次又一次重复使用模型
# 导入绘图方法
mpDraw = mp.solutions.drawing_utils
#(1)导入视频
filepath = 'C:\\GameDownload\\Deep Learning\\master.mp4'
cap = cv2.VideoCapture(filepath)
pTime = 0 # 设置第一帧开始处理的起始时间
#(2)处理每一帧图像
while True:
# 接收图片是否导入成功、帧图像
success, img = cap.read()
# 将导入的 BGR 格式图像转为 RGB 格式
imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 将图像传给姿态识别模型
results = pose.process(imgRGB)
# 查看体态关键点坐标,返回 x,y,z,visibility
# print(results.pose_landmarks)
# 如果检测到体态就执行下面内容,没检测到就不执行
if results.pose_landmarks:
# 绘制姿态坐标点,img 为画板,传入姿态点坐标,坐标连线
mpDraw.draw_landmarks(img, results.pose_landmarks, mpPose.POSE_CONNECTIONS)
# 查看 FPS
cTime = time.time() #处理完一帧图像的时间
fps = 1/(cTime-pTime)
pTime = cTime #重置起始时间
# 在视频上显示 fps 信息,先转换成整数再变成字符串形式,文本显示坐标,文本字体,文本大小
cv2.putText(img, str((fps)), (,), cv2.FONT_HERSHEY_PLAIN, , (,,), )
cv2.imshow(, img)
cv2.waitKey() & ==:
cap.release()
cv2.destroyAllWindows()
接下来,我们将 33 个关键点的坐标保存下来,并将这些关键点放大一些,使其更加明显。因此我们补充上面的代码。 由于 results.pose_landmarks.landmark 中保存的 xyz 坐标是归一化后的比例坐标,即某一像素点在图像的某一比例位置,如 [0.5, 0.5]。我们需要将其转为像素坐标,如 [200,200],像素坐标一定是整数。通过图像宽高乘以各自比例即可得到像素坐标下的宽高。为了能更明显的显示关键点,把关键点画的大一些,只需以关键点的像素坐标为圆心画圆 cv2.circle() 即可。将像素坐标保存到 lmlist 中。
import cv2
import mediapipe as mp
import time
# 导入姿态跟踪方法
mpPose = mp.solutions.pose # 姿态识别方法
pose = mpPose.Pose(static_image_mode=False, # 静态图模式,False 代表置信度高时继续跟踪,True 代表实时跟踪检测新的结果
#upper_body_only=False, # 是否只检测上半身
smooth_landmarks=True, # 平滑,一般为 True
min_detection_confidence=0.5, # 检测置信度
min_tracking_confidence=0.5) # 跟踪置信度
# 检测置信度大于 0.5 代表检测到了,若此时跟踪置信度大于 0.5 就继续跟踪,小于就沿用上一次,避免一次又一次重复使用模型
# 导入绘图方法
mpDraw = mp.solutions.drawing_utils
#(1)导入视频
filepath = 'C:\\GameDownload\\Deep Learning\\master.mp4'
cap = cv2.VideoCapture(filepath)
pTime = 0 # 设置第一帧开始处理的起始时间
#(2)处理每一帧图像
lmlist = [] # 存放人体关键点信息
while True:
# 接收图片是否导入成功、帧图像
success, img = cap.read()
# 将导入的 BGR 格式图像转为 RGB 格式
imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 将图像传给姿态识别模型
results = pose.process(imgRGB)
# 查看体态关键点坐标,返回 x,y,z,visibility
# print(results.pose_landmarks)
# 如果检测到体态就执行下面内容,没检测到就不执行
if results.pose_landmarks:
# 绘制姿态坐标点,img 为画板,传入姿态点坐标,坐标连线
mpDraw.draw_landmarks(img, results.pose_landmarks, mpPose.POSE_CONNECTIONS)
# 获取 33 个人体关键点坐标,index 记录是第几个关键点
for index, lm in enumerate(results.pose_landmarks.landmark):
# 保存每帧图像的宽、高、通道数
h, w, c = img.shape
cx, cy = (lm.x * w), (lm.y * h)
(index, cx, cy)
lmlist.append((cx, cy))
cv2.circle(img, (cx,cy), , (,,), cv2.FILLED)
cTime = time.time()
fps = /(cTime-pTime)
pTime = cTime
cv2.putText(img, ((fps)), (,), cv2.FONT_HERSHEY_PLAIN, , (,,), )
cv2.imshow(, img)
cv2.waitKey() & ==:
cap.release()
cv2.destroyAllWindows()

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online