新闻详情

新闻详情

首页 / 资讯中心 / 详情

SMPL/SMPLify源码实战:从2D关键点到3D人体网格的拟合全解析

发布时间:2026/9/28 16:55:59来源:尧图网络
SMPL/SMPLify源码实战:从2D关键点到3D人体网格的拟合全解析
简介在人体动作捕捉与三维重建研究中SMPL 参数化人体模型与 SMPLify 姿态拟合方法是两条核心实现路径。面向计算机、数学、电子信息等专业学生这份 Python 工程适合作为课程设计、期末大作业或毕业设计的参考资料帮助读者快速跑通完整流程并理解算法原理。压缩包内共 2000 个文件包含 14 个 Python 源码、1 份 Markdown 项目说明和 1985 张示例图片整体大小 12.85MB便于下载和对照学习。源码目录按模块拆分两个入口脚本分别演示 SMPL 模型生成与 SMPLify 三维姿态拟合Markdown 说明中列出了 libosmesa6-dev、opendr、pyrender、trimesh 等依赖安装命令与脚本运行方式可显著减少环境配置和上手使用的时间成本。大量示例图片覆盖多种人体姿态与重建结果既能用于直观核对算法输出也可辅助调试参数与流程。已有 486 人学习/下载。该资源作为参考资料更适合具备一定 Python 基础、愿意钻研并自行扩展功能的读者掌握后可获得从参数化人体建模到三维姿态拟合的完整参考链路。1. 从2D关键点到3D人体网格这套SMPL/SMPLify源码包能干什么拿到这个zip的时候我正被课程设计里的“三维重建”卡得头疼。解压一看code目录下就两个核心脚本hello_smpl.py和fit_3d.py外加一串im0793.jpg、im1824.jpg之类的示例图片。最初我以为是拿视频直接生成人体模型的黑盒工具跑通才发现它的路子很不一样它不是靠深度图或视频光流而是把一帧2D人体关键点喂进优化器反推出SMPL模型的姿态参数和体型参数从而得到一个可驱动、可重绘的3D人体网格。这套源码适合做计算机视觉、图形学方向课程设计或毕设的人也适合刚接触参数化人体模型的同学当练手基线。看懂fit_3d.py基本就打通了“2D关键点→3D姿态”这条主线后续换检测器、换数据集都是小事。2. SMPL模型怎么跑通hello_smpl.py的运行、依赖与参数含义2.1 先搞懂SMPL在算什么SMPLSkinned Multi-Person Linear Model是2015年前后提出的参数化人体模型核心思想是把“人体长什么样”和“人体怎么动”压缩成两组数字形状参数β和姿态参数θ。β通常是一个10维或300维的向量控制高矮胖瘦、肩宽腿长这类跟动作无关的体型属性θ则是24个关节点乘以3个旋转分量共72维每个关节用axis-angle表示法描述局部旋转。模型的前向计算可以写成M(β,θ) W(T_p(β,θ), J(β), θ, W)。其中T_p是变形后的模板网格J(β)是根据体型回归得到的关节点位置W是蒙皮权重。更细一步T_p T̄ B_s(β) B_p(θ)意思是先从一个标准T-pose网格T̄出发叠加形状混合形状B_s(β)再叠加姿态混合形状B_p(θ)。这样做的好处是姿态变化引起的皮肤隆起、肌肉形变被直接建模进了线性混合形状里而不像传统骨骼蒙皮那样只有刚性旋转。理解这个设计对读源码很重要你在fit_3d.py里看到的绝大多数矩阵运算本质都是在算从β、θ到顶点坐标的映射。只要这个映射是可微的梯度就能顺着损失函数传回去优化器才能一点点把姿态调对。这也是为什么SMPL成了后续VPoser、HMR、PyMAF等一堆工作的地基它把原来黑匣子的“姿态估计”变成了一个可解的参数优化问题。2.2 环境安装三条命令背后的依赖关系资源说明里给了三条安装命令先照抄一遍$ sudo apt-get install libosmesa6-dev $ pip3 install opendr0.78 $ pip3 install pyrender trimesh第一条命令安装的是OSMesa离屏渲染库。SMPL和SMPLify在拟合过程中要把3D网格投影到2D平面做可视化还会借助渲染器生成对应关系服务器或本机没有显示器时就需要离屏渲染libosmesa6-dev就是干这个的。很多人在这一步图省事跳过后面import或运行必翻车。第二条命令装opendr这个老牌库在SMPLify早期版本里负责渲染和相机构建第三条装pyrender和trimeshtrimesh用来加载、导出和操作网格模型pyrender用来做高质量的可视化渲染这两者是现代Python三维管线里的标配。从命令能看出这套源码是Python3改写版。需要注意opendr0.78这个固定版本有兼容性隐患不同Ubuntu版本、不同Python小版本下编译结果不一样具体坑在第四章展开。如果只是想把hello_smpl.py跑出网格pyrender和trimesh其实已经够用opendr更多是历史代码的依赖残留。2.3 运行hello_smpl.py并改出自己的数值安装完依赖后运行方式很简单$ cd code $ python hello_smpl.py这个脚本的典型行为是加载SMPL模型文件给一组默认的β和θ计算网格顶点然后导出OBJ或用pyrender渲染一张图。跑通后你会看到标准T-pose人体的6890个顶点和13776个三角面。多数实现还会在终端打印模型的包围盒大小、顶点数量有些会顺手存一个smpl.obj方便你在MeshLab里翻看。真正要用起来不能只跑默认参数。我自己习惯先把模型参数抽出来单独写个小脚本验证不同β、θ下的网格变化import numpy as np import pickle # 加载SMPL模型参数文件pkl是官方注册后下载的 with open(models/basicModel_neutral_lbs_10_207_0_v1.0.0.pkl, rb) as f: model_data pickle.load(f, encodinglatin1) # 初始化参数10维体型系数全024个关节旋转全0即标准T-pose beta np.zeros(10) theta np.zeros(72) # 常见工程里模型封装成SMPL类forward返回顶点坐标(6890,3) # 这里示意性地调forward实际看代码里的类名 # verts smpl_model(betabeta, thetatheta) # 返回 (6890, 3) 顶点解释一下这段的关键点。beta是10维数组第一位是“胖瘦”主成分调成3.0左右能明显看到人体变壮theta是72维数组想摆指定姿势需要找到对应关节的索引比如左肘通常落在某几个固定维度上具体索引可以从模型的关节注册表里查。刚开始练习时推荐一次只改一个维度渲染出来对比比看数字直观得多。参数调完如果不方便看渲染图可以把顶点存成ply或obj再用trimesh加载import trimesh # 将顶点和面片组成trimesh对象并导出 mesh trimesh.Trimesh(verticesverts, facesfaces, processFalse) mesh.export(output_smpl.obj)这样跑几次你就能直观感受到β和θ各自控制什么。这个手感对后面理解SMPLify的优化目标非常重要因为fit_3d.py里求的正是这一组让损失函数最小的β和θ。3. SMPLify拟合实战fit_3d.py把2D关键点变成3D人体网格3.1 SMPLify的优化目标长什么样SMPLify是SMPL配套的姿态拟合方法核心思路是把“找姿态”变成一个能量最小化问题。给定一帧2D关键点我们要找一组θ和β使得模型投影出来的2D关节点与观测关键点尽可能重合同时姿态和体型不能跑飞。常见的目标函数写成E(β,θ) E_J(β,θ) λ_θ · E_θ(θ) λ_α · E_α(θ) λ_β · E_β(β)第一项E_J是重投影误差把3D关节通过相机模型投影到2D和检测到的2D关键点比像素距离第二项E_θ是姿态先验用来约束关节角度的自然程度避免出现肘部反折这类离谱姿态第三项E_α是姿态间惩罚抑制连续帧抖动第四项E_β是体型先验约束β不要偏离标准体型太远。各项前面的λ是权重不同版本取值不同一般λ_θ在4.0量级、λ_β在10.0量级具体以源码里的设置为准。这个公式决定了fit_3d.py的代码结构先加载SMPL模型和2D关键点初始化θ为全0的T-pose然后用迭代优化器反复计算能量并更新参数。常见做法是用scipy.optimize.minimize里的Powell或L-BFGS方法分多轮拟合每轮增加关节自由度和迭代次数也就是常说的coarse-to-fine策略。第一轮先锁定大部分关节只调全局姿态后面几轮逐步放开局部关节防止一开始就陷入局部最优。3.2 fit_3d.py的输入输出套路直接运行$ cd code $ python fit_3d.py这个脚本不会凭空生成mesh它需要读取2D关键点。多数工程里的做法是读一个NDJSON或JSON文件里面存OpenPose格式的关键点坐标。OpenPose输出的每个关键点形如x, y, confidence三个值共25个点或18个点SMPLify内部会做关节映射把OpenPose点序对齐到SMPL的24个关节上。如果工程里没有预置检测结果你需要先自己对包里的示例图片跑一遍OpenPose或MediaPipe输出JSON再喂给fit_3d.py。下表是这类工程常见的文件布局文件/目录作用images/im0793.jpg 等示例输入图片用于测试整条链路data/keypoints.json2D关键点检测结果一般由OpenPose生成models/*.pklSMPL官方模型参数需自行去官网注册下载code/fit_3d.py主拟合脚本读关键点、优化参数、输出网格code/hello_smpl.py基础SMPL演示脚本跑通模型前向跑通后脚本通常会输出三样东西拟合得到的θ和β数组、相机参数焦距和主点、一个OBJ或PLY格式的3D网格。有些实现还会把mesh渲染成带纹理的图片方便直接跟原始图片并排对比。3.3 写一个能照抄的重投影误差计算函数拟合是否成功最直观的指标就是重投影误差。很多新手把SMPLify当黑盒用只看mesh长什么样其实把误差算出来能帮你更快定位问题。下面这段代码可以用作评估import numpy as np # 相机内参焦距f主点cx、cy f, cx, cy 500.0, 320.0, 240.0 # joint_3d: 模型预测的3D关节形状(24, 3) # keypoints_2d: 检测到的2D关键点形状(24, 2) def compute_reproj_error(joint_3d, keypoints_2d): proj np.zeros_like(keypoints_2d) for i in range(joint_3d.shape[0]): x, y, z joint_3d[i] # 透视投影z小于0的点说明在相机后方跳过 if z 0: continue proj[i, 0] f * x / z cx proj[i, 1] f * y / z cy # 只对有效点计算平均像素误差 mask (keypoints_2d[:, 0] 0) (keypoints_2d[:, 1] 0) diff np.sqrt(np.sum((proj[mask] - keypoints_2d[mask]) ** 2, axis1)) return np.mean(diff)这段代码的要点在于它把模型输出的3D关节先做透视投影再跟检测到的2D关键点做差。实际拟合完以后平均误差在10像素以内基本可以接受超过30像素说明姿态没对齐需要检查关键点映射或相机初始化。注意SMPLify内部用的损失不是单纯的几何重投影权重项E_θ和E_β会弱化一部分几何约束所以即使优化完了重投影误差也可能略高于纯几何对齐的结果这是正常的。如果你想拿这个误差做收敛判断建议直接看外层优化轮次里的能量值曲线而不是只看最后的像素差。3.4 把拟合结果可视化核对拟合完成后常见做法是把生成的mesh用trimesh加载再叠加到原始图片上看贴合程度。我习惯先导出一帧侧视图和一帧正视图import trimesh import pyrender # 加载拟合输出的mesh mesh trimesh.load(output/fit_0001.obj) scene pyrender.Scene() mesh_node pyrender.Node(meshpyrender.Mesh.from_trimesh(mesh)) scene.add_node(mesh_node) # 设置相机视角从正面观察 camera pyrender.PerspectiveCamera(yfovnp.pi / 3.0) camera_pose np.eye(4) camera_pose[2, 3] 3.0 scene.add(camera, posecamera_pose) # 渲染保存 renderer pyrender.OffscreenRenderer(640, 480) color, _ renderer.render(scene)渲染前记得检查mesh顶点坐标是否在相机视野内如果mesh位置偏得很离谱通常是相机平移初始化不对而不是姿态算错。坐上这一步你就能肉眼判断拟合到底成功没成功也方便把多个角度截图写进课程设计报告。4. 常见问题与避坑这5个坑让我白折腾了两天4.1 opendr编译失败卡在xf86drm.h缺失现象执行pip3 install opendr0.78时编译报错fatal error: xf86drm.h: No such file or directory或者装完以后import就崩。原因opendr是个老库底层直接调用DRM和OSMesa的头文件系统里没装libosmesa6-dev时头文件缺失。解决先执行sudo apt-get install libosmesa6-dev装完再重新编译。如果还不行检查Python版本opendr 0.78对Python3.8以上的兼容性很差建议直接用pyrender替代它的渲染功能把fit_3d.py里依赖opendr渲染的段落改写掉代码量不大但能根治问题。4.2 模型文件缺失跑起来就报pkl找不到现象运行hello_smpl.py时提示找不到basicModel_neutral_lbs_10_207_0_v1.0.0.pkl。原因SMPL官方模型参数是受版权保护的需要到SMPL官网注册申请很多源码包为了合规不放pkl文件。解决先去官网注册并下载SMPL for Python版本解压后把里面的pkl文件放进models目录。下载时记得选对版本10个shape分量、207个pose分量那版是基础款后缀带neutral的表示中性体型跟大多数SMPLify代码匹配。4.3 numpy版本太新报np.float不存在现象运行时出现AttributeError: module numpy has no attribute float。原因老代码大量使用np.float、np.int这类别名numpy 1.24起把这两个别名移除了。解决把numpy锁到1.23.5一行命令搞定。但注意不要跟其他依赖冲突最好是建独立的conda环境再装。既然项目本身是Python3改写版直接把代码里的np.float替换成float再跑也是一种干净解法全局替换后重新运行即可。4.4 Python2和Python3语法残留现象运行脚本时提示invalid syntax错误位置在print语句或者直接报NameError: name xrange is not defined。原因SMPLify原始版本是Python2时代的代码后来有人改写成Python3但偶尔有函数内遗漏的旧语法没清理干净。解决运行前先python --version确认环境出现xrange就全局替换成range。如果工程里print语句没有括号用sed批量处理sed -i s/\bprint\b/print/g 需要逐行判断最省事的是把这些段落手工改成print()这类残留通常集中在工具函数里量不大。4.5 图像分辨率不统一导致拟合发散现象有的示例图片拟合得很好有的拟合结果严重扭曲重投影误差巨大。原因OpenPose给出的2D关键点坐标是相对于原图像素坐标的而SMPLify内部渲染窗口宽度固定如果图片没有统一缩放关键点坐标和相机内参就对不上。解决预处理阶段把所有图片resize到同一尺寸比如640×480同时把关键点坐标按比例缩放缩放时注意保持宽高比不要直接拉伸否则关节位置会偏移。我在工程里一般写成先统一长边到640再居中填充到正方形关键点做一模一样的变换这样相机内参能保持稳定拟合成功率明显提高。提示第四、第五条是新手最容易忽略的“玄学失败”。很多学员跑来问为什么拟合结果扭曲排查下来十有八九是坐标系或预处理的问题不是优化器调参的问题。5. 验证技巧与批处理把示例图片变成你的第一份动作序列数据这套源码最实用的进阶用法是把它从“单张图拟合”扩成“多帧批处理”输出一整套可驱动的关节旋转参数。示例图片虽然来自不同场景但只要你换成同一段动作的连续帧拟合出的θ序列就是一份最基础的动作捕捉数据。先写一个简单的批处理脚本把images目录下的所有图片依次跑完import subprocess import glob import os # 找到所有jpg文件 images sorted(glob.glob(images/*.jpg)) for img in images: # 每张图跑一次拟合入参为图片路径 cmd [python, fit_3d.py, --image, img, --save_dir, results/] subprocess.run(cmd) # 检查results目录下生成的obj数量 objs glob.glob(results/*.obj) print(f共生成 {len(objs)} 个网格文件)这个脚本的价值在于自动化验证跑完以后你得到的不是一个孤立mesh而是一批带顺序的网格。如果图片是连续帧你可以按编号把它们拼成一个glb动画或者把每帧的θ参数存成numpy数组后续做插值、滤波、驱动虚拟角色都用得上。这里有个验证习惯我强烈建议保留每批跑完顺手把重投影误差的均值打印出来误差超过阈值的帧单独拉出来看确认是图片质量问题还是优化器没收敛。接着我把θ序列导出成CSV方便后续分析import numpy as np # 所有帧的theta堆叠成(帧数, 72)转置后按关节维度保存 theta_seq np.stack(all_thetas, axis0) # 假设all_thetas是每帧拟合后的theta np.savetxt(pose_sequence.csv, theta_seq, delimiter,, header,.join([fjoint_{i} for i in range(72)]))这样处理后每列是某个关节的一个旋转分量随时间的变化曲线用matplotlib画出来就能看到动作是否平滑。如果曲线出现突然的跳变基本可以断定那一帧拟合质量差回到第4章的坑里去排查。回到开头那个困扰我的课程设计我后来把批处理输出的θ序列接到了一个简易的3D角色模型上角色在屏幕上做出和示例图片里人体一致的动作时整条链路的效果瞬间就直观了。从那以后我每次跑SMPL/SMPLify相关工程都会强制自己先走一遍固定流程确认pkl模型到位确认numpy版本统一图片尺寸最后再看拟合结果。这套源码包的代码量不大但方法论非常标准把它的环境、输入输出和优化链路摸透往后读任何基于SMPL的工作都会顺畅很多。希望这会成为你的第一份能跑通的“2D到3D”参考实现。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

STC51串口通信三大坑:丢数据、粘包、乱码及解决方案 2026/9/28 19:22:25

STC51串口通信三大坑:丢数据、粘包、乱码及解决方案

1. 坑一:查询方式接收,主循环一忙就丢字节1.1 现象描述与根因很多初学者第一次写STC51串口接收,用的都是类似这样的查询代码:while (1) {if (RI) {RI 0;buf[count] SBUF;}// 其他任务:数码管扫描、按键检测、延时...…

阅读更多 →
Visual Studio 预览版 Agent 模式配 TaoToken:settings.json 骨架与验证 2026/9/28 19:22:25

Visual Studio 预览版 Agent 模式配 TaoToken:settings.json 骨架与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Jev Auto Router:智能路由与可恢复机制,让Codex配额不再浪费 2026/9/28 19:22:25

Jev Auto Router:智能路由与可恢复机制,让Codex配额不再浪费

我自己的Codex用量,一天能清空好几轮配额,回头一看,干的全是批量替换、格式修正、写测试模板这种机械活。旗舰模型的能力被当成锄头用,心疼是一回事,效率才是真问题——真正需要深度推理的活儿反而没配额了。Jev Auto …

阅读更多 →
【Hermes Agent场景】数据分析师的瑞士军刀:TaoToken 统一 Key 接入配置实战 2026/9/28 19:21:59

【Hermes Agent场景】数据分析师的瑞士军刀:TaoToken 统一 Key 接入配置实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Amazon Pinpoint SDK for Python(Boto3)代码示例:从发送邮件、SMS 到模板消息的完整实战指南 2026/9/28 19:21:59

Amazon Pinpoint SDK for Python(Boto3)代码示例:从发送邮件、SMS 到模板消息的完整实战指南

示例工程教程后端 【免费下载链接】aws-doc-sdk-examples Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below. 项目地…

阅读更多 →
Claude Code之父谈「自动化」:用TaoToken统一Key打通AI智能体代码库工作流 2026/9/28 19:21:52

Claude Code之父谈「自动化」:用TaoToken统一Key打通AI智能体代码库工作流

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉