Python如何把人体姿态向量化
摘要:本文介绍了如何利用Python和MediaPipe将人体动作实时转化为数字向量,用于AI健身教练等应用开发。通过提取17个关键点的3D坐标(x,y,z)组成51维向量,实现人体姿态的数字化表示。文章详细讲解了从单张图片到实时视频流的处理流程,包括关键点提取、向量归一化、关节角度计算等核心方法,并演示了如何优化向量特征使AI更容易理解。这种姿态向量化技术可应用于动作识别、异常检测、虚拟形象驱动
想象一下,你正在开发一款AI健身教练APP。用户对着摄像头做深蹲,APP需要实时判断:“膝盖弯曲角度够不够?背是不是挺直的?”
计算机看不懂视频里的“人”,它只看得懂数字。如果你把一张照片扔给神经网络,它看到的只是一堆 [255, 128, 30...] 的像素矩阵。
怎么办?我们需要把“人”抽象成数学模型——这就是“姿态向量化”。
今天,我们用 Python + MediaPipe(谷歌开源的黑科技),只用几十行代码,把复杂的人体动作变成一串AI能读懂的数字向量。
第一步:理解什么是“姿态向量”
不要被“向量”两个字吓到。其实就是关键点坐标列表。
人类的身体可以被拆解成一个个关节(关键点):鼻子、左肩、右肘、手腕、膝盖、脚踝……
目前主流的模型(如 COCO 格式)会把人体定义为 17个关键点(2D)或 33个关键点(3D全身)。
每个关键点有 x, y, z 三个坐标值。
向量化,就是把这些坐标按顺序排成一列。比如:[鼻_x, 鼻_y, 鼻_z, 左肩_x, 左肩_y, 左肩_z, 右肩_x, ...]
这一长串数字,就是你在视频里的“数字分身”。
第二步:工具选择——为什么用 MediaPipe?
以前做姿态估计,要么自己训练模型(累死),要么用 OpenPose(配置环境累死)。
现在谷歌的 MediaPipe 是首选:
- 快:在普通笔记本CPU上也能实时运行(30+ FPS)。
- 准:自带3D坐标(z轴),能感知深度。
- 全:支持手部、面部、全身姿态。
安装依赖:
pip install mediapipe opencv-python numpy
第三步:实战代码——把人变成数字
我们来写一个脚本:读取摄像头画面,把每一帧画面中的人提取出来,变成向量并打印。
1. 基础版:提取单张图片的姿态向量
import cv2
import mediapipe as mp
import numpy as np
# 初始化 MediaPipe Pose
mp_pose = mp.solutions.pose
pose = mp_pose.Pose(model_complexity=1, enable_segmentation=False) # model_complexity越高越准越慢
# 读取一张图片(或者视频帧)
image = cv2.imread("fitness.jpg") # 换成你的图片路径
if image is None:
raise FileNotFoundError("找不到图片,请检查路径")
# 转换颜色 BGR -> RGB
rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# 进行姿态估计
results = pose.process(rgb_image)
# --- 核心:向量化过程 ---
if results.pose_landmarks:
landmarks = results.pose_landmarks.landmark
vector_list = []
# 遍历17个关键点 (nose, left_shoulder, right_shoulder, etc.)
for landmark in landmarks:
# landmark 包含 x, y, z, visibility
# 注意:这里的 x, y 是相对于图像宽高的归一化坐标 (0.0 ~ 1.0)
# z 是深度坐标,以髋部为原点
vector_list.extend([landmark.x, landmark.y, landmark.z])
# 转换成 numpy 数组 (这就是最终的向量!)
pose_vector = np.array(vector_list)
print(f"生成的向量维度: {pose_vector.shape}") # 应该是 17 * 3 = 51
print(f"向量数据: {pose_vector}")
# 简单的应用:打印左手腕的坐标
# 左手腕是 landmark index 15,对应向量切片 [15*3 : 15*3+3]
left_wrist_vec = pose_vector[45:48]
print(f"左手腕坐标(归一化): {left_wrist_vec}")
else:
print("没检测到人!")
pose.close()
代码解析:
pose.process()是黑盒子,输入图片,输出结果。results.pose_landmarks.landmark是一个列表,包含了17个关键点对象。- 我们用
extend把每个点的x, y, z拼起来,得到了一个长度为 51 (17x3) 的一维数组。 - 这就是最基础的姿态向量!
第四步:进阶——如何让向量更“智能”?
直接用绝对坐标(像素值或归一化值)有个问题:离镜头近的人显得大,离得远显得小。 AI会误以为这是两个不同的动作。
我们需要做归一化处理,让向量只关注“骨架结构”,不关注“人在画面哪里”。
技巧1:以鼻子为原点(相对坐标)
把所有点的坐标减去鼻子的坐标,这样向量描述的是“手腕离鼻子多远”,而不是“手腕在屏幕左上角还是右下角”。
# 假设 nose_coord = [x_n, y_n, z_n]
# new_wrist_coord = [x_w - x_n, y_w - y_n, z_w - z_n]
技巧2:计算肢体角度(特征工程)
与其给AI原始坐标,不如直接算出“大臂和小臂的夹角”、“大腿和躯干的夹角”。这对判断深蹲动作非常有效。
def calculate_angle(a, b, c):
# a, b, c 是三个点的坐标 (x, y)
# 利用反余弦定理计算夹角
ba = a - b
bc = c - b
cosine_angle = np.dot(ba, bc) / (np.linalg.norm(ba) * np.linalg.norm(bc))
angle = np.arccos(cosine_angle)
return np.degrees(angle)
# 例如计算肘关节角度
# 左肩(11), 左肘(13), 左腕(15)
angle_elbow = calculate_angle(left_wrist, left_elbow, left_shoulder)
print(f"手肘弯曲角度: {angle_elbow} 度")
现在,你的向量不再是简单的坐标列表,而是 [手肘角度, 膝盖角度, 脊柱弯曲度...]。这才是AI最喜欢的特征!
第五步:实时视频流向量化
把上面的逻辑放进 while True 循环,就是一个实时的AI骨架分析器。
import cv2
import mediapipe as mp
import numpy as np
mp_drawing = mp.solutions.drawing_utils
mp_pose = mp.solutions.pose
cap = cv2.VideoCapture(0) # 打开摄像头
with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose:
while cap.isOpened():
ret, frame = cap.read()
if not ret: break
# 翻转画面,像照镜子一样自然
frame = cv2.flip(frame, 1)
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = pose.process(rgb_frame)
if results.pose_landmarks:
# 绘制骨架(可视化)
mp_drawing.draw_landmarks(frame, results.pose_landmarks, mp_pose.POSE_CONNECTIONS)
# 在这里插入上面的向量提取代码...
# 你可以把向量实时发送给后端的LSTM或分类模型
# 比如:if knee_angle < 30: print("深蹲不够深!")
cv2.imshow('Pose Vectorization', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
总结:向量化之后能干嘛?
当你把人体变成了一串数字(比如每秒30帧,每帧51个数字),你就打开了新世界的大门:
- 动作分类:把向量丢进随机森林或神经网络,训练它识别“敬礼”、“拳击”、“瑜伽下犬式”。
- 异常检测:监控工地工人,如果向量显示“手臂举过头顶且身体倾斜”,判定为不安全行为。
- 动作纠错:像Just Dance或Keep一样,对比用户的向量和标准动作的向量,计算欧氏距离,打分。
- 虚拟形象驱动:把向量实时发给Unity或Unreal,让游戏里的角色模仿你的动作(Vtuber技术核心)。
Python + MediaPipe 把这一切的门槛降到了极低。现在,去打开你的摄像头,试试把你自己“数字化”吧!
更多推荐



所有评论(0)