ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

DensePose apply_net 工具实战:Dump 模式批量导出推理结果与 Show 模式多形态可视化

DensePose apply_net 工具实战:Dump 模式批量导出推理结果与 Show 模式多形态可视化 DensePose apply_net 工具实战Dump 模式批量导出推理结果与 Show 模式多形态可视化【免费下载链接】detectron2Detectron2 is a platform for object detection, segmentation and other visual recognition tasks.项目地址: https://gitcode.com/GitHub_Trending/de/detectron2本指南围绕 Detectron2 项目中 DensePose 子项目自带的apply_net命令行工具展开它是 DensePose 官方用于在任意图片集合上打印导出与可视化模型推理结果的一站式工具也是 DensePose 入门文档GETTING_STARTED.md推荐的推理入口。读完本文你将掌握apply_net两种工作模式dump与show的完整命令行用法、输出文件的数据结构与 Python 解析方式以及 8 种可视化类型的含义与源码级实现原理可直接用于 DensePose 模型的批量推理、结果落盘与效果调试。工具概览一个入口、两种模式apply_net是 DensePose 提供的一体化推理/可视化工具定义在 apply_net.py 中。它通过 argparse 子命令注册了两种动作源码中的DumpAction与ShowAction分别对应COMMAND dump与COMMAND showdump模式对一组图片执行 DensePose 推理将每个检测实例的得分、边界框与 DensePose 预测结果序列化保存到一个 pickle 文件中方便后续离线分析或二次处理show模式对一组图片执行推理并把结果直接绘制到图片上输出可视化的 PNG/JPG 文件便于直观查看模型效果。两种模式都继承自InferenceAction基类共享同一套推理管线读取配置 → 加载模型权重 → 构造DefaultPredictor→ 逐图推理 → 按模式分发处理。因此下面的「运行环境与通用前提」对两种模式同样适用。运行环境与通用前提在运行apply_net之前需要确认以下几点以当前仓库为准工作目录命令默认从 projects/DensePose 目录下执行否则需调整配置与模型文件的相对路径配置文件必须使用 DensePose 专用配置例如 IUV 模型配置 densepose_rcnn_R_50_FPN_s1x.yaml或 CSE 模型配置 cse/densepose_rcnn_R_50_FPN_s1x.yaml。普通 Detectron2 配置不包含ROI_DENSEPOSE_HEAD相关项无法直接使用——源码中正是通过add_densepose_config(cfg)InferenceAction.setup_config注入 DensePose 的配置项模型文件DensePose 预训练模型权重可从 DensePose 模型库获取IUV 系列与 CSE 系列的模型清单分别见 DENSEPOSE_IUV.md 与 DENSEPOSE_CSE.md。模型权重也支持 detectron2 的detectron2://与本地路径见配置文件中的MODEL.WEIGHTS字段输入图片可以是单个图片文件、一个目录目录内所有文件都会被处理或一个通配符模式如image*.jpg依赖除 Detectron2 本身外show模式依赖 OpenCVcv2dp_contour可视化在安装 matplotlib 时使用 matplotlib 绘制否则回退到自研的 marching squares 实现见 densepose_results.py 末尾的 try/except 分支。原文档示例中使用的image.jpg取自 COCO train2017 中的000000117508.jpg一张含人物的街景图实际使用时替换为任意含人体的图片即可。Dump 模式把推理结果导出为 pickle 文件命令格式与参数dump模式的通用命令形式如下python apply_net.py dump [-h] [-v] [--output dump_file] config model input三个必选位置参数参数含义config给定模型的配置文件DensePose 专用 YAMLmodel训练好的模型权重文件input输入图片单个文件、目录或文件名通配模式可选参数--output用于指定输出文件名。原文档描述其默认值为output.pkl但需要说明的是当前仓库源码DumpAction.add_arguments见 apply_net.py中该参数的实际默认值是results.pkl以源码为准-v可叠加使用以提高日志详细程度verbosity_to_level将-v次数映射为日志级别。实操示例示例 1处理目录中的全部图片将目录images中所有图片的 DensePose 推理结果R_50_FPN_s1x 模型导出到dump.pklpython apply_net.py dump configs/densepose_rcnn_R_50_FPN_s1x.yaml \ model_final.pkl \ images --output dump.pkl -v示例 2按文件名模式筛选图片将文件名匹配image*.jpg的图片结果导出到results.pklpython apply_net.py dump configs/densepose_rcnn_R_50_FPN_s1x.yaml \ model_final.pkl \ image*.jpg --output results.pkl -v其中model_final.pkl替换为从模型库下载的 R_50_FPN_s1x 权重文件路径。源码中的输入解析逻辑input参数的三种形态在InferenceAction._get_input_file_list中按序判定见 apply_net.py若input_spec是目录os.path.isdir则列出目录内所有文件os.path.isfile过滤子目录拼接完整路径若input_spec是文件os.path.isfile则仅处理该文件否则将其当作glob.glob的通配模式处理。dump的执行流程为execute中对每张图片调用read_image(file_name, formatBGR)预测器期望 BGR 输入在torch.no_grad()下执行predictor(img)[instances]随后由execute_on_outputs组装每条结果最终postexecute用torch.save(context[results], hFile)将结果列表写入 pickle 文件并在输出目录不存在时自动创建os.makedirs。读取与解析 pickle 文件dump产出的 pickle 文件内容为「每张图片一条结果」的列表每条结果是一个字典。加载方式如下# 确保 DensePose 在 PYTHONPATH 中或手动添加 sys.path.append(/your_detectron2_path/detectron2_repo/projects/DensePose/) f open(/your_result_path/results.pkl, rb) data pickle.load(f)IUV 模型dump 结果的数据格式如果使用IUV 模型基于 chart 的参数化方法模型列表见 DENSEPOSE_IUV.md导出数据形如data: [{file_name: /your_path/image1.jpg, scores: tensor([0.9884]), pred_boxes_XYXY: tensor([[ 69.6114, 0.0000, 706.9797, 706.0000]]), pred_densepose: [DensePoseChartResultWithConfidences(labelstensor(...), uvtensor(...), sigma_1None, sigma_2None, kappa_uNone, kappa_vNone, fine_segm_confidenceNone, coarse_segm_confidenceNone), DensePoseChartResultWithConfidences, ...] } {file_name: /your_path/image2.jpg, scores: tensor([0.9999, 0.5373, 0.3991]), pred_boxes_XYXY: tensor([[ 59.5734, 7.7535, 579.9311, 932.3619], [612.9418, 686.1254, 612.9999, 704.6053], [164.5081, 407.4034, 598.3944, 920.4266]]), pred_densepose: [DensePoseChartResultWithConfidences(labelstensor(...), uvtensor(...), sigma_1None, sigma_2None, kappa_uNone, kappa_vNone, fine_segm_confidenceNone, coarse_segm_confidenceNone), DensePoseChartResultWithConfidences, ...] }]其中DensePoseChartResultWithConfidences定义在 chart_result.py字段含义如下labels形状为[H, W]、类型torch.long的张量保存精细分割标签即旧称的I每个像素对应一个身体部位编号uv形状为[2, H, W]、类型torch.float的张量保存每个像素的U、V参数化坐标二者取值均在[0, 1]区间对应类文档注释中「每个 chart 是一个由 U、V 两个坐标参数化的二维流形」若干可选的置信度字段sigma_1、sigma_2、kappa_u、kappa_v、fine_segm_confidence、coarse_segm_confidence均为形状[H, W]的 float 张量未启用置信度预测时这些字段为None如上例所示。值得一提的是源码还在DensePoseChartResult基础上提供了量化压缩的存储变体quantize_densepose_chart_result将labels与uv打包成[3, H, W]的 uint8 张量Uq U * 255、Vq V * 255compress_quantized_densepose_chart_result再将其视作三通道图像做 PNG 压缩并 Base64 编码适合对结果做紧凑序列化同见 chart_result.py。CSE 模型dump 结果的数据格式如果使用CSE 模型基于连续表面嵌入的方法模型列表见 DENSEPOSE_CSE.md导出数据形如data: [{file_name: /your_path/image1.jpg, scores: tensor([0.9984, 0.9961]), pred_boxes_XYXY: tensor([[480.0093, 461.0796, 698.3614, 696.1011], [78.1589, 168.6614, 307.1287, 653.8522]]), pred_densepose: DensePoseEmbeddingPredictorOutput(embeddingtensor(...), coarse_segmtensor(...))} {file_name: /your_path/image2.jpg, scores: tensor([0.9189, 0.9491]), pred_boxes_XYXY: tensor([[734.9685, 534.2003, 287.3923, 254.8859], [434.2853, 765.1219, 132.1029, 867.9283]]), pred_densepose: DensePoseEmbeddingPredictorOutput(embeddingtensor(...), coarse_segmtensor(...))}]DensePoseEmbeddingPredictorOutput定义在 cse.py字段含义如下embedding形状为[N, D, sz, sz]、类型torch.float的张量保存图像中N个检测实例的、维度为D的嵌入向量源码注释指明D MODEL.ROI_DENSEPOSE_HEAD.CSE.EMBED_SIZEcoarse_segm形状为[N, 2, sz, sz]、类型torch.float的张量保存N个检测实例的分割得分例如可通过coarse_segm.argmax(dim1)得到二值掩膜源码注释指明类别通道数K MODEL.ROI_DENSEPOSE_HEAD.NUM_COARSE_SEGM_CHANNELS2对应背景/前景两类。其中sz是固定尺寸如需与原图对齐可将其缩放到对应边界框的尺寸。解析示例读取第一个实例的 UV以下代码取出第一张图片上第一个被检测实例的边界框与 UV 结果IUV 模型img_id, instance_id 0, 0 # Look at the first image and the first detected instance bbox_xyxy data[img_id][pred_boxes_XYXY][instance_id] result data[img_id][pred_densepose][instance_id] uv result.uv数组bbox_xyxy保存了边界框的(x0, y0, x1, y1)四个坐标result.labels与result.uv均可按像素级张量继续处理例如绘制热力图、统计部位面积等。Show 模式把推理结果可视化到图片上命令格式与参数show模式的通用命令形式如下python apply_net.py show [-h] [-v] [--min_score score] [--nms_thresh threshold] [--output image_file] config model input visualizations四个必选位置参数中前三个与dump相同第四个visualizations为逗号分隔的可视化类型列表当前支持的类型如下可视化类型说明适用模型bbox检测到的人体边界框IUV / CSEdp_segm检测到的人体精细分割掩膜IUVdp_u各身体部位按 U 坐标估计值着色IUVdp_v各身体部位按 V 坐标估计值着色IUVdp_contour以颜色编码的 U、V 坐标等值线图IUVdp_iuv_texture将给定纹理图转移到检测实例上IUVdp_vertex对给定网格输出最近顶点预测的彩虹可视化CSEdp_cse_texture将纹理图列表每个人体/动物网格一张转移到检测实例上CSE可选参数--min_score score只显示得分不低于该值的检测。源码中默认值为0.8且该参数会通过opts覆盖为MODEL.ROI_HEADS.SCORE_THRESH_TEST见ShowAction.setup_config即同时作用于模型推理阶段的后处理阈值--nms_thresh threshold对检测结果额外应用指定阈值的非极大值抑制内部映射为MODEL.ROI_HEADS.NMS_THRESH_TEST不传则保持配置默认值--output image_file输出文件名模板。原文档描述默认值为output.png当前源码中的实际默认值为outputres.png见ShowAction.add_arguments以源码为准。为区分不同图片的输出工具会按 1 起始的条目序号追加到文件名中例如output.0001.png、output.0002.png……_get_out_fname使用base .{0:04d}.format(entry_idx) ext拼接--texture_atlas texture_atlasIUV 纹理转移所用的纹理图集texture atlas图像--texture_atlases_map texture_atlases_mapCSE 纹理转移所用的纹理图集映射形如{网格名: 纹理图集路径}的 JSON 字符串。源码中get_texture_atlases用json.loads解析后为每个网格名调用get_texture_atlas加载对应图像见 densepose_outputs_vertex.py。实操示例ResNet-50 FPN 骨干网络以下示例均以image.jpg为输入模型为 R_50_FPN_s1x。注意 IUV 与 CSE 两类模型权重需从各自模型库下载model_final.pkl为占位符请替换为实际权重文件路径。1. 显示边界框与分割掩膜python apply_net.py show configs/densepose_rcnn_R_50_FPN_s1x.yaml \ model_final.pkl \ image.jpg bbox,dp_segm -v2. 显示边界框与身体部位 U 坐标python apply_net.py show configs/densepose_rcnn_R_50_FPN_s1x.yaml \ model_final.pkl \ image.jpg bbox,dp_u -v3. 显示边界框与身体部位 V 坐标python apply_net.py show configs/densepose_rcnn_R_50_FPN_s1x.yaml \ model_final.pkl \ image.jpg bbox,dp_v -v4. 以等值线形式显示 U、V 坐标python apply_net.py show configs/densepose_rcnn_R_50_FPN_s1x.yaml \ model_final.pkl \ image.jpg dp_contour,bbox -v5. IUV 纹理转移python apply_net.py show configs/densepose_rcnn_R_50_FPN_s1x.yaml \ model_final.pkl \ image.jpg dp_iuv_texture,bbox --texture_atlas texture_from_SURREAL.jpg -v6. CSE 彩虹顶点可视化python apply_net.py show configs/cse/densepose_rcnn_R_50_FPN_s1x.yaml \ model_cse.pkl \ image.jpg dp_vertex,bbox -v7. CSE 纹理转移python apply_net.py show configs/cse/densepose_rcnn_R_50_FPN_s1x.yaml \ model_cse.pkl \ image.jpg dp_cse_texture,bbox --texture_atlases_map {smpl_27554: smpl_uvSnapshot_colors.jpg} -v其中smpl_27554是 DensePose CSE 使用的 SMPL 人体网格名网格与纹理数据由工具按需加载纹理图文件如texture_from_SURREAL.jpg、smpl_uvSnapshot_colors.jpg需要由用户自行准备原文档指出它们位于 DensePose 发行版中的doc/images目录下。注意示例 57 中 IUV 与 CSE 的配置、模型、可视化类型与纹理参数必须配套使用混用会导致类型不匹配错误。源码中的可视化管线show模式的可视化类型与实现类一一对应注册在ShowAction.VISUALIZERS字典中见 apply_net.py命令行名称可视化器类dp_contourDensePoseResultsContourVisualizerdp_segmDensePoseResultsFineSegmentationVisualizerdp_uDensePoseResultsUVisualizerdp_vDensePoseResultsVVisualizerdp_iuv_textureDensePoseResultsVisualizerWithTexturedp_cse_textureDensePoseOutputsTextureVisualizerdp_vertexDensePoseOutputsVertexVisualizerbboxScoredBoundingBoxVisualizercreate_context会按逗号切分visualizations参数为每个可视化器创建配套的提取器create_extractor再用CompoundVisualizer与CompoundExtractor组合成整体execute_on_outputs中每张图片的处理细节值得注意输入图片先被cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)转成灰度图再np.tile复制成三通道——这意味着show模式的可视化底图是灰度底图DensePose 结果以彩色叠加显示原图彩色信息被丢弃extractor(outputs)从模型输出中抽取 DensePose 结果与边界框visualizer.visualize(image, data)将结果绘制到底图上按序号生成输出文件名并cv2.imwrite落盘。从实现细节可以进一步理解各类可视化的差异见 densepose_results.pydp_segm/dp_u/dp_v都是DensePoseMaskedColormapResultsVisualizer的变体内部用MatrixVisualizer以 PARULA 色彩映射、alpha0.7叠加绘制三者的区别仅在于从 IUV 数组中提取哪个通道I/U/V作为着色数据、以哪个通道作为掩膜dp_contour优先使用 matplotlib 绘制等值线DensePoseResultsMplContourVisualizer将 U、V 各自归一化到[0, 1]后分别调用plt.contour叠加在图片上未安装 matplotlib 时自动回退到基于 marching squares 的自研实现DensePoseResultsCustomContourVisualizerdp_vertex通过get_closest_vertices_mask_from_ES为每个像素找到嵌入空间中最接近的网格顶点再用 JET 色彩映射渲染见 densepose_outputs_vertex.pydp_cse_texture则利用网格的纹理坐标mesh.texcoords把纹理图按 UV 采样到检测区域上支持带 alpha 通道的纹理图做半透明融合。底层推理流程两种模式共享的调用链无论dump还是show最终都走InferenceAction.execute的固定管线见 apply_net.pysetup_config(config_fpath, model_fpath, args, opts)get_cfg()创建默认配置 →add_densepose_config(cfg)注册 DensePose 专属配置项 →cfg.merge_from_file(config_fpath)合并 YAML → 合并--opts命令行键值对 → 设置cfg.MODEL.WEIGHTS model_fpath→cfg.freeze()冻结配置DefaultPredictor(cfg)构建预测器预测器内部会根据MODEL.WEIGHTS加载权重并自动将模型切到 GPU/CPU 与 eval 模式_get_input_file_list(args.input)解析输入文件/目录/通配模式逐图执行img read_image(file_name, formatBGR)→outputs predictor(img)[instances]→execute_on_outputs(...)分发到dump的「组装字典」或show的「绘制落盘」最后调用postexecute(...)dump写 pickle 文件show为空操作。show模式相比dump多了一个配置注入步骤ShowAction.setup_config会把--min_score默认 0.8写入MODEL.ROI_HEADS.SCORE_THRESH_TEST并在提供--nms_thresh时写入MODEL.ROI_HEADS.NMS_THRESH_TEST从而在推理阶段就控制检出质量。数据落地与后续处理建议dump 结果与边界框pred_boxes_XYXY是[N, 4]的浮点张量行序与pred_densepose列表一一对应若要按得分筛选可对scores做阈值过滤后再索引像素级 UV 应用IUV 的labels/uv尺寸为边界框内部尺寸H × W需要结合bbox_xyxy做坐标平移与缩放才能映射回原图CSE 的embedding/coarse_segm为固定sz × sz同样需要 resize存储体积若结果需要长期保存或跨网络传输可考虑使用quantize_densepose_chart_resultcompress_quantized_densepose_chart_result的 PNG/Base64 压缩方案定义见 chart_result.py解压侧提供decompress_compressed_densepose_chart_result还原与其他工具配合apply_net定位为「模型推理结果」的导出与可视化若需查看数据集标注则使用配套的query_db工具详见 TOOL_QUERY_DB.md训练与评估请使用 train_net.py用法见 GETTING_STARTED.md。常见问题速查现象排查方向报错缺少ROI_DENSEPOSE_HEAD配置确认使用的是 DensePose 配置如 densepose_rcnn_R_50_FPN_s1x.yaml而非纯 Detectron2 配置且从projects/DensePose目录运行以便导入densepose包模型与可视化类型不匹配dp_iuv_texture等 IUV 可视化必须配 IUV 权重dp_vertex/dp_cse_texture必须配 CSE 权重与 CSE 配置输出文件名为outputres.*而非预期--output未指定时当前源码默认值为outputres.png原文档写output.png以源码为准输出会附加0001等序号没有检测结果调低--min_score默认 0.8或检查--nms_thresh是否过小dump 默认文件名未传--output时默认写入results.pkl当前源码值原文档描述为output.pkl综上apply_net是衔接 DensePose 模型与业务应用的关键桥梁dump面向数据流水线show面向效果展示与调参验证两者共享一套配置驱动、逐图推理的轻量架构配合本文给出的参数说明与源码依据足以支撑起完整的 DensePose 批量推理与可视化工作流。【免费下载链接】detectron2Detectron2 is a platform for object detection, segmentation and other visual recognition tasks.项目地址: https://gitcode.com/GitHub_Trending/de/detectron2创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进