
踩过的坑多了反而觉得 VideoPose3D 这种老牌项目特别适合拿来练手。我第一次跑通它是用手机随手录了一段自己原地踏步的视频导出结果的时候看到画面里多了一个旋转的 3D 骨架那种“原来我也能做出这种效果”的成就感比单纯看论文强太多了。VideoPose3D 是 3D 人体姿态估计里非常经典的开源项目核心思路不是直接从图像回归 3D 坐标而是先用成熟 2D 关键点检测器提取二维坐标再靠时序建模把 2D 序列“提升”成 3D 姿态。官方代码用 PyTorch 实现训练在 Human3.6M 数据集上进行推理阶段只要喂一段普通 RGB 视频就能输出带关节坐标的 3D 骨架动画。这篇文章我打算把整个流程完整走一遍环境怎么搭、依赖怎么选版本、官方脚本怎么用、自己拍的视频如何顺利跑出结果以及我实际踩过的一些坑。适合想复现经典 CV 项目、做人体姿态估计实验或者急着给视频加 3D 骨骼动画的读者。整个过程重点不在读代码而在把链路打通2D 检测器负责“看见人”VideoPose3D 负责“算深度”可视化脚本负责“画骨架”。只要理解了这条链换成任何自己的视频都只是时间问题。1. VideoPose3D 到底在做什么1.1 2D 到 3D 的“提升”思路很多人第一次听到 VideoPose3D 都会问它是不是像 OpenPose 那样直接输入图片、输出 3D 关节坐标其实不是。VideoPose3D 用的是两阶段方案第一阶段是 2D 人体姿态估计第二阶段才是 3D 坐标恢复。它假设你已经有了 2D 关键点序列这些关键点可以是 Detectron2、AlphaPose、OpenPose 甚至 MediaPipe 输出的结果模型要做的事情是把时间维度上连续排列的 2D 关键点序列映射到 3D 空间。为什么这样设计能行关键点在于深度信息可以从运动轨迹里恢复。单张 2D 图片丢失了深度但一段连续视频里人物的关节会持续移动肩膀、胯部、膝盖的相对位置随时间变化这些运动轨迹里隐含了大量的 3D 几何信息。VideoPose3D 用带残差连接的时间卷积网络来捕捉这种跨帧依赖每个 2D 关键点在时间窗内的邻域都能被模型看到最终输出对应的 3D 坐标。这种“2D 检测 3D 提升”的模式很务实因为 2D 姿态估计这些年已经非常成熟在复杂背景下也能拿到不错的 2D 关键点良好的 2D 检测质量直接降低了 3D 提升阶段的难度。1.2 项目结构与关键文件从 GitHub 官方仓库拿到的代码虽然文件多但核心路径很清晰。仓库根目录下主要有 inference、common、data、model、scripts 这几个目录。inference 里放着推理脚本最常见的是 infer_video_d2.py它会自动调用 Detectron2 检测关键点然后加载 VideoPose3D 预训练权重最终输出可视化视频如果你只用现成的 2D 关键点文件也可以绕开 Detectron2。common 里是一些公共模块比如 camera.py 处理相机参数losses.py 定义训练损失utils.py 处理日志和检查点。model 目录就是网络结构定义VideoPose3D 的核心模型在 common/model.py 里可以找到对应实现本质是一组时间卷积层加残差连接。data 目录通常不直接放数据集而是放准备数据的脚本比如 prepare_data_h36m.py 用来下载并预处理 Human3.6M 数据。scripts 目录下则有 run.py 之类的训练与评估入口。对新手来说不需要一开始把每个文件都读懂先跑通 demo 最重要。我建议按这个顺序来先把 infer_video_d2.py 的流程走完再回头看 common/camera.py 里的坐标变换逻辑最后有兴趣再研究 model 的时间卷积结构。这样学习曲线比较缓不容易被一堆抽象类吓跑。1.3 为什么还值得玩它现在市面上的 3D 姿态方案已经很多VideoPose3D 依然是值得一玩的原因有三。第一是轻量它的模型参数量不大甚至 CPU 都能跑推理比起某些需要超大显存的端到端模型友好太多适合没有好显卡的同学。第二是模块化二阶段方案意味着你可以随意替换 2D 检测器今天用 Detectron2明天用 MediaPipe只要把关键点格式转成模型需要的格式就能继续跑。第三是透明度高输出的是关节坐标不是黑盒结果方便后续计算关节角度、肢体速度、运动范围等运动学指标这点对生物力学分析或者康复评估特别有用。如果你想理解一个完整 3D 视觉项目从视频输入到结构化输出的链路VideoPose3D 几乎是教科书级别的范例。它不涉及复杂的多模态对齐也不需要 3D 标注数据却把“视频 → 2D 关键点 → 3D 坐标 → 可视化”这条最重要的技术栈讲得明明白白。2. 环境搭建全流程2.1 先想清楚版本选型再动手环境搭建最怕的不是命令复杂而是版本乱配。VideoPose3D 本身对 PyTorch 版本要求不算极端真正的坑在于 Detector2。官方 demo 默认会调用 Detectron2 作为 2D 检测器而 Detectron2 的编译和运行与 PyTorch、CUDA 版本强绑定版本不对就编译失败或者 import 的时候直接报错。我实际使用的配置是 Ubuntu 20.04Python 3.8CUDA 11.3PyTorch 1.10.0Detectron2 用了 0.6 的预编译版本跑官方 demo 一路顺利。后来在一台 CUDA 11.7 的机器上用 PyTorch 1.13 Detectron2 0.6 也能跑但编译过程更久也更容易遇上 gcc 版本问题。如果你不是非要最新特性建议选稳定组合不要盲目追新。官网 README 的时间线比较早拿最新 PyTorch 去跑老代码经常会在 torch 的 API 变动上翻车。以下组合供参考PyTorch 版本CUDA 版本推荐 PythonDetectron2 方式1.10.011.33.8源码编译或预编译 wheel1.12.011.63.8 / 3.9预编译 wheel 较方便1.13.011.73.8 / 3.9源码编译需注意 gcc 版本如果你已经装好了更高版本的 PyTorch 也不要慌先跑python -c import torch; print(torch.__version__, torch.cuda.is_available())确认 torch 本身正常再尝试安装对应版本的 Detectron2如果反复报错最稳妥的办法是新建一个环境单独装一套期望的版本组合避免影响你正在用的深度学习环境。2.2 创建虚拟环境并安装 PyTorch我习惯用 conda 管理 Python 环境因为当你想尝试不同版本 PyTorch 时环境隔离可以避免把系统 Python 弄乱。创建环境指定 Python 3.8之后就算装错也能一键删掉重建。安装 PyTorch 建议直接用 pip按官网给出的 wheel 下载地址指定 CUDA 版本。下面以 CUDA 11.7 为例conda create -n videopose python3.8 -y conda activate videopose pip install torch1.13.0 torchvision0.14.0 --index-url https://download.pytorch.org/whl/cu117安装完成后立刻验证 CUDA 是否可用python -c import torch; print(torch.__version__, torch.cuda.is_available(), torch.cuda.get_device_name(0))这一步非常重要。很多同学装完 torch 就急着装后续依赖结果最后跑 demo 才发现模型被加载到了 CPU速度慢得离谱或者干脆报 CUDA 不可用。如果输出里torch.cuda.is_available()是 False先检查显卡驱动在终端执行nvidia-smi看驱动版本以及支持的 CUDA 版本驱动太老的话即使你 pip 安装了 cu117 的 torch 也无法使用 GPU。2.3 安装 Detectron2 及其他依赖Detectron2 的安装是整个环境搭建里最繁琐的一步。如果你直接从源码编译需要先安装 gcc、g、python3-dev 等工具源码目录下执行git clone https://github.com/facebookresearch/detectron2.git cd detectron2 pip install -e .源码编译经常要编译十几分钟甚至更长中间如果遇到 gcc 版本和 CUDA 不匹配还会中断。预编译 wheel 会快很多但依赖匹配关系需要自己找对版本常见的小坑是预编译包只支持某个特定范围内的 torch 版本。对于官方 demo 来说Detectron2 的作用只是提供 2D 关键点如果你实在装不上也可以走另一条路用 OpenPose、AlphaPose 或者 MediaPipe 提取 2D 关键点保存成模型能读的格式再让 VideoPose3D 做 3D 提升。后面第 3 节我会详细说这条替代路线的操作思路。还需要安装的依赖包括 opencv-python、numpy、matplotlib、tqdm、json5 等多数在官方 requirements 里已经列好。你可以直接在仓库根目录执行pip install -r requirements.txt如果项目没有 requirements 文件就手动装一下上面那几项。注意 numpy 版本不要用太新某些老代码里np.int的写法在新版 numpy 里会报错遇到这种情况把 numpy 降到 1.23.x 左右即可。2.4 下载源码与预训练权重接下来把 VideoPose3D 源码克隆到本地git clone https://github.com/facebookresearch/VideoPose3D.git cd VideoPose3D仓库里通常带一个 checkpoints 目录说明但权重文件你需要单独下载。官方提供了在 Human3.6M 数据集上训练好的预训练模型文件名类似于pretrained_h36m_cpn.bin或者pretrained_h36m_detectron_coco.bin。如果不提前下载好运行 demo 时脚本会尝试在线加载网络不好的时候会卡住或者报下载失败。我的建议是提前把权重下载到 checkpoints 目录并在脚本参数里指定对应的检查点文件名。权重文件比较大下载时要有耐心。如果官方下载链接访问不稳定可以换个时间段重试或者在别的机器上先下载好再拷贝到目标机器。2.5 验证环境是否完整环境装完先别急着跑自己的视频我建议先用官方 demo 验证一遍完整链路。仓库里如果有示例视频直接拿它测试如果没有就随便拍一段几秒钟的走路视频当作测试输入。跑通官方 demo 之后再换成自己的视频这样排查问题时能分清是环境问题还是视频内容问题。验证命令一般长这样python inference/infer_video_d2.py \ --cfg detectron2/configs/COCO-Keypoints/keypoint_rcnn_R_50_FPN_3x.yaml \ --video-file test.mp4 \ --output out.mp4不同版本的脚本参数名可能略有差异运行前先通过python inference/infer_video_d2.py --help确认一下当前脚本支持的参数以实际提示为准。如果这步能跑通说明环境就绪接下来就可以研究怎么把自己的视频跑得更好看。3. 制作自己的视频完整实操3.1 准备一段合适的输入视频VideoPose3D 对输入视频有基本要求人物要完整出现在画面中尽量正面朝向相机背景不要过于杂乱单人场景效果最稳。手机拍的原片分辨率很高直接拿去跑不是不行但 Detectron2 在 1080p 以上分辨率上推理速度会明显下降显存占用也大。我建议先做预处理用 ffmpeg 把视频压到 720p 左右帧率统一到 30fps编码用 H.264ffmpeg -i input.mp4 -vcodec libx264 -vf scale720:-2 -r 30 input_prepared.mp4这里的scale720:-2表示宽度缩放到 720高度按比例自适应并保持偶数避免编码器报错。为什么要压到 30fps因为 VideoPose3D 的时间卷积依赖帧间连续性帧率太高如 60fps 或 120fps会导致相邻帧之间人物位移太小反而不利于模型捕捉运动信息帧率太低则运动轨迹会显得生硬30fps 是比较平衡的选择。另外视频长度也需要注意。如果拍了一段 5 分钟的长视频又不做裁剪后面可视化阶段会浪费大量时间。我一般先用 ffmpeg 截取 5 到 20 秒的关键片段比如ffmpeg -i input_prepared.mp4 -ss 00:00:03 -t 10 clip.mp4这样便于快速迭代调参确认效果稳定后再跑完整视频。3.2 跑通官方推理脚本以官方 inference/infer_video_d2.py 为例整个推理可以分为几个步骤video 文件读入后Detectron2 对每一帧检测 2D 关键点关键点经过格式转换后按时间顺序拼接成序列VideoPose3D 模型读取序列输出每帧的 3D 坐标最后把 3D 骨架渲染成可视化的视频。这个脚本会自动处理检测、推理和渲染最适合新手第一次跑通。参数配置上你需要指定 Detectron2 的关键点检测配置文件、输入视频路径、输出视频路径。如果有多个检测器权重或模型权重也要在参数里指定。具体参数名以仓库 README 或--help为准思路是一样的先让 2D 检测器工作再让 3D 提升模型工作。运行过程中如果显存不够可以把输入视频分辨率再降低一些或者关闭可视化窗口只保存输出文件。3.3 离线 2D 关键点流程官方脚本默认使用 Detectron2但实际项目中完全可以用其他 2D 检测器替代。这个替代思路特别适合 Detectron2 编译失败的情况或者你已经有一批现成的 2D 关键点想直接上 3D。具体做法是先用你熟悉的检测器对视频逐帧检测输出 COCO 格式的 17 个关键点保存为 JSON 或 NPZ 文件然后写一个小脚本把关键点坐标按照 VideoPose3D 期望的顺序和格式整理好最后调用模型进行 3D 推理不再走 Detectron2。这一步里最麻烦的是关键点顺序映射。VideoPose3D 在官方 demo 中使用的骨架定义来自 Human3.6M包含 17 个关节顺序和 COCO 17 点并不完全一致常见的映射关系如下COCO 关键点Human3.6M 对应关节left hipLHipright hipRHipleft kneeLKneeright kneeRKneeleft ankleLAnkleright ankleRAnkleleft shoulderLShoulderright shoulderRShoulderleft elbowLElbowright elbowRElbow这只是一个大致对照不同检测器的输出命名可能还有差异。建议你写的时候先打印出每个关键点的索引和坐标检查一下骨架连接是否正确再喂给 VideoPose3D。我第一次用 AlphaPose 替换时就是因为肩膀和胯部的索引顺序弄反导致输出骨架整体扭曲排查了很久。离线流程还有一个好处你可以对 2D 关键点做后处理比如填补短暂遮挡产生的缺失点或者对关键点坐标做平滑后再输入 3D 模型能明显改善输出稳定性。3.4 输出结果解读与导出最终输出的视频里你会看到一个人体骨架彩色线条连接着关节点背景通常是黑色的方便观察 3D 姿态。骨架会随人物动作变化同时整个人体看起来在三维空间里轻微旋转这是可视化脚本为了让观察者感受到深度信息而设置的视角变化。如果结果不理想先检查输入视频质量人物是否太小、遮挡是否严重、镜头是否快速移动。镜头抖动对 2D 关键点影响很大因为检测器在运动模糊帧上容易输出抖动坐标最终 3D 姿态也会跟着跳。如果你想保存 3D 坐标做后续分析注意仓库里通常有--viz-export或类似的参数可以输出一份关键点坐标文件。有了坐标你可以计算关节角度、重心变化、肢体速度等运动学指标这是把姿态估计落地到应用的关键一步。我经常用这些坐标直接分析走路过程中膝盖角度的变化曲线比肉眼观察视频直观得多。3.5 调参让结果更顺眼不同视频适合不同参数组合。如果人物在画面中比较小2D 检测器可能漏检可以考虑把输入分辨率调高一些同时放慢推理速度换取召回率。如果人物动作较大比如跳跃或者快速挥手时间卷积窗口可能不足以估计出平滑的 3D 轨迹这时可以尝试更换预训练权重或者降低帧率让相邻帧的运动变化更显著。可视化方面有些脚本支持调整输出视角如果你想固定某个角度观察姿态可以直接在渲染代码里改成固定相机视角或者干脆把每帧的 3D 坐标用 matplotlib 画出来旋转查看效果更灵活。我个人的经验是先跑一段 5 秒的小片段确认 2D 检测没有明显丢帧再调 3D 模型相关参数最后才跑完整视频。一次跑完整视频如果发现中间某段姿态崩了处理起来会很麻烦。4. 常见问题与排查实录4.1 环境类问题环境问题是最多人卡住的地方我把遇到的典型问题整理成一个排查表方便你对照处理现象可能原因解决思路torch.cuda.is_available() 为 False驱动太老或 PyTorch 版本与 CUDA 不匹配查看 nvidia-smi升级驱动或重装对应 cu 版本 torchdetectron2 import 报错torch 版本与预编译 wheel 不匹配换用源码编译或尝试匹配的 torch 版本编译 detectron2 失败缺少 gcc、python3-dev安装编译工具链后重试numpy 相关报错如 np.int 不存在numpy 版本过新降级 numpy 到 1.23.x导入 torchvision 报错torch 与 torchvision 版本不匹配同时安装匹配版本不要分别安装这类问题共同的处理思路是先确认基础版本再查上层依赖。我见过太多人一报错就疯狂搜索其实把python -c import torch; print(torch.__version__)以及编译日志贴出来问题原因马上就能定位。做环境搭建版本一致性永远排在第一位。4.2 数据与视频问题如果环境正常但结果不对问题很可能出在视频本身或者关键点检测环节。人物在画面里太小2D 检测器可能完全漏检输出视频里骨架消失人物被遮挡比如手放在身体后面关键点坐标会抖动甚至跳到另一侧多人场景下官方 demo 通常默认处理第一个检测框你需要根据参数指定跟踪某个特定人物否则可能出现人物切换骨架跟着跳。遇到这些情况我的建议是先单独跑一下 2D 检测器的可视化结果确认 2D 关键点是否稳定。如果 2D 关键点本身是乱的3D 结果不可能好。用 MediaPipe 或者 AlphaPose 的官方 demo 先看看中间结果这是很有效的排查手段。另外直接拿竖屏视频跑也有风险很多模型训练数据以横屏为主对竖屏视频的检测效果可能打折建议转成横屏或者先裁剪成模型友好的宽高比。4.3 权重与检查点问题预训练权重下载不全会导致模型加载报错。常见的报错信息是文件不存在或者加载时尺寸不匹配。检查点文件要放在脚本能扫描到的路径下并且在命令行参数里明确指定检查点名称。如果你下载的是在 CPN 关键点上训练的模型喂进去的 2D 关键点最好也是 CPN 检测器输出的格式如果是 Detectron2 关键点训练的模型就用 Detectron2 的 2D 关键点。预训练权重的训练数据分布会影响最终泛化效果这点严格来说不算 bug但很容易被忽略。如果你下载的权重和你使用的骨架定义不同模型在加载阶段就报错或者即便加载成功输出姿态也是歪的。权重和检测器匹配这件事是官方 demo 能通、换用自定义检测器后各种问题的常见原因。4.4 可视化与后处理问题最后一个常见类别是输出视频画质或者姿态不稳定的问题。由于 VideoPose3D 是逐序列预测的相邻时间窗之间的结果可能有些微跳变在长时间视频里会表现为骨架抖动。缓解办法有两种一是对 2D 关键点先做平滑滤波比如滑动平均或 Savitzky-Golay 滤波二是对输出的 3D 坐标再做一次时间维度的平滑。前者效果更直接因为 2D 关键点的抖动会直接传导到 3D 输出。不过平滑强度要适中太强的平滑会让人物动作看起来黏滞丧失真实运动细节。如果输出视频里的骨架比例看起来奇怪比如手臂过长或躯干扭曲先检查输入的分辨率和裁剪是否改变了人物的宽高比。相机内参也会影响 3D 姿态的绝对尺度但大部分情况下我们只关心姿态形状不关心绝对尺度所以这种比例问题多数不影响使用。5. 一点实操心得从零搭环境到跑通自己的视频我前前后后折腾了两天回头来看最花时间的不是模型原理而是版本匹配。PyTorch、Detectron2、CUDA 三者只要有一个对不上就可能白等一次编译。所以我的第一条体会是环境搭建要“锁版本”锁死一套经过验证的组合而不是追求最新。第二点体会是中间结果可视化非常重要。不要等整个流程都跑完才看结果2D 关键点检测完就单独渲染一下确认人的关节位置是对的3D 模型跑完再快速看几帧坐标确认深度方向没有反转。这样每一步都有反馈排错效率会高很多。最后再分享一个小技巧如果你只是想在项目演示里展示 3D 姿态别用真人视频里带背景的那种输出建议把背景改成纯黑并使用固定视角渲染视觉上会专业很多。如果后续想进一步扩展可以在 VideoPose3D 的输出坐标基础上接入关节角度计算逻辑比如分析深蹲时膝盖角度变化曲线或者走路时骨盆倾斜角度。这个项目真正的价值并不只是显示骨架而是它给了你一份干净、连续、有序的 3D 关节数据面向运动分析、动作比对、康复评估这类场景时它就是很好的底层基础。