OOTDiffusion 中的 DensePose 实战指南:基于 Detectron2 的稠密人体姿态估计推理、训练与可视化
2026/9/17 2:14:39 网站建设 项目流程

OOTDiffusion 中的 DensePose 实战指南:基于 Detectron2 的稠密人体姿态估计推理、训练与可视化

【免费下载链接】OOTDiffusion[AAAI 2025] Official implementation of "OOTDiffusion: Outfitting Fusion based Latent Diffusion for Controllable Virtual Try-on"项目地址: https://gitcode.com/GitHub_Trending/oo/OOTDiffusion

导读

本文以 OOTDiffusion 仓库内携带的 DensePose in Detectron2 文档为核心,系统讲解 Dense Human Pose Estimation In The Wild(稠密人体姿态估计)的核心原理、仓库中的代码组织结构、预训练模型推理、模型训练与评估,以及apply_net/query_db两大配套工具的使用方法。读者读完本文后,将能够利用仓库中现成的 DensePose-RCNN 配置与权重,完成从单张人体图像到 24 个表面块(patch)UV 坐标映射的完整推理管线,并掌握结果可视化、数据集查询与自定义训练的全流程操作。

DensePose 是什么:从稀疏关键点到稠密 UV 对应

按 DensePose README 的定义,稠密人体姿态估计(Dense Human Pose Estimation)的目标是:将一张 RGB 图像中的所有人体像素,一一映射到人体三维表面(3D surface of the human body)上。

与传统的稀疏人体姿态估计(通常只输出十几个关键点坐标,如 openpose 风格的关键点)不同,DensePose 为每个属于人体的像素都估计一个稠密对应关系,具体表现为:

  • 块索引(patch index / I):人体表面被划分为 24 个表面块(由 config.py 中的NUM_PATCHES = 24定义),每个像素属于哪一个块;
  • UV 坐标(U / V):在该表面块的参数化坐标系中的连续坐标值。

由此,DensePose 建立起"图像像素 ↔ 人体表面点"的稠密映射,这一能力可服务于服装贴合、人体纹理映射、虚拟试穿等下游任务。在 OOTDiffusion 的预处理模块中,DensePose 实现以 detectron2 扩展项目的形式被携带于 projects/DensePose 目录下,与人体解析(humanparsing)共用同一个 detectron2 框架(详见 detectron2 README 中 "Includes more features such as panoptic segmentation, densepose..." 的说明),为仓库的预处理链路提供了基于检测分割框架的稠密人体建模能力。

仓库中的 DensePose 模块结构

在深入使用之前,先梳理本仓库中 DensePose 相关文件的布局(根目录为preprocess/humanparsing/mhp_extension/detectron2/projects/DensePose/):

文件 / 目录作用
README.md项目总览:任务定义、快速开始、模型动物园、License 与引用
doc/GETTING_STARTED.md推理、训练、评估的完整操作指南
doc/MODEL_ZOO.md基线模型与指标汇总
doc/TOOL_APPLY_NET.mdapply_net推理结果导出与可视化工具说明
doc/TOOL_QUERY_DB.mdquery_db数据集条目打印与可视化工具说明
apply_net.pyapply_net工具源码(dump / show 两种模式)
query_db.pyquery_db工具源码(print / show 两种模式)
train_net.pyDensePose 训练 / 评估入口脚本
configs/全部基线模型对应的 YAML 配置文件
densepose/DensePose 核心模块:配置注入、数据、模型头、可视化等
tests/模型端到端与数据结构测试

快速上手:用预训练模型进行推理

根据 GETTING_STARTED.md,使用预训练模型推理只需两步:

  1. 选定模型与配置文件:从 Model Zoo 中挑选一个模型及其配置,例如 densepose_rcnn_R_50_FPN_s1x.yaml;
  2. 运行 Apply Net 工具完成可视化或结果落盘。例如使用轮廓(contour)可视化:
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

该命令的三个必选位置参数分别是:配置文件、权重文件、输入图片;dp_contour,bbox指定了要叠加的可视化类型。执行前需要把模型权重文件下载到本地(下载入口见 MODEL_ZOO.md 中的模型下载链接)。

apply_net:推理结果导出与可视化工具

apply_net 是 DensePose 官方提供的推理结果工具,拥有dump(保存结果)与show(可视化)两种模式。

dump 模式:把模型输出保存为 pickle 文件

通用命令形式为:

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

三个必选参数含义:

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

可选参数--output指定输出文件名(默认results.pkl)。

官方示例:

# 1) 对 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 # 2) 对匹配 image*.jpg 的图像执行推理并保存到 results.pkl 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

从 apply_net.py 源码 可以看到,<input>的处理逻辑是:目录则枚举目录内全部文件,单个文件则直接使用,否则当作glob通配模式展开——这解释了上面三种输入的等价性。

pickle 结果的结构:每个图像对应一个字典,保存了检测分数、边界框和稠密姿态结果,例如:

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': <densepose.structures.DensePoseResult object>}, {'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': <densepose.structures.DensePoseResult object>}]

结果解析代码示例(先保证 DensePose 在PYTHONPATH中,或临时追加其路径):

import sys, pickle sys.path.append("/your_detectron2_path/detectron2_repo/projects/DensePose/") 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] # (x0, y0, x1, y1) result_encoded = data[img_id]['pred_densepose'].results[instance_id] iuv_arr = DensePoseResult.decode_png_data(*result_encoded)

iuv_arr的形状为[3, H, W](H、W 为边界框尺寸),三个通道的含义是:

  • iuv_arr[0,:,:]:图像点的块索引,表示该点位于 24 个表面块中的哪一块;
  • iuv_arr[1,:,:]:该点的U 坐标值;
  • iuv_arr[2,:,:]:该点的V 坐标值。

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:只显示分数不低于该值的检测结果(在源码ShowAction.add_arguments中默认值为0.8,且会通过MODEL.ROI_HEADS.SCORE_THRESH_TEST注入配置);
  • --nms_thresh:对检测结果额外执行非极大值抑制(NMS),阈值由该参数给定;
  • --output:输出文件名模板(默认outputres.png);为区分多张图像的输出,工具会追加从 1 开始的序号,例如outputres.0001.pngoutputres.0002.png(该行为由源码中的_get_out_fname实现)。

官方示例:

# 边界框 + 分割 python apply_net.py show configs/densepose_rcnn_R_50_FPN_s1x.yaml DensePose_ResNet50_FPN_s1x-e2e.pkl image.jpg bbox,dp_segm -v # 边界框 + U 坐标着色 python apply_net.py show configs/densepose_rcnn_R_50_FPN_s1x.yaml DensePose_ResNet50_FPN_s1x-e2e.pkl image.jpg bbox,dp_u -v # 边界框 + V 坐标着色 python apply_net.py show configs/densepose_rcnn_R_50_FPN_s1x.yaml DensePose_ResNet50_FPN_s1x-e2e.pkl image.jpg bbox,dp_v -v # 边界框 + U/V 轮廓图 python apply_net.py show configs/densepose_rcnn_R_50_FPN_s1x.yaml DensePose_ResNet50_FPN_s1x-e2e.pkl image.jpg dp_contour,bbox -v

从 apply_net.py 的ShowAction实现 可以看到,可视化类型到可视化器的映射(VISUALIZERS字典)是dp_contour/dp_segm/dp_u/dp_v/bbox五种,多个可视化器通过CompoundVisualizer组合渲染到同一张图上,-v用于提升日志详细度。

Model Zoo:基线模型与配置

MODEL_ZOO.md 汇总了所有官方基线。所有模型均使用 COCOtrain2014+valminusminival2014训练,并在 COCOminival2014上评估,统一采用 s1x 学习率调度。指标列含义:box AP(人体框检测精度)、dp. AP GPSdp. AP GPSm(DensePose 稠密姿态在 GPS 与 GPSm 两种阈值设定下的平均精度)。

传统基线(Legacy Models)

沿用 Güler et al., 2018 训练调度的模型:

名称训练耗时 (s/iter)推理耗时 (s/im)训练显存 (GB)box APdp. AP GPSdp. AP GPSm
R_50_FPN_s1x_legacy0.3070.0513.258.152.154.9
R_101_FPN_s1x_legacy0.3900.0634.359.553.256.1

改进基线:原始全卷积 Head + Panoptic FPN Head

使用改进训练调度与 Kirillov et al., 2019 的 Panoptic FPN head:

名称训练耗时 (s/iter)推理耗时 (s/im)训练显存 (GB)box APdp. AP GPSdp. AP GPSm
R_50_FPN_s1x0.3590.0664.561.263.765.3
R_101_FPN_s1x0.4280.0795.862.364.566.4

改进基线:DeepLabV3 Head

在上一组基础上,将 DensePose 头替换为 Chen et al., 2017 的 DeepLabV3 head:

名称训练耗时 (s/iter)推理耗时 (s/im)训练显存 (GB)box APdp. AP GPSdp. AP GPSm
R_50_FPN_DL_s1x0.3920.0706.761.165.666.8
R_101_FPN_DL_s1x0.4780.0837.062.366.367.7

带置信度估计的基线(Confidence Estimation)

这些模型在回归 UV 坐标的同时,额外估计坐标置信度(思路见 Neverova et al., 2019),命名中WC1/WC2对应两种协方差建模方式(对应配置中的UV_CONFIDENCE.TYPE):

名称训练耗时 (s/iter)推理耗时 (s/im)训练显存 (GB)box APdp. AP GPSdp. AP GPSm
R_50_FPN_WC1_s1x0.3530.0644.660.564.265.6
R_50_FPN_WC2_s1x0.3640.0664.860.764.265.7
R_50_FPN_DL_WC1_s1x0.3970.0686.761.165.867.1
R_50_FPN_DL_WC2_s1x0.4100.0706.860.865.666.7
R_101_FPN_WC1_s1x0.4350.0765.762.564.966.5
R_101_FPN_WC2_s1x0.4500.0785.762.364.866.6
R_101_FPN_DL_WC1_s1x0.4790.0817.962.066.267.4
R_101_FPN_DL_WC2_s1x0.4910.0827.661.765.967.3

以上模型与配置文件一一对应,均可直接在 configs 目录中找到;每个模型的权重与训练日志(modelmetrics)通过 MODEL_ZOO 文档中的下载链接获取。MODEL_ZOO 还说明:所有可下载模型均遵循 Creative Commons Attribution-ShareAlike 3.0 许可。文档同时指出,DensePose 1(旧版框架)的ResNet50_FPN_s1x-e2e(bbox AP 54.673)与ResNet101_FPN_s1x-e2e(bbox AP 56.032)两个旧基线也可在当前框架中加载评估,但分数与旧版报告值存在轻微差异(源于框架间的小型不兼容)。

从配置文件看模型结构

以 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)

其基类 Base-DensePose-RCNN-FPN.yaml 定义了完整的网络骨架:

  • 元架构GeneralizedRCNN,骨干为build_resnet_fpn_backbone,FPN 输入res2res5
  • RPN:5 个特征层各有单尺度锚框(32–512),长宽比[0.5, 1.0, 2.0],训练 / 测试的PRE_NMS_TOPK分别为 2000 / 1000(每 FPN 层),POST_NMS_TOPK均为 1000;
  • ROI 头DensePoseROIHeadsNUM_CLASSES: 1(只有 person 一类);
  • Box headFastRCNNConvFCHead,2 个 FC 层,ROIAlign 池化分辨率 7;
  • DensePose 头DensePoseV1ConvXHeadNUM_COARSE_SEGM_CHANNELS: 2
  • 数据与求解器:训练集densepose_coco_2014_train+densepose_coco_2014_valminusminival,测试集densepose_coco_2014_minivalIMS_PER_BATCH: 16BASE_LR: 0.01、90k 迭代,训练输入短边在 640–800 之间多尺度采样。

置信度版本的配置(如 densepose_rcnn_R_101_FPN_DL_WC2_s1x.yaml)则在此基础上开启UV_CONFIDENCE.ENABLED: True并将TYPE设为indep_aniso,同时将POINT_REGRESSION_WEIGHTS调低到0.0005、启用梯度裁剪。

DensePose 头配置参数详解

DensePose 的全部配置项在 densepose/config.py 的add_densepose_config中注册,这里列出关键参数及其默认值:

配置项默认值含义
MODEL.DENSEPOSE_ONTrue是否启用 DensePose 分支
ROI_DENSEPOSE_HEAD.NAME""DensePose 头名称(如DensePoseV1ConvXHeadDensePoseDeepLabHead
ROI_DENSEPOSE_HEAD.NUM_STACKED_CONVS8堆叠卷积层数
ROI_DENSEPOSE_HEAD.NUM_PATCHES24人体表面块数量(点标签的部件数)
ROI_DENSEPOSE_HEAD.DECONV_KERNEL4反卷积核大小
ROI_DENSEPOSE_HEAD.CONV_HEAD_DIM512卷积头通道数
ROI_DENSEPOSE_HEAD.CONV_HEAD_KERNEL3卷积核大小
ROI_DENSEPOSE_HEAD.UP_SCALE2上采样倍率
ROI_DENSEPOSE_HEAD.HEATMAP_SIZE112输出热图尺寸
ROI_DENSEPOSE_HEAD.POOLER_TYPEROIAlignV2RoI 池化类型
ROI_DENSEPOSE_HEAD.POOLER_RESOLUTION28RoI 池化分辨率
ROI_DENSEPOSE_HEAD.POOLER_SAMPLING_RATIO2池化采样率
ROI_DENSEPOSE_HEAD.NUM_COARSE_SEGM_CHANNELS2粗分割通道数(注释说明可取值152
ROI_DENSEPOSE_HEAD.FG_IOU_THRESHOLD0.7RoI 被判为前景的 IOU 阈值
ROI_DENSEPOSE_HEAD.INDEX_WEIGHTS5.0注释掩码(14 部件)的损失权重
ROI_DENSEPOSE_HEAD.PART_WEIGHTS1.0表面部件(24 部件)的损失权重
ROI_DENSEPOSE_HEAD.POINT_REGRESSION_WEIGHTS0.01UV 回归损失权重
ROI_DENSEPOSE_HEAD.DECODER_ONTrue是否启用解码器
ROI_DENSEPOSE_HEAD.DECODER_NUM_CLASSES256解码器类别数
ROI_DENSEPOSE_HEAD.DECODER_CONV_DIMS256解码器卷积维度
ROI_DENSEPOSE_HEAD.DECODER_NORM""解码器归一化方式
ROI_DENSEPOSE_HEAD.DECODER_COMMON_STRIDE4解码器公共步长
ROI_DENSEPOSE_HEAD.DEEPLAB.NORM"GN"DeepLab 头的归一化方式(GroupNorm)
ROI_DENSEPOSE_HEAD.DEEPLAB.NONLOCAL_ON0是否启用 non-local 模块
ROI_DENSEPOSE_HEAD.UV_CONFIDENCE.ENABLEDFalse是否在学习 UV 值的同时学习置信度(方差)
ROI_DENSEPOSE_HEAD.UV_CONFIDENCE.EPSILON0.01UV 置信度的下界
ROI_DENSEPOSE_HEAD.UV_CONFIDENCE.TYPE"iid_iso"置信度统计模型:iid_iso(独立同分布、各向同性协方差)或indep_aniso(独立但各向异性协方差)

理解这些默认值对调参很有帮助:例如切换 DensePose 头时通过ROI_DENSEPOSE_HEAD.NAME指定DensePoseDeepLabHead,开启置信度估计时则需要同时调整UV_CONFIDENCEPOINT_REGRESSION_WEIGHTS(置信度基线中将其从默认的0.01降为0.0005)。

训练 DensePose-RCNN

数据集准备

按 GETTING_STARTED.md 的说明,先将 DensePose 数据集组织为如下目录结构(位于训练脚本运行目录下):

datasets/coco/ annotations/ densepose_{train,minival,valminusminival}2014.json densepose_minival2014_100.json # 可选,仅用于测试 {train,val}2014/ # json 中引用到的图像文件

其中densepose_minival2014_100.json是仅含 100 张图的轻量测试子集,方便快速验证流程。

训练命令

训练统一使用 train_net.py,MODEL_ZOO 中的全部模型均由该脚本训练得到。8 卡端到端训练 ResNet-50 FPN 骨干的 DensePose-RCNN(s1x 调度):

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

注意:配置默认面向 8 卡训练。若只有 1 张 GPU,需按线性学习率缩放规则(linear learning rate scaling rule,见 arXiv:1706.02677)同步下调批大小与学习率:

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

从 train_net.py 源码 可以看到,训练前的配置组装流程是:get_cfg()获取基础配置 →add_dataset_category_config(cfg)注入类别白名单与映射 →add_densepose_config(cfg)注入 DensePose 头配置 → 合并 YAML 文件与命令行--optsfreeze()冻结。训练器Trainer还重载了评估器与数据加载器:当cfg.MODEL.DENSEPOSE_ON为真时,会在 COCO 评估之外叠加DensePoseCOCOEvaluator;并支持通过test_with_TTA在训练结束时执行带测试时增强(TTA)的评估。

评估模型

评估与训练命令几乎相同,只需额外添加--eval-only标志,并通过MODEL.WEIGHTS指定模型路径:

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

评估时会同时产出目标检测(COCOEvaluator)与 DensePose 稠密姿态(DensePoseCOCOEvaluator)两类指标;若配置中开启TEST.AUG.ENABLED,还会额外运行 TTA 评估(结果键带_TTA后缀)。

query_db:数据集条目的打印与可视化

query_db 是面向数据集(而非模型推理结果)的工具,用于查看 DensePose 标注数据。

print 模式

python query_db.py print [-h] [-v] [--max-entries N] <dataset> <selector>
  • <dataset>:DensePose 数据集说明符,例如densepose_coco_2014_train
  • <selector>:条目选择器,可以是单个说明或逗号分隔的多个,形式为field[:type]=value(精确匹配)或field[:type]=min-max(范围匹配);
  • --max-entries:限制输出条目的最大数量。

官方示例:

# 输出 densepose_coco_2014_train 中前 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 范围匹配(注意 :int 类型标注) python query_db.py print densepose_coco_2014_train image_id:int=36-156 -v

show 模式

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

可视化类型与 apply_net 不同,针对的是标注数据

  • bbox:标注人体的边界框;
  • dp_i:标注点按所属表面块着色;
  • dp_pts:标注点以绿色显示;
  • dp_segm:标注人体的分割掩码;
  • dp_u:标注点按 U 坐标着色;
  • dp_v:标注点按 V 坐标着色。

官方示例(查看densepose_coco_2014_trainimage_id = 322的样本):

python query_db.py show densepose_coco_2014_train image_id:int=322 bbox,dp_segm -v python query_db.py show densepose_coco_2014_train image_id:int=322 bbox,dp_i -v python query_db.py show densepose_coco_2014_train image_id:int=322 bbox,dp_pts -v python query_db.py show densepose_coco_2014_train image_id:int=322 bbox,dp_u -v python query_db.py show densepose_coco_2014_train image_id:int=322 bbox,dp_v -v

--output为输出文件名模板(默认output.png),多条目输出时会追加从 1 开始的序号(如output.0001.png)。

从 query_db.py 源码 可以确认其执行流程:先通过DatasetCatalog.get(dataset)加载数据集,再用EntrySelector.from_string(args.selector)解析选择器,逐条过滤后交给PrintAction(pprint 输出)或ShowAction(可视化叠加)。ShowAction在读取条目时会通过DensePoseDataRelative.validate_annotation校验标注有效性,并将DensePoseDataRelative数据与边界框一并交给对应的可视化器。

引用与许可

若在研究中使用了 DensePose,README 提供了两份 BibTeX 引用:

  • 使用带置信度估计的 DensePose 时:
@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}, }
  • 使用原始 DensePose时:
@InProceedings{Guler2018DensePose, title={DensePose: Dense Human Pose Estimation In The Wild}, author={R{i}za Alp G"uler, Natalia Neverova, Iasonas Kokkinos}, journal={The IEEE Conference on Computer Vision and Pattern Recognition (CVPR)}, year={2018} }

许可方面,DensePose 随 detectron2 一起以 Apache 2.0 许可 发布;而 Model Zoo 中可下载的模型权重遵循 Creative Commons Attribution-ShareAlike 3.0 许可,使用时需注意区分。

总结

本文围绕 OOTDiffusion 仓库中携带的 DensePose README 及其配套文档,完整覆盖了:稠密人体姿态估计的任务定义(24 表面块 + UV 坐标)、仓库文件结构、预训练模型的推理(apply_net的 dump / show 两种模式)、Model Zoo 全部四类基线(legacy / 改进 FPN head / DeepLabV3 head / 置信度估计)及其配置解析、DensePose 头的全部关键超参数、训练(含单卡线性学习率缩放)与评估(--eval-only)命令,以及数据集查询工具query_db的使用。无论是想快速对单张人体图像做稠密姿态推理与可视化,还是准备在自有数据上复现或微调 DensePose-RCNN,上述命令与配置都具备直接可复制、可运行的实战价值。

【免费下载链接】OOTDiffusion[AAAI 2025] Official implementation of "OOTDiffusion: Outfitting Fusion based Latent Diffusion for Controllable Virtual Try-on"项目地址: https://gitcode.com/GitHub_Trending/oo/OOTDiffusion

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询