人体三维重建学习笔记(SMPL / SMPL‑X / SMPLify‑X)
摘要: SMPL系列模型(SMPL/SMPL-X/SMPLify-X)是当前人体三维重建的核心方法。SMPL通过形状参数β(10维)和姿态参数θ(72维)生成可动画人体网格;SMPL-X扩展为统一的身体-手-脸模型(55关节+10,475顶点);SMPLify-X则从单图2D关键点优化求解模型参数。核心流程包括:(1)基于线性blend-shape与LBS的网格形变;(2)多阶段能量函数优化(投影
人体三维重建学习笔记(SMPL / SMPL‑X / SMPLify‑X)
更多详细内容,请访问:[人工智能社区] ( http://studyai.com )
http://studyai.com
1️⃣ 背景与模型概述
- SMPL(Skinned Multi‑Person Linear model)是第一个基于线性 blend‑shape 与骨骼绑定的可微分人体模型,能够用 形状参数 β(≈10 维) 与 姿态参数 θ(72 维) 生成完整的三维网格[[1]]。
- SMPL‑X 在 SMPL 基础上加入 全身手部(MANO) 与 表情面部(FLAME),形成统一的 55 个关节 + 10 475 个顶点 模型,能够一次性捕获 身体‑手‑脸 的细节[[2]][[3]]。
- SMPLify‑X 是一种 基于优化的 fitting 方法,从单张 RGB 图像的 2D 关键点出发,最小化多项能量函数(关节投影误差、姿态先验、碰撞惩罚、性别检测等),快速得到 SMPL‑X 参数[[4]][[5]]。
2️⃣ SMPL 结构与核心公式
| 组成 | 说明 |
|---|---|
| 形状空间 β | 通过 PCA 从数千个人体扫描得到的低维形变基,控制体型(身高、体重、体格) |
| 姿态空间 θ | 24 个关节的 3 DoF 旋转(轴角),共 72 维 |
| 线性 blend‑shape | 顶点位置 = T̄ + B_shape·β + B_pose·θ(T̄ 为平均网格) |
| 骨骼绑定 | 使用 LBS(Linear Blend Skinning) 将关节变换传播到网格顶点上 |
| 可微分实现 | 通过 Chumpy / PyTorch 实现,使得梯度可直接用于深度学习优化[[6]] |
3️⃣ SMPL‑X 的扩展点
- 手部:采用 MANO 手部模型(21 个关节),与身体关节统一在同一骨骼层级。
- 面部:采用 FLAME 表情模型,加入 55 个面部/颈部关节 与 表情参数 ψ。
- 统一参数向量:
[
\Phi = {\beta,;\theta,;\psi,;\gamma}
]
其中 γ 为手部姿态,ψ 为面部表情。 - UV 贴图 & 纹理:提供完整的 UV 展开,便于纹理映射与渲染。
- 更丰富的关节集合:55 个关节(包括手指、眼睛、舌头等),适配细粒度动作捕捉[[7]][[8]]。
4️⃣ SMPLify‑X 的优化流程(核心能量函数)
[
\begin{aligned}
E(\beta,\theta,\psi,\gamma) = &;E_J ;+; \lambda_{b_h}E_{b_h} ;+; \lambda_{o_f}E_{o_f} ;+; \lambda_{m_h}E_{m_h}\
&;+; \lambda_{\alpha}E_{\alpha} ;+; \lambda_{\beta}E_{\beta} ;+; \lambda_{\varepsilon}E_{\varepsilon} ;+; \lambda_{C}E_{C}
\end{aligned}
]
- (E_J):2D 关键点投影误差(包括身体、手、脸)。
- (E_{b_h}):手部关键点误差。
- (E_{o_f}):面部关键点误差。
- (E_{m_h}):自碰撞惩罚(快速且准确的渗透检测)[[9]]。
- (E_{\alpha},E_{\beta},E_{\varepsilon}):姿态、形状、表情的正则化先验(基于大规模 MoCap 数据训练的 VAE 先验)。
- (E_{C}):性别检测与模型选择(男性/女性/中性)[[10]]。
优化采用 L‑BFGS 或 Adam,在 PyTorch 实现中可实现 8× 以上的速度提升[[11]]。
5️⃣ 实践步骤(从零开始)
5.1 环境准备
# 推荐使用 conda 管理依赖
conda create -n smplx python=3.9 -y
conda activate smplx
# 安装官方库(包括 SMPL、SMPL‑X、MANO、FLAME)
pip install torch==2.2.0 torchvision==0.17.0
pip install smplx[all] # 包含模型下载脚本
5.2 下载模型文件
- 访问 https://smpl-x.is.tue.mpg.de (需注册)下载 SMPL‑X、SMPL+H、SMPL 的 .npz 权重文件。
- 将下载的压缩包解压至
~/.smplx/(默认搜索路径),文件结构示例:~/.smplx/ smpl/ SMPL_NEUTRAL.pkl smplx/ SMPLX_NEUTRAL.npz mano/ MANO_RIGHT.pkl flame/ FLAME_NEUTRAL.pkl
5.3 关键代码示例(加载模型 & 可视化)
import torch
import smplx
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# 1) 加载 SMPL‑X(中性模型)
model_path = "~/.smplx/smplx"
smplx_model = smplx.create(model_path,
model_type='smplx',
gender='neutral',
use_face_contour=True,
ext='npz')
# 2) 随机生成一套参数
batch_size = 1
device = torch.device('cpu')
pose = torch.zeros([batch_size, smplx_model.NUM_POSE_PARAMS], device=device) # 55*3
betas = torch.zeros([batch_size, smplx_model.NUM_BETAS], device=device) # 10
expression = torch.zeros([batch_size, smplx_model.NUM_EXPRESSION_PARAMS], device=device)
# 3) 前向推理得到顶点
output = smplx_model(betas=betas, body_pose=pose[:,3:],
global_orient=pose[:,:3],
transl=torch.zeros([batch_size,3]),
expression=expression,
jaw_pose=pose[:,55*3:58*3]) # 示例:取 jaw_pose
vertices = output.vertices.detach().cpu().numpy().squeeze()
# 4) 简单 3D 可视化
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(vertices[:,0], vertices[:,1], vertices[:,2], s=0.5)
ax.set_axis_off()
plt.show()
运行后即可看到一个完整的 SMPL‑X 网格(包括手部、面部)。
5.4 SMPLify‑X 实际 fitting(以单张图片为例)
- 准备 2D 关键点:使用 OpenPose、Detectron2 或 Mediapipe 提取 body、hand、face 关键点(共 127 点)。
- 加载 SMPLify‑X 优化器(官方实现位于
smplx/SMPLifyX.py),示例代码:
from smplx import SMPLifyX
import cv2, numpy as np
# 读取图片 & 关键点(这里假设已经得到 keypoints_2d, confidence)
img = cv2.imread('person.jpg')
keypoints_2d = np.load('keypoints.npy') # (127,2)
conf = np.load('conf.npy') # (127,)
# 初始化 SMPLify‑X
fitter = SMPLifyX(model_path, device='cpu')
fit_params = fitter.fit(keypoints_2d, conf, img_path='person.jpg')
# 输出优化后的参数
beta_opt = fit_params['betas']
pose_opt = fit_params['pose']
expr_opt = fit_params['expression']
- 渲染结果:使用
smplx.render或 PyRender 将优化后的模型投影回图像,检查关键点对齐情况。
该流程在 PyTorch 中实现,单帧耗时约 0.5 s(相较于原始 Chumpy 实现的 4 s 有显著提升)[[12]]。
5.5 常见调优技巧
| 场景 | 建议 |
|---|---|
| 手部关键点噪声大 | 增大 λ_{b_h} 权重,或先对手部关键点做平滑滤波。 |
| 面部表情不收敛 | 使用更强的 表情先验(VAE)并适当提升 λ_{ψ}。 |
| 性别错误 | 在 fit 前手动指定 gender,或使用 fit 返回的 gender 置信度重新初始化。 |
| 碰撞惩罚失效 | 确认 self_intersection 模块已开启(use_self_collision=True),并检查 mesh 缩放比例。 |
| GPU 加速 | 将模型和关键点张量搬到 cuda,并使用 torch.backends.cudnn.benchmark=True。 |
6️⃣ 参考资源(可直接访问)
- SMPL 原始论文:Loper et al., SMPL: A Skinned Multi‑Person Linear Model, ACM TOG 2015[[13]]
- SMPL‑X 论文:Pavlakos et al., SMPL‑X: A new joint 3D model of the human body, face and hands together, CVPR 2019[[14]][[15]]
- SMPLify‑X 论文:Pavlakos et al., Expressive Body Capture: 3D Hands, Face and Body from a Single Image, CVPR 2019[[16]][[17]]
- 官方代码仓库:
https://github.com/vchoutas/smplx(包含模型下载脚本、SMPLify‑X 实现)[[18]] - 实战教程:GitCode 上的 SMPLify‑X 实现指南(环境搭建、数据准备)[[19]]
- 最新应用:SMPL‑X 在 3D‑aware Diffusion、点云拟合等前沿工作(如 MagicMan、PSHuman)展示了模型的持续活跃度[[20]][[21]]
7️⃣ 小结
- SMPL 为人体建模提供了 低维、可微分、可编辑 的基石。
- SMPL‑X 在此基础上实现 全身‑手‑脸 的统一表示,极大提升了细节捕获能力。
- SMPLify‑X 通过 多项能量函数 与 高效 PyTorch 实现,实现了从单张 RGB 图像到完整 SMPL‑X 参数的快速拟合。
- 实践中只需 下载模型、准备 2D 关键点、调用官方
SMPLifyX即可完成端到端的三维重建,后续可结合渲染、动画或下游任务(姿态估计、动作合成等)进行扩展。
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)