正文从这里开始。
https://chatgpt.com/share/68592322-5850-8002-8395-7aa7eec4a7eb
SegFormer-B2 ADE20K 与 MonoGS 融合笔记
1. SegFormer-B2 ADE20K 回顾
- 任务:语义分割,将输入图像中每个像素标注为 ADE20K 中的 150 类(如 “wall”、“floor”、“person” 等)。
- 模型架构:
- 编码器(Backbone):Mix Transformer B2(MiT-B2),分 4 个 stage,
depths=[3,4,6,3],hidden_sizes=[64,128,320,512],对应不同下采样率[1,4,8,16]。 - Transformer 层:自注意力机制提取全局上下文和局部特征。
- 解码器(SegformerDecoderHead):轻量 MLP 或 1×1 卷积融合多尺度特征,上采样到原图尺寸,输出每像素 150 维 logits,再
argmax得到类别 ID。
- 编码器(Backbone):Mix Transformer B2(MiT-B2),分 4 个 stage,
- 预处理(
preprocessor_config.json):do_resize: true, size: 512→ 缩放到 512×512。do_normalize: true, image_mean=[0.485,0.456,0.406], image_std=[0.229,0.224,0.225]→ 归一化。resample: 2(bicubic)。reduce_labels: true(通常指简化内部标签处理,但具体以模型实现为准)。
- 模型文件:
config.json:定义架构、层数、hidden size、dropout、类别数等(示例字段已解释)。preprocessor_config.json:定义预处理过程细节。pytorch_model.bin:训练后保存的所有权重(Transformer 各层、解码器、分类头等)。README.md:说明、使用示例等,可参考类别映射、预训练信息。
- 部署与推理:
- 加载预处理器与模型:
from transformers import SegformerFeatureExtractor, SegformerForSemanticSegmentation feature_extractor = SegformerFeatureExtractor.from_pretrained("path/to/model") model = SegformerForSemanticSegmentation.from_pretrained("path/to/model").to(device) model.eval() - 读取图像并预处理:
from PIL import Image image = Image.open("xxx.jpg").convert("RGB") inputs = feature_extractor(images=image, return_tensors="pt").to(device) - 前向推理:
with torch.no_grad(): outputs = model(**inputs) logits = outputs.logits # [1,150,H,W] seg_map = logits.argmax(dim=1)[0].cpu().numpy() # 每像素类别 ID - 可视化/后处理:用 ADE20K 的 id2label 与配色表,将 seg_map 转成彩色图或类别名称标签图;如果输入先做了 resize/crop,则需映射回原始尺寸。
- 加载预处理器与模型:
- 优化手段:
- 混合精度(FP16)、半精度推理、ONNX/TensorRT 加速、分辨率-速度折中(降低到 384×384 等)、分块推理、batch=1、剪枝/蒸馏等。
2. Transformer 层与解码器
- Transformer 层(在编码器里):
- 在
model.segformer.encoder中,分 4 个 stage,每个 stage 多个 Transformer block(self-attention + MLP)。 - 输入:预处理后的图像 patches;输出:多尺度特征图(分辨率逐 stage 缩小)。
- 在
- 解码器:
- 在
model.decode_head(或SegformerDecoderHead)中,接收 4 个 stage 特征。 - 用 1×1 卷积/MLP 把各特征通道对齐,上采样到相同尺寸后拼接或加权融合,最后输出每像素 logits。
- 在
- 参数存储:
pytorch_model.bin存储了这些层里所有权重(注意力权重、线性层权重、偏置等);config.json定义网络“骨架”。
- 预处理执行:
- 文件
preprocessor_config.json中的do_normalize等字段在SegformerFeatureExtractor里通过代码判断并调用相应函数(例如/255.0,(x-mean)/std等)。
- 文件
3. 与 MonoGS 融合思路
MonoGS(Monocular Gaussian Splatting SLAM)的核心是基于单目相机生成三维高斯表示,并进行跟踪与重建。将 SegFormer-B2 ADE20K 融入 MonoGS,可以给 SLAM 增加语义信息,在动态剔除、语义地图构建、优化策略上带来改进。下面是关键思路与实践要点。
3.1 基本框架与数据流
- 相机采集:获取 RGB 图像(可同步或结合深度估计模块)。
- 语义分割:对每帧 RGB 图像运行 SegFormer-B2,得到
seg_map(每像素类别 ID)。 - 深度/点云生成:MonoGS 通常通过单目深度估计或多视角融合得到 3D 点或高斯分布。
- 投影与语义附加:
- 将像素级语义投影到 3D 点或高斯:利用相机内外参计算像素到 3D 坐标的映射(单目需深度估计;若已有稠密深度或重建结果,可直接投影)。
- 每个 3D 点/高斯附上对应像素的语义类别或分布概率。
- 语义驱动处理:
- 动态剔除:若某些像素/点属于动态类别(如 person, car, bicycle),剔除或降低其在地图构建中的权重,避免将动态物体错误融合到静态地图。
- 语义权重:针对不同语义类别,可赋予不同置信度或融合权重,例如:墙、地面、家具等高置信度,植被、天等可视场景外的类别处理方式可调。
- 语义地图构建:在高斯表示中记录类别标签,实现带语义的 3D 重建,可用于语义查询、语义导航等。
- 优化与控制:
- 在优化步骤中(如 pose 优化或高斯分布参数优化),结合语义信息进行约束或加权:例如,同类别点之间更易关联,避免跨语义区域匹配错误。
- 可视化与后续应用:
- 输出带语义的高斯点云/体渲染,或者生成语义拓扑图,用于机器人理解、路径规划等。
3.2 详细实现要点
3.2.1 相机标定与时间同步
- 标定:准确得到内参(fx,fy,cx,cy)与外参(若多摄像头、多传感器融合)。用于把像素坐标映射到 3D。
- 时间同步:确保 RGB 图与 MonoGS 内部生成深度或重建结果对齐(同一时间戳),否则语义投影会存在漂移。
3.2.2 语义分割调用频率
- 实时性考虑:SegFormer-B2 在 512×512 下 GPU 推理可能几十到上百 ms/帧,根据显卡性能而定。可选择:
- 每 N 帧做一次分割,用跟踪或卡尔曼滤波等手段在中间帧预测语义。
- 降低分辨率(如 384×384 或 256×256),在精度可接受范围内平衡速度。
- 混合精度 FP16 推理或 TensorRT 加速。
- 异步处理:在独立线程或进程中跑分割,让主 SLAM 线程拿到最近一次结果;注意线程安全和延迟容忍。
3.2.3 投影到 3D
- 单目深度估计:若 MonoGS 依赖单目深度估计网络(如 MiDaS 等),先得到深度图,再投影:
- 像素 (u,v) 的深度 d → 相机坐标 (X,Y,Z) = inv(K) * [u,v,1]^T * d。
- 稠密/稀疏重建:若 MonoGS 已有稠密高斯表示,通过渲染或对已有 3D Gaussians 采样像素坐标映射回 2D,或反向投影 2D 像素到现有 3D 表示中。
- 标签附加:
- 对应像素位置的语义 ID,赋给生成的 3D element(点或 Gaussian)。可存储单一类别或概率分布(若输出 softmax 概率)。
- 若同一个 3D element 在多帧有多个语义预测,可累积统计或做加权融合,减少单帧噪声带来的误标。
3.2.4 动态剔除与滤波
- 剔除规则:定义哪些 ADE20K 类别为动态(如 person, car, bicycle, animal 等)。在构建或更新地图时跳过这些点/高斯,避免将移动物体融入静态地图。
- 软剔除:可不完全丢弃,而是降低它们在优化或渲染中的权重;若后续多帧都预测为静态类别,可重新纳入。
- 连贯性检测:结合跟踪信息判断一个物体是否持续存在于静态环境(如停泊车辆 vs 行驶车辆),可用时序一致性或光流辅助。
3.2.5 语义权重优化
- 类别权重:根据类别重要性或置信度,给不同类别点/高斯赋不同融合权重。例如:
- 建筑、墙、地板:高权重,优先用于重建。
- 植被、天空:可作为背景或剔除。
- 空间先验:结合场景先验(如地面通常在图像下半部分),辅助语义结果的置信增强或修正。
- 几何-语义联合优化:在高斯优化或位姿估计的损失中,引入语义一致性项,即同一类别区域在不同帧之间应匹配,不同类别间不匹配。
3.2.6 存储与可视化
- 高斯表示带语义:在每个 Gaussian 数据结构中增加语义标签字段,可用于后续查询与渲染。渲染时可按类别着色,生成语义彩色点云或体渲染。
- 统计与分析:在运行过程中记录不同类别点数、覆盖区域,评估场景语义分布,用于机器人决策(例如哪些区域可行走)。
- ROS 集成:可将语义点云或图像话题发布,RViz 可视化;也可发布语义分割图供其他节点使用。
3.2.7 代码示例思路(伪代码)
# 在 SLAM 主循环或回调中:
rgb_image = get_current_frame()
# 异步请求分割
seg_map = segformer_inference(rgb_image) # 返回 HxW 的类别 ID 矩阵
# 若使用单目深度估计:
depth_map = monocular_depth_net(rgb_image) # HxW 浮点深度
# 投影到 3D:
points3D = []
semantics = []
for v in range(0, H, stride):
for u in range(0, W, stride):
d = depth_map[v,u]
if not valid(d): continue
X, Y, Z = backproject(u, v, d, K)
cls_id = seg_map[v,u]
points3D.append([X,Y,Z])
semantics.append(cls_id)
# 构建或更新 Gaussian:
for p, cid in zip(points3D, semantics):
if cid in dynamic_classes:
continue # 剔除
weight = class_weight_map.get(cid, default=1.0)
add_or_update_gaussian(p, weight, semantic_label=cid)
# 在优化时,可用语义一致性:
# 例如,损失项 L_semantic = sum_over_correspondences( semantic_distance(...) * weight )
- 上例中
stride可用于稀疏采样以加速;class_weight_map事先定义各类别权重;add_or_update_gaussian是 MonoGS 核心接口;语义一致性可在后端优化模块中加入。
3.2.8 性能与资源
-
显存与计算:SegFormer-B2 在 512×512 下大约几十 ms/帧,建议:
-
GPU 上异步并行。
-
可考虑更轻量版本(B1/B0)或降分辨率。
-
-
线程/进程架构:SLAM 主循环独立于分割线程;二者通过线程安全队列通信,保持实时性。
4. 总结
-
SegFormer-B2 ADE20K 是当前高效的语义分割 Transformer 模型,能准确提取复杂场景语义。
-
它的编码器+解码器架构和预处理流程,配合训练得到的权重,构成一个完整语义分割模块。
-
将 SegFormer-B2 语义分割与 MonoGS 高斯溅射 SLAM 融合,能为三维重建赋予丰富语义信息,有助于动态物体剔除和语义地图构建。
-
实现时需注意多线程异步推理、精度与速度权衡、投影映射准确性以及语义权重设计。
-
该融合路径是前沿研究方向,适合做语义 SLAM 及动态环境理解相关课题。
备注:请根据你的硬件资源与具体任务,调整模型推理分辨率、类别处理策略及 SLAM 优化模块中的语义约束设计。