DensePose in Detectron2:面向 IDM-VTON 的人体稠密姿态估计与预处理实战指南

原创2026-10-02 16:05:191,909 阅读
文章标签:计算机视觉深度学习媒体生成

DensePose in Detectron2:面向 IDM-VTON 的人体稠密姿态估计与预处理实战指南

DensePose 将传统稀疏人体关键点提升为"稠密对应关系":它把 RGB 图像中的每一个人体像素映射到人体三维表面,输出包含 24 个表面分片(part)与 U/V 参数化坐标的稠密结果,是连接 2D 图像与 3D 人体先验的桥梁。在 IDM-VTON(ECCV 2024 真实场景虚拟试穿方案)中,DensePose 被用作人物图像的关键预处理条件——本文以仓库内置的 DensePose in Detectron2 模块为核心,完整讲解其原理、模型库、配置体系、推理/训练/评估命令与结果可视化工具,读完即可在 IDM-VTON 的预处理链路中独立复现 image-densepose 的生成。

DensePose 是什么:从稀疏关键点到稠密人体表面

DensePose 由 Rıza Alp Güler、Natalia Neverova 与 Iasonas Kokkinos 提出,其核心目标是"稠密人体姿态估计"(Dense Human Pose Estimation In The Wild):将输入 RGB 图像中所有属于人体的像素,映射到人体三维表面的对应位置。与只输出数十个关节点的传统姿态估计不同,DensePose 为每个可见的人体像素都回归出稠密对应信息,因此也被称为"稠密人体对应估计"。

其输出结构由三部分组成(对应源码中 TOOL_APPLY_NET.md 描述的解码结果 iuv_arr,形状为 [3, H, W]):

通道 含义
iuv_arr[0,:,:] 表面分片索引(patch index),指示该点位于 24 个表面分片中的哪一块
iuv_arr[1,:,:] 该点在分片参数化下的 U 坐标
iuv_arr[2,:,:] 该点在分片参数化下的 V 坐标

这套"分片 + UV 坐标"表示法让 DensePose 结果天然适合作为生成式模型的几何条件,也是虚拟试穿任务中衡量衣服与人体贴合关系的重要依据。

DensePose 在 IDM-VTON 中的角色:image-densepose 预处理

在 IDM-VTON 的数据预处理链路中,DensePose 承担"人体稠密姿态/表面提取"的任务。仓库根目录 README.md 中明确列出了 image-densepose 这一预处理产物目录,说明其用于提供预计算的 densepose 图像与描述文本;同时致谢部分注明人体稠密姿态估计源自 DensePose 工作。

对应关系可从两处仓库证据印证:

  • 预训练权重已内置:仓库 ckpt/densepose/model_final_162be9.pkl 正是 DensePose in Detectron2 官方 Model Zoo 中 densepose_rcnn_R_50_FPN_s1x(model id 165712039)的模型文件;
  • 推理代码直接引用该目录:在 inference.py 中,人物图像路径以 os.path.join(self.dataroot, self.phase, "image-densepose", im_name) 拼接,说明人物分支读取的是 DensePose 预处理输出。

也就是说,在 IDM-VTON 中,DensePose 与人体解析(humanparsing)、OpenPose 姿态、法线图等共同构成人物的多模态条件,为后续扩散模型的换装生成提供几何与语义约束。

快速开始与模型库(Model Zoo)

DensePose in Detectron2 的完整入口文档位于 DensePose/README.md。模块提供了训练与评估 DensePose-RCNN 的完整代码,以及可视化 DensePose 标注与推理结果的一整套工具(apply_net、query_db、train_net)。

模型库一览

官方基线模型均训练于 COCO train2014 + valminusminival2014,在 COCO minival2014 上评测,对应配置存放在 projects/DensePose/configs 目录。按模型发展阶段可划分为四档(详细指标见 MODEL_ZOO.md):

  1. Legacy 模型:沿用 Güler et al. 2018 训练 schedule,如 densepose_rcnn_R_50_FPN_s1x_legacy.yaml、densepose_rcnn_R_101_FPN_s1x_legacy.yaml;
  2. 改进基线(Panoptic FPN Head):采用 Kirillov et al. 2019 的改进 schedule 与 FPN head,如 densepose_rcnn_R_50_FPN_s1x.yaml(对应本仓库内置权重,box AP 61.2 / dp. AP GPS 63.7 / GPSm 65.3)、densepose_rcnn_R_101_FPN_s1x.yaml;
  3. DeepLabV3 Head 系列(DL):在上一档基础上将回归头替换为 DeepLabV3,如 densepose_rcnn_R_50_FPN_DL_s1x.yaml、densepose_rcnn_R_101_FPN_DL_s1x.yaml;
  4. 置信度估计系列(WC1/WC2):按 Neverova et al. 2019 的思路额外回归 UV 坐标的置信度,如 densepose_rcnn_R_50_FPN_WC1_s1x.yaml、densepose_rcnn_R_50_FPN_DL_WC1_s1x.yaml、densepose_rcnn_R_101_FPN_DL_WC2_s1x.yaml 等。

模型下载遵循 Creative Commons Attribution-ShareAlike 3.0 许可。IDM-VTON 场景下直接使用仓库已下载好的 ckpt/densepose/model_final_162be9.pkl 即可,无需再自行下载。

配置体系解析

DensePose 的配置采用 detectron2 的 _BASE_ 继承机制,所有系列配置共享同一个基础文件 Base-DensePose-RCNN-FPN.yaml,其关键结构如下:

MODEL:
  META_ARCHITECTURE: "GeneralizedRCNN"
  BACKBONE:
    NAME: "build_resnet_fpn_backbone"
  RESNETS:
    OUT_FEATURES: ["res2", "res3", "res4", "res5"]
  FPN:
    IN_FEATURES: ["res2", "res3", "res4", "res5"]
  ANCHOR_GENERATOR:
    SIZES: [[32], [64], [128], [256], [512]]
    ASPECT_RATIOS: [[0.5, 1.0, 2.0]]
  DENSEPOSE_ON: True
  ROI_HEADS:
    NAME: "DensePoseROIHeads"
    NUM_CLASSES: 1
  ROI_DENSEPOSE_HEAD:
    NAME: "DensePoseV1ConvXHead"
    NUM_COARSE_SEGM_CHANNELS: 2
DATASETS:
  TRAIN: ("densepose_coco_2014_train", "densepose_coco_2014_valminusminival")
  TEST: ("densepose_coco_2014_minival",)
SOLVER:
  IMS_PER_BATCH: 16
  BASE_LR: 0.01
  STEPS: (60000, 80000)
  MAX_ITER: 90000
  WARMUP_FACTOR: 0.1
INPUT:
  MIN_SIZE_TRAIN: (640, 672, 704, 736, 768, 800)

要点解读:

  • 整体架构为 GeneralizedRCNN(Faster R-CNN 两阶段范式):先由 RPN 在 FPN 的 p2–p6 特征上产出候选框,再由 DensePoseROIHeads 同时完成框回归与稠密姿态回归;
  • DENSEPOSE_ON: True 与 ROI_HEADS.NAME: "DensePoseROIHeads" 是启用 DensePose 分支的关键开关;
  • ROI_DENSEPOSE_HEAD.NUM_COARSE_SEGM_CHANNELS: 2 对应"粗分割"输出 2 类(前景/背景),细分的 24 分片与 UV 坐标由网络其余分支回归;
  • 数据侧默认使用 COCO DensePose 标注(train / valminusminival / minival 三份)。

具体的模型配置只在基础文件之上做少量覆盖,例如最常用的 densepose_rcnn_R_50_FPN_s1x.yaml:

_BASE_: "Base-DensePose-RCNN-FPN.yaml"
MODEL:
  WEIGHTS: "detectron2://ImageNetPretrained/MSRA/R-50.pkl"
  RESNETS:
    DEPTH: 50
SOLVER:
  MAX_ITER: 130000
  STEPS: (100000, 120000)

而 densepose_rcnn_R_50_FPN_DL_s1x.yaml 仅将 ROI_DENSEPOSE_HEAD.NAME 替换为 DensePoseDeepLabHead;带置信度的 densepose_rcnn_R_50_FPN_DL_WC1_s1x.yaml 则额外开启:

UV_CONFIDENCE:
  ENABLED: True
  TYPE: "iid_iso"
POINT_REGRESSION_WEIGHTS: 0.0005

其中 POINT_REGRESSION_WEIGHTS 控制回归损失的权重,UV_CONFIDENCE.TYPE: "iid_iso" 表示对 UV 坐标采用各向同性独立高斯的不确定性建模。

推理与可视化:apply_net 工具

apply_net 是模块内最核心的推理工具(脚本见 apply_net.py),提供 dump(把结果序列化到 pickle)与 show(直接在图像上可视化)两种模式。详细说明见 TOOL_APPLY_NET.md。

Dump 模式:批量推理并保存结果

通用命令形式:

python apply_net.py dump [-h] [-v] [--output <dump_file>] <config> <model> <input>

三个必填参数:

  • <config>:模型对应的配置文件;
  • <model>:训练好的模型权重文件;
  • <input>:输入图像的文件名、通配模式或文件夹。

--output 指定输出文件名,默认 output.pkl。两个典型示例:

# 对整个文件夹 images 推理,结果存到 dump.pkl
python apply_net.py dump configs/densepose_rcnn_R_50_FPN_s1x.yaml DensePose_ResNet50_FPN_s1x-e2e.pkl images --output dump.pkl -v

# 对匹配模式 "image*.jpg" 的图片推理
python apply_net.py dump configs/densepose_rcnn_R_50_FPN_s1x.yaml DensePose_ResNet50_FPN_s1x-e2e.pkl "image*.jpg" --output results.pkl -v

解析 pickle 结果

dump 生成的 pickle 文件是"每张图一个字典"的列表,字段包括 file_name、scores、pred_boxes_XYXY(检测框,格式 (x0, y0, x1, y1))与 pred_densepose(DensePoseResult 对象)。解析第一张图第一个实例的代码如下:

f = open('/your_result_path/results.pkl', 'rb')
data = pickle.load(f)

img_id, instance_id = 0, 0  # 第一张图、第一个检测实例
bbox_xyxy = data[img_id]['pred_boxes_XYXY'][instance_id]
result_encoded = data[img_id]['pred_densepose'].results[instance_id]
iuv_arr = DensePoseResult.decode_png_data(*result_encoded)

得到的 iuv_arr 即为前文所述的 [3, H, W] 稠密姿态张量,可直接用于下游任务(如写入 image-densepose 目录供 IDM-VTON 训练/推理使用)。

Show 模式:结果可视化

通用命令形式:

python apply_net.py show [-h] [-v] [--min_score <score>] [--nms_thresh <threshold>] [--output <image_file>] <config> <model> <input> <visualizations>

<visualizations> 支持的可视化类型:

标识 内容
bbox 检测到的人体边界框
dp_segm 人体分割掩膜
dp_u 按 U 坐标着色的身体分片
dp_v 按 V 坐标着色的身体分片
dp_contour 以 U/V 值着色的轮廓图

可选参数:--min_score 过滤低分检测;--nms_thresh 对检测施加非极大值抑制;--output 设置输出模板(默认 output.png,多张图时自动追加序号如 output.0001.png)。常用示例(对应 GETTING_STARTED.md 中的快速开始命令):

python apply_net.py show configs/densepose_rcnn_R_50_FPN_s1x.yaml densepose_rcnn_R_50_FPN_s1x.pkl image.jpg dp_contour,bbox --output image_densepose_contour.png

训练 DensePose-RCNN

数据准备

将 densepose.org 发布的数据集整理为如下结构(位于运行训练脚本的目录下):

datasets/coco/
  annotations/
    densepose_{train,minival,valminusminival}2014.json
  {train,val}2014/
    # 与 json 中 file_name 对应的图片文件

启动训练

训练统一使用 train_net.py(Model Zoo 中所有模型均由其训练得到)。8 卡训练 ResNet-50 FPN 骨干、s1x schedule 的命令:

python train_net.py --config-file configs/densepose_rcnn_R_50_FPN_s1x.yaml --num-gpus 8

官方配置按 8 卡设计(IMS_PER_BATCH: 16)。若只有 1 张卡,需按线性学习率缩放规则(linear scaling rule)同步缩小 batch 与学习率:

python train_net.py --config-file configs/densepose_rcnn_R_50_FPN_s1x.yaml \
    SOLVER.IMS_PER_BATCH 2 SOLVER.BASE_LR 0.0025

即 batch 从 16 缩到 2、BASE_LR 从 0.01 缩到 0.0025,保持 batch 与学习率的比例关系不变。

模型评估

评估与训练命令相同,追加 --eval-only 并通过 MODEL.WEIGHTS 指定权重路径:

python train_net.py --config-file configs/densepose_rcnn_R_50_FPN_s1x.yaml \
    --eval-only MODEL.WEIGHTS model.pth

评测指标沿用 COCO 风格的 box AP,以及 DensePose 专属的 dp. AP GPS、dp. AP GPSm(基于 UV 对应关系的平均精度)。

数据探索:query_db 工具

query_db(脚本见 query_db.py)用于从数据集中打印或可视化 DensePose 标注,同样有 print 与 show 两种模式,详见 TOOL_QUERY_DB.md。

  • print 模式:python query_db.py print [-h] [-v] [--max-entries N] <dataset> <selector>
  • show 模式:python query_db.py show [-h] [-v] [--max-entries N] [--output <image_file>] <dataset> <selector> <visualizations>

其中 <selector> 支持 field[:type]=value(精确匹配)或 field[:type]=min-max(区间匹配)的逗号分隔列表;show 模式的可视化类型包括 bbox、dp_i(按分片着色的标注点)、dp_pts(绿色标注点)、dp_segm、dp_u、dp_v。示例:

# 打印前 10 条训练标注
python query_db.py print densepose_coco_2014_train \* --max-entries 10 -v

# 按文件名精确筛选
python query_db.py print densepose_coco_2014_train file_name=COCO_train2014_000000000036.jpg -v

# 按 image_id 区间筛选并可视化
python query_db.py show densepose_coco_2014_train image_id:int=322 bbox,dp_segm -v

仓库源码结构导览

本仓库不仅内置了 DensePose 的预训练权重,还完整保留了 DensePose in Detectron2 的实现源码(位于 gradio_demo/densepose),便于二次开发:

从源码结构可以推断:DensePose 分支被设计为可插拔的 ROI Head 扩展,任何满足 detectron2 ROI_HEADS 接口的模型都可以通过配置替换 ROI_HEADS.NAME 与 ROI_DENSEPOSE_HEAD.NAME 切换不同回归头,这正是 IDM-VTON 可以将其复用为预处理模块的架构基础。

引用与许可

若在研究与开发中使用 DensePose,请按 DensePose/README.md 提供的 BibTeX 引用。原始论文:

@InProceedings{Guler2018DensePose,
  title={DensePose: Dense Human Pose Estimation In The Wild},
  author={R{i}za Alp Güler, Natalia Neverova, Iasonas Kokkinos},
  journal={The IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},
  year={2018}
}

带置信度估计的版本:

@InProceedings{Neverova2019DensePoseConfidences,
    title = {Correlated Uncertainty for Learning Dense Correspondences from Noisy Labels},
    author = {Neverova, Natalia and Novotny, David and Vedaldi, Andrea},
    journal = {Advances in Neural Information Processing Systems},
    year = {2019},
}

代码框架(detectron2)遵循 Apache 2.0 许可,Model Zoo 中的预训练模型遵循 CC BY-SA 3.0 许可,使用时请遵循对应条款。在 IDM-VTON 中,直接复用仓库内置的 ckpt/densepose/model_final_162be9.pkl 即可生成 image-densepose 预处理结果,无需自行训练。

登录后查看全文
IDM-VTON