跳转至

图像分割算法

图像分割(Image Segmentation)是计算机视觉中最精细的理解任务——将图像中的每一个像素都分配一个标签,实现像素级的场景理解。


一、什么是图像分割?

图像分割的目标是将图像划分为若干有意义的区域,每个区域对应一个物体或类别。

\[ \text{Segmentation}: I \in \mathbb{R}^{H \times W \times 3} \rightarrow M \in \{0, 1, \ldots, C-1\}^{H \times W} \]

即输出一张与输入同样大小的分割掩码(Mask),每个像素的值表示其所属类别。

三种分割任务

任务 输出内容 示例
语义分割 每个像素的类别 所有"人"标红,所有"车"标蓝
实例分割 每个像素的类别 + 实例归属 人1 标红,人2 标橙,车1 标蓝
全景分割 语义分割 + 实例分割的统一 所有可数物体按实例分,不可数物体(天空、道路)按语义分
graph LR
    A[图像分割] --> B[语义分割<br/>Semantic Segmentation]
    A --> C[实例分割<br/>Instance Segmentation]
    A --> D[全景分割<br/>Panoptic Segmentation]
    B --> E[每个像素一个类别]
    C --> F[区分同类不同个体]
    D --> G[B + C 的统一]

直观理解

想象你在看一张街景照片:

  • 语义分割:所有行人像素标"人",所有车辆像素标"车",路面标"道路"——但不区分不同的人或车
  • 实例分割:行人 A 和行人 B 用不同颜色标注——区分不同个体,但只标注"东西"(可数的物体)
  • 全景分割:既区分不同的人和车,又标注天空、道路这些"材质"——最完整的理解

二、传统分割方法

1. 阈值分割

最简单的分割方法:根据像素值设定阈值将图像分为前景和背景。

\[ M(x, y) = \begin{cases} 1 & \text{if } I(x, y) > T \\ 0 & \text{otherwise} \end{cases} \]
  • 全局阈值:整张图用同一个 \(T\)(如 Otsu 自适应阈值)
  • 局部阈值:不同区域用不同的 \(T\)

Otsu 算法

自动寻找最优阈值 \(T^*\),使前景和背景的类间方差最大

\[T^* = \arg\max_T \omega_0(\mu_0 - \mu)^2 + \omega_1(\mu_1 - \mu)^2\]

其中 \(\omega_0, \omega_1\) 是前景/背景像素比例,\(\mu_0, \mu_1\) 是各自均值。

2. 区域生长

种子点出发,逐步将相似的相邻像素合并到同一区域:

  1. 选择种子点(手动或自动)
  2. 检查种子点的邻域像素
  3. 如果邻域像素与当前区域的相似度满足条件(如灰度差 < 阈值),将其加入区域
  4. 重复直到没有新像素加入

3. 分水岭算法

将图像的灰度值看作"地形高度",模拟水从低洼处上涨的过程:

  1. 找到局部最小值作为"盆地"
  2. 模拟水位上升,不同盆地的水相互接触时形成"分水岭"
  3. 分水岭线就是分割边界

传统方法的局限

传统方法依赖手工设计的规则,对复杂场景(多类别、遮挡、光照变化)效果很差,无法理解语义信息。


三、全卷积网络(FCN)

开山之作

FCN(Fully Convolutional Networks),2015 年由 Long 等人提出,是深度学习语义分割的奠基之作。

核心思想:将分类网络(如 VGG)的全连接层替换为卷积层,使网络能接受任意大小的输入并输出与之对应的分割图。

graph LR
    A[输入图像<br/>H×W×3] --> B[卷积下采样<br/>多层卷积+池化]
    B --> C[低分辨率特征图<br/>H/32×W/32]
    C --> D[上采样/反卷积<br/>恢复分辨率]
    D --> E[分割预测<br/>H×W×C]

关键技术

1. 全卷积化

传统分类网络(VGG、AlexNet)的最后几层是全连接层,要求固定输入大小。FCN 将全连接层替换为 \(1 \times 1\) 卷积:

  • 全连接层:\(\mathbb{R}^{4096} \rightarrow \mathbb{R}^{1000}\)
  • \(1 \times 1\) 卷积:\(\mathbb{R}^{H \times W \times 4096} \rightarrow \mathbb{R}^{H \times W \times 1000}\)

这样网络就能保留空间信息,输出每个位置的类别预测。

2. 转置卷积(Transposed Convolution)

经过多次池化后,特征图缩小到原图的 \(\frac{1}{32}\),需要上采样恢复原始分辨率。

转置卷积(也叫反卷积)通过在输入特征图的像素之间填充零,然后做卷积运算来放大特征图。

3. 跳跃连接(Skip Connection)

直接将 \(\frac{1}{32}\) 的特征图上采样到原图大小,结果会很粗糙。FCN 通过跳跃连接融合不同层级的信息:

变体 融合方式 效果
FCN-32s 只用最后一层,32× 上采样 最粗糙
FCN-16s 融合 pool4 + pool5,16× 上采样 更精细
FCN-8s 融合 pool3 + pool4 + pool5 最精细

FCN 的意义

FCN 奠定了深度学习语义分割的基本范式:编码器(下采样提特征)+ 解码器(上采样恢复分辨率)。后续所有方法都是在这个框架上改进。


四、U-Net

为医学图像而生

U-Net(2015)最初为医学图像分割设计,因其 U 形结构而得名,是目前最广泛使用的分割网络之一。

架构

graph TB
    subgraph 编码器-左侧下采样
        E1[Conv×2 + Pool] --> E2[Conv×2 + Pool]
        E2 --> E3[Conv×2 + Pool]
        E3 --> E4[Conv×2 + Pool]
        E4 --> B[Bottleneck<br/>Conv×2]
    end
    subgraph 解码器-右侧上采样
        B --> D4[Up + Conv×2]
        D4 --> D3[Up + Conv×2]
        D3 --> D2[Up + Conv×2]
        D2 --> D1[Up + Conv×2]
    end
    E4 -.->|Skip Connection| D4
    E3 -.->|Skip Connection| D3
    E2 -.->|Skip Connection| D2
    E1 -.->|Skip Connection| D1
    D1 --> O[1×1 Conv → 输出]

核心设计

组件 说明
对称的编码器-解码器 编码器逐步缩小分辨率提取语义特征;解码器逐步恢复分辨率
跳跃连接(Concatenation) 将编码器的高分辨率特征与解码器的高语义特征拼接融合
少量数据也能训练 通过数据增强 + 强正则化,U-Net 在几十张标注图像上就能取得好效果

Skip Connection 的作用

编码器下采样时会丢失空间细节(边缘位置等),解码器上采样时需要这些细节来做精确分割。跳跃连接将编码器的"细节信息"直接送到解码器对应层,实现语义 + 细节的融合。

U-Net 的变体

变体 改进
U-Net++ 密集跳跃连接,缩小编码器-解码器之间的语义鸿沟
Attention U-Net 在跳跃连接中加入注意力门控,自动聚焦重要区域
nnU-Net 自适应配置网络结构和训练策略,"开箱即用"的医学分割
Swin-UNet 用 Swin Transformer 替换 CNN 编码器

五、DeepLab 系列

DeepLab 系列是语义分割的另一条重要技术路线,核心创新是空洞卷积ASPP 模块

空洞卷积(Atrous/Dilated Convolution)

解决的问题:普通卷积 + 池化会导致分辨率急剧下降,丢失空间细节。

核心思想:在卷积核的采样位置之间插入空洞(间隔),不增加参数量,就能扩大感受野。

\[ (I *_r K)(x) = \sum_{k} I(x + r \cdot k) \cdot K(k) \]

其中 \(r\) 是膨胀率(dilation rate):

  • \(r = 1\):正常卷积,\(3 \times 3\) 感受野
  • \(r = 2\)\(3 \times 3\) 核覆盖 \(5 \times 5\) 范围
  • \(r = 4\)\(3 \times 3\) 核覆盖 \(9 \times 9\) 范围

优势

不用池化就能获得大感受野,保持高分辨率特征图,对分割至关重要。

ASPP(Atrous Spatial Pyramid Pooling)

用不同膨胀率的空洞卷积并行处理同一特征图,然后融合,捕获多尺度上下文信息:

graph LR
    A[输入特征图] --> B1["1×1 Conv (r=1)"]
    A --> B2["3×3 Conv (r=6)"]
    A --> B3["3×3 Conv (r=12)"]
    A --> B4["3×3 Conv (r=18)"]
    A --> B5[Global Avg Pool]
    B1 --> C[Concatenate]
    B2 --> C
    B3 --> C
    B4 --> C
    B5 --> C
    C --> D["1×1 Conv → 输出"]

DeepLab 版本演进

版本 关键创新
DeepLab v1 空洞卷积 + CRF 后处理
DeepLab v2 ASPP 多尺度特征聚合
DeepLab v3 改进的 ASPP + 全局平均池化
DeepLab v3+ 编码器-解码器结构 + ASPP,成为标杆方法

六、实例分割

语义分割不区分同类的不同个体,实例分割则需要为每个物体实例生成独立的分割掩码。

Mask R-CNN(2017)

He Kaiming 等 在 Faster R-CNN 基础上增加了一个掩码预测分支,实现实例分割。

graph LR
    A[Faster R-CNN] --> B[分类分支]
    A --> C[边界框回归分支]
    A --> D[掩码分支 - 新增]
    D --> E[每个 RoI 预测<br/>一个二值掩码]

关键改进

RoI Align:替代 RoI Pooling,解决量化误差问题。

RoI Pooling 的问题:将浮点坐标取整为整数坐标时会产生像素偏差,对检测影响不大,但对分割(像素级任务)影响很大。

RoI Align 使用双线性插值在浮点坐标处采样,避免量化误差:

\[ f(x, y) = \sum_{i,j} f(i, j) \cdot \max(0, 1-|x-i|) \cdot \max(0, 1-|y-j|) \]

掩码分支

对每个检测到的 RoI,用一个小型 FCN(全卷积网络)预测 \(K\)\(m \times m\) 的二值掩码(\(K\) 为类别数),每个类别一个掩码,根据分类结果选择对应类别的掩码作为输出。

为什么每个类别一个掩码?

这样做将分类分割解耦:分割分支只需关注"这个像素属不属于这个物体",不需要区分类别,降低了学习难度,显著提升性能。

YOLACT(2019)

实时实例分割方法:

  1. 网络生成一组原型掩码(Prototype Masks)——全局共享的掩码基
  2. 对每个检测到的物体预测一组组合系数
  3. 用组合系数线性组合原型掩码,得到该物体的实例掩码
\[ \text{mask}_i = \sigma\left(\sum_k c_{ik} \cdot P_k\right) \]

优点:实时速度(30 FPS),结构简洁。


七、全景分割

全景分割 = 语义分割 + 实例分割,对图像中的所有像素给出完整的理解:

  • Thing(可数物体):人、车、动物 → 需要实例级分割
  • Stuff(不可数材质):天空、道路、草地 → 只需语义分割

评价指标:PQ(Panoptic Quality)

\[ \text{PQ} = \underbrace{\frac{\sum_{(p,g) \in TP} \text{IoU}(p,g)}{|TP|}}_{\text{SQ(分割质量)}} \times \underbrace{\frac{|TP|}{|TP| + \frac{1}{2}|FP| + \frac{1}{2}|FN|}}_{\text{RQ(识别质量)}} \]

Panoptic FPN(2019)

在 Mask R-CNN(实例分割)的基础上,增加一个语义分割分支,两个分支共享 FPN backbone,分别处理 Thing 和 Stuff。


八、基于 Transformer 的分割方法

SegFormer(2021)

轻量高效的 Transformer 分割模型:

  • 层级 Transformer 编码器:生成多尺度特征
  • 轻量 MLP 解码器:融合多尺度特征做预测
  • 无需位置编码,通过 Mix-FFN 引入局部性

Mask2Former(2022)

统一框架,一个模型同时处理语义分割、实例分割和全景分割:

  • 使用 Masked Attention:每个 query 只关注其对应区域的特征
  • 引入多尺度特征:在 FPN 的不同层级上做交叉注意力

SAM(Segment Anything Model,2023)

Meta 提出的通用分割基础模型,在 11M 张图像上训练,可以分割"任何东西"。

graph LR
    A[图像] --> B[Image Encoder<br/>ViT-H]
    C[Prompt<br/>点/框/文本] --> D[Prompt Encoder]
    B --> E[Mask Decoder]
    D --> E
    E --> F[分割掩码]

三种提示方式

  1. 点提示:点击物体上的一个或多个点
  2. 框提示:画一个边界框
  3. 文本提示:用文字描述要分割的物体

SAM 的革命性意义

SAM 是视觉领域的"GPT 时刻"——一个预训练模型可以零样本泛化到各种分割任务,无需针对特定数据集微调。SAM 2 进一步扩展到了视频分割。


九、损失函数

像素级交叉熵

最基本的分割损失,对每个像素独立计算分类损失:

\[ L_{CE} = -\frac{1}{N}\sum_{i=1}^{N} \sum_{c=1}^{C} y_{ic} \log(\hat{y}_{ic}) \]

问题:当类别不平衡时(如前景只占图像 5%),模型倾向于全部预测为背景。

Dice Loss

直接优化 Dice 系数(F1 Score 的连续版本):

\[ L_{\text{Dice}} = 1 - \frac{2 \sum_i p_i g_i}{\sum_i p_i + \sum_i g_i} \]

其中 \(p_i\) 是预测概率,\(g_i\) 是真实标签。

优势:对类别不平衡不敏感,即使前景很少也能有效训练。

Focal Loss

给简单样本降权,让模型关注困难像素(参见目标检测章节)。

实际使用

通常组合使用:

\[ L = L_{CE} + \lambda \cdot L_{\text{Dice}} \]

十、总结与对比

方法 类型 核心创新 适用场景
FCN 语义分割 全卷积化 + 跳跃连接 基础方法,教学理解
U-Net 语义分割 对称编码器-解码器 + 跳跃拼接 医学图像、小数据集
DeepLab v3+ 语义分割 空洞卷积 + ASPP 自动驾驶、通用分割
Mask R-CNN 实例分割 Faster R-CNN + 掩码分支 需要区分实例的场景
Panoptic FPN 全景分割 实例 + 语义统一 完整场景理解
SAM 通用分割 大规模预训练 + 提示交互 零样本泛化