人体三维重建学习笔记(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 顶点位置 = + B_shape·β + B_pose·θ(T̄ 为平均网格)
骨骼绑定 使用 LBS(Linear Blend Skinning) 将关节变换传播到网格顶点上
可微分实现 通过 Chumpy / PyTorch 实现,使得梯度可直接用于深度学习优化[[6]]

3️⃣ SMPL‑X 的扩展点

  1. 手部:采用 MANO 手部模型(21 个关节),与身体关节统一在同一骨骼层级。
  2. 面部:采用 FLAME 表情模型,加入 55 个面部/颈部关节表情参数 ψ
  3. 统一参数向量
    [
    \Phi = {\beta,;\theta,;\psi,;\gamma}
    ]
    其中 γ 为手部姿态,ψ 为面部表情。
  4. UV 贴图 & 纹理:提供完整的 UV 展开,便于纹理映射与渲染。
  5. 更丰富的关节集合: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‑BFGSAdam,在 PyTorch 实现中可实现 以上的速度提升[[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(以单张图片为例)
  1. 准备 2D 关键点:使用 OpenPoseDetectron2Mediapipe 提取 body、hand、face 关键点(共 127 点)。
  2. 加载 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']
  1. 渲染结果:使用 smplx.renderPyRender 将优化后的模型投影回图像,检查关键点对齐情况。

该流程在 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 即可完成端到端的三维重建,后续可结合渲染、动画或下游任务(姿态估计、动作合成等)进行扩展。
Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐