计算机视觉入门第四课:图像分割

30次阅读
没有评论

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

4.1 语义分割(Semantic Segmentation)

语义分割的目标是为图像中的 每个像素 分配一个类别标签(如“人”、“车”、“天空”),但 不区分同一类别的不同个体。例如,图中有两个人,语义分割会将他们都标记为“人”,而不区分谁是谁。

4.1.1 U-Net

U-Net 是由 Ronneberger 等人在 2015 年提出的经典语义分割网络,最初用于生物医学图像分割。

网络结构特点:

  • 编码器 - 解码器结构(Encoder-Decoder)
  • 编码器(下采样路径):使用卷积 + 池化逐步提取高层语义特征,空间分辨率降低,通道数增加。
  • 解码器(上采样路径):通过转置卷积(或插值)逐步恢复空间分辨率。
  • 跳跃连接(Skip Connections)
  • 将编码器中对应层级的高分辨率特征图与解码器的上采样结果拼接(concatenate),融合局部细节与全局语义。
  • 输出:与输入图像同尺寸的像素级分类图。

优点:

  • 对小数据集表现优异(得益于跳跃连接保留细节)
  • 结构清晰,易于实现和改进
  • 广泛应用于医学图像、遥感图像等场景
# 伪代码示意(PyTorch 风格)class UNet(nn.Module):
    def __init__(self, n_channels, n_classes):
        super().__init__()
        self.inc = DoubleConv(n_channels, 64)
        self.down1 = Down(64, 128)
        self.down2 = Down(128, 256)
        self.down3 = Down(256, 512)
        self.down4 = Down(512, 1024)
        self.up1 = Up(1024, 512)
        self.up2 = Up(512, 256)
        self.up3 = Up(256, 128)
        self.up4 = Up(128, 64)
        self.outc = OutConv(64, n_classes)

    def forward(self, x):
        x1 = self.inc(x)
        x2 = self.down1(x1)
        x3 = self.down2(x2)
        x4 = self.down3(x3)
        x5 = self.down4(x4)
        x = self.up1(x5, x4)
        x = self.up2(x, x3)
        x = self.up3(x, x2)
        x = self.up4(x, x1)
        logits = self.outc(x)
        return logits

4.1.2 DeepLab 系列

DeepLab 是 Google 提出的一系列高性能语义分割模型,核心思想是 在保持空间分辨率的同时扩大感受野

关键技术演进:

版本 核心技术
DeepLab v1 空洞卷积(Atrous Convolution)
DeepLab v2 空洞空间金字塔池化(ASPP)+ CRF 后处理
DeepLab v3 改进 ASPP + 多尺度特征融合
DeepLab v3+ 引入编码器 - 解码器结构,结合 Xception 骨干网络

核心组件:

  1. 空洞卷积(Atrous/Dilated Convolution)
  • 在不增加参数量和计算量的前提下,扩大卷积核的感受野。
  • 公式:输出位置 $$ y[i] = \sum_k x[i + r \cdot k] \cdot w[k] $$,其中 $ r $ 为膨胀率。
  1. ASPP(Atrous Spatial Pyramid Pooling)
  • 使用不同膨胀率的空洞卷积并行处理特征图,捕获多尺度上下文信息。
  • 通常包含:1×1 卷积 + 多个不同 rate 的 3×3 空洞卷积 + 全局平均池化。
  1. 编码器 - 解码器(v3+)
  • 编码器:DeepLab v3 的输出
  • 解码器:上采样 + 低层特征融合(类似 U -Net)

优点:

  • 对多尺度目标鲁棒性强
  • 边界分割精度高
  • 在 Cityscapes、PASCAL VOC 等基准上表现优异

4.2 实例分割(Instance Segmentation)

实例分割不仅区分类别,还 区分同一类别的不同个体,即为每个对象生成独立的像素级掩码(mask)。

4.2.1 Mask R-CNN

Mask R-CNN 是 He 等人在 2017 年提出的实例分割框架,是 Faster R-CNN 的自然扩展。

网络结构:

  1. 骨干网络(Backbone):如 ResNet + FPN(特征金字塔网络)
  2. 区域建议网络(RPN):生成候选框
  3. RoIAlign(关键改进):
  • 替代 RoIPooling,通过双线性插值避免量化误差,精准对齐特征与原始像素
  1. 三个并行分支
  • 分类分支:预测类别
  • 边界框回归分支:精修框坐标
  • 掩码分支:为每个 RoI 生成 $28 \times 28$ 的二值掩码(sigmoid 激活)

输出:

  • 每个实例:类别标签 + 边界框 + 像素级掩码

优点:

  • 精度高,是 COCO 实例分割竞赛的标杆模型
  • 框架灵活,可扩展至关键点检测等任务
  • 开源实现成熟(Detectron2、MMDetection)

4.3 图像分割评估指标

4.3.1 IoU(Intersection over Union)

IoU 是最常用的分割评估指标,衡量预测区域与真实区域的重叠程度。

$$
\text{IoU} = \frac{|A \cap B|}{|A \cup B|}
$$

  • $A$:预测掩码
  • $B$:真实掩码(Ground Truth)
  • 取值范围:[0, 1],值越大越好

注意 :在语义分割中,通常计算 每个类别的 IoU,再取平均(mIoU,mean IoU)。

4.3.2 Dice 系数(Dice Coefficient)

Dice 系数与 IoU 密切相关,常用于医学图像分割。

$$
\text{Dice} = \frac{2|A \cap B|}{|A| + |B|} = \frac{2 \cdot \text{TP}}{2 \cdot \text{TP} + \text{FP} + \text{FN}}
$$

  • 与 IoU 的关系:$$\text{Dice} = \frac{2 \cdot \text{IoU}}{1 + \text{IoU}}$$
  • 对小目标更敏感(因分母为面积和而非并集)

4.3.3 其他指标

指标 说明
Pixel Accuracy 正确分类像素数 / 总像素数(忽略类别不平衡)
mIoU 所有类别 IoU 的平均值(主流指标)
Boundary F1-score (BF-score) 衡量边界分割精度
AP (Average Precision) 实例分割常用(如 COCO AP@0.5:0.95)

4.4 方法对比总结

方法 类型 是否区分实例 典型应用场景
U-Net 语义分割 医学图像、遥感
DeepLab 语义分割 自动驾驶、街景理解
Mask R-CNN 实例分割 COCO、工业检测、机器人视觉

4.5 实战代码示例(简要)

4.5.1 使用 torchvision 加载 DeepLabV3

import torch
import torchvision.transforms as T
from PIL import Image

# 加载预训练模型
model = torch.hub.load('pytorch/vision:v0.10.0', 'deeplabv3_resnet50', pretrained=True)
model.eval()

# 预处理
input_image = Image.open("input.jpg")
preprocess = T.Compose([
    T.ToTensor(),
    T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
input_tensor = preprocess(input_image).unsqueeze(0)

# 推理
with torch.no_grad():
    output = model(input_tensor)['out'][0]
output_predictions = output.argmax(0)

# 可视化
palette = torch.tensor([2 ** 25 - 1, 2 ** 15 - 1, 2 ** 21 - 1])
colors = torch.as_tensor([i for i in range(21)])[:, None] * palette
colors = (colors % 255).numpy().astype("uint8")
r = Image.fromarray(output_predictions.byte().cpu().numpy()).resize(input_image.size)
r.putpalette(colors)
r.save("segmentation_result.png")

4.5.2 计算 mIoU 和 Dice

import numpy as np

def compute_iou(pred, target, num_classes):
    ious = []
    for cls in range(num_classes):
        pred_cls = (pred == cls)
        target_cls = (target == cls)
        intersection = np.logical_and(pred_cls, target_cls).sum()
        union = np.logical_or(pred_cls, target_cls).sum()
        iou = intersection / union if union != 0 else 0
        ious.append(iou)
    return np.mean(ious)

def dice_coefficient(pred, target):
    smooth = 1e-6
    intersection = (pred * target).sum()
    dice = (2. * intersection + smooth) / (pred.sum() + target.sum() + smooth)
    return dice

4.6 本课小结

  • 语义分割:像素级分类,不区分实例 → U-Net、DeepLab
  • 实例分割:像素级分类 + 实例区分 → Mask R-CNN
  • 评估指标
  • IoU/mIoU:通用标准
  • Dice:医学图像常用
  • 技术趋势
  • 从 FCN → U-Net → DeepLab → Transformer-based(如 SegFormer)
  • 实时分割(如 BiSeNet)、弱监督分割也是研究热点

建议实践:使用 Cityscapes 或 Pascal VOC 数据集,分别训练 U-Net 和 DeepLab,并对比 mIoU;尝试用 Detectron2 运行 Mask R-CNN 进行实例分割。

正文完
 0
一诺
版权声明:本站原创文章,由 一诺 于2025-09-15发表,共计4072字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
验证码