CamVid数据集实战:基于语义分割的街景解析解决方案

1次阅读
没有评论

共计 1501 个字符,预计需要花费 4 分钟才能阅读完成。

image.webp

背景与痛点

街景解析是自动驾驶、机器人导航等领域的基础技术,其核心任务是对街景图像中的每个像素进行分类。然而在实际应用中,高质量标注数据稀缺且标注成本高昂,导致模型在小样本场景下泛化能力较差。CamVid 数据集作为街景解析的经典基准数据集,为解决这一问题提供了良好的研究平台。

数据集解析

CamVid 数据集包含 700 张街景图像(分为训练集、验证集和测试集),每张图像分辨率为 960×720,标注了 32 个语义类别。与其他常用数据集相比:

  • 相比 Pascal VOC(20 类),CamVid 的类别更细粒度(如区分人行道 / 道路)
  • 相比 Cityscapes(5000 张),数据规模更小但标注质量更高
  • 所有图像均为车载摄像头拍摄,包含昼夜不同光照条件

技术方案

数据预处理

  1. 几何增强 :随机水平翻转(p=0.5)、裁剪(512×512)、旋转(±10°)
  2. 色彩增强 :亮度(±0.2)、对比度(±0.2)、饱和度(±0.2)抖动
  3. 类别处理 :将原始 32 类合并为 11 个主要类别(如所有车辆类合并)

模型选型对比

模型 mIoU(%) 参数量 (M) 推理速度 (FPS)
FCN-8s 57.3 134 28
UNet 63.1 31 42
DeepLabv3+ 68.7 59 37

测试环境:NVIDIA T4 GPU,输入尺寸 512×512

损失函数选择

  • CrossEntropy Loss:基础选择,但对类别不平衡敏感
  • Dice Loss:适用于前景 - 背景极度不平衡场景
  • 组合策略 :0.7CE + 0.3Dice 效果最佳

代码实现

# 自定义 Dataset 示例
class CamVidDataset(torch.utils.data.Dataset):
    def __init__(self, img_dir, mask_dir, transform=None):
        self.img_paths = sorted(glob(f"{img_dir}/*.png"))
        self.mask_paths = sorted(glob(f"{mask_dir}/*.png"))
        self.transform = transform
        self.class_map = {...}  # 32 类到 11 类的映射

    def __getitem__(self, idx):
        image = cv2.imread(self.img_paths[idx])
        mask = cv2.imread(self.mask_paths[idx], 0)

        if self.transform:
            aug = self.transform(image=image, mask=mask)
            image, mask = aug["image"], aug["mask"]

        mask = self._convert_mask(mask)
        return image, mask

避坑指南

  1. 类别不平衡 :
  2. 采用样本加权(inverse class frequency)
  3. 使用 OHEM(Online Hard Example Mining)

  4. 显存优化 :

  5. 梯度累积(batch_size= 4 时累积 4 次等效 bs=16)
  6. 混合精度训练(AMP)

  7. 评估陷阱 :

  8. 避免仅看 Pixel Accuracy(对主导类别敏感)
  9. mIoU 计算需排除 void 类

性能验证

CamVid 数据集实战:基于语义分割的街景解析解决方案
ResNet50/101/152 作为 backbone 的验证集 mIoU 对比

延伸思考

  1. 将当前方案迁移到 Cityscapes 时:
  2. 需要注意 2048×1024 的高分辨率处理
  3. 可尝试 HRNet 等高分辨率网络
  4. 实际部署时:
  5. 转换为 TensorRT 引擎可提升 3 倍推理速度
  6. 考虑使用知识蒸馏压缩模型

实验环境

  • GPU: NVIDIA Tesla T4 (16GB)
  • CUDA: 11.1
  • Framework: PyTorch 1.8.1
  • Training Time: ~4 小时(200 epochs)
正文完
 0
评论(没有评论)