图像分割算法¶
图像分割(Image Segmentation)是计算机视觉中最精细的理解任务——将图像中的每一个像素都分配一个标签,实现像素级的场景理解。
一、什么是图像分割?¶
图像分割的目标是将图像划分为若干有意义的区域,每个区域对应一个物体或类别。
即输出一张与输入同样大小的分割掩码(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. 阈值分割¶
最简单的分割方法:根据像素值设定阈值将图像分为前景和背景。
- 全局阈值:整张图用同一个 \(T\)(如 Otsu 自适应阈值)
- 局部阈值:不同区域用不同的 \(T\)
Otsu 算法
自动寻找最优阈值 \(T^*\),使前景和背景的类间方差最大:
其中 \(\omega_0, \omega_1\) 是前景/背景像素比例,\(\mu_0, \mu_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)¶
解决的问题:普通卷积 + 池化会导致分辨率急剧下降,丢失空间细节。
核心思想:在卷积核的采样位置之间插入空洞(间隔),不增加参数量,就能扩大感受野。
其中 \(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 使用双线性插值在浮点坐标处采样,避免量化误差:
掩码分支¶
对每个检测到的 RoI,用一个小型 FCN(全卷积网络)预测 \(K\) 个 \(m \times m\) 的二值掩码(\(K\) 为类别数),每个类别一个掩码,根据分类结果选择对应类别的掩码作为输出。
为什么每个类别一个掩码?
这样做将分类和分割解耦:分割分支只需关注"这个像素属不属于这个物体",不需要区分类别,降低了学习难度,显著提升性能。
YOLACT(2019)¶
实时实例分割方法:
- 网络生成一组原型掩码(Prototype Masks)——全局共享的掩码基
- 对每个检测到的物体预测一组组合系数
- 用组合系数线性组合原型掩码,得到该物体的实例掩码
优点:实时速度(30 FPS),结构简洁。
七、全景分割¶
全景分割 = 语义分割 + 实例分割,对图像中的所有像素给出完整的理解:
- Thing(可数物体):人、车、动物 → 需要实例级分割
- Stuff(不可数材质):天空、道路、草地 → 只需语义分割
评价指标:PQ(Panoptic Quality)¶
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[分割掩码]
三种提示方式:
- 点提示:点击物体上的一个或多个点
- 框提示:画一个边界框
- 文本提示:用文字描述要分割的物体
SAM 的革命性意义
SAM 是视觉领域的"GPT 时刻"——一个预训练模型可以零样本泛化到各种分割任务,无需针对特定数据集微调。SAM 2 进一步扩展到了视频分割。
九、损失函数¶
像素级交叉熵¶
最基本的分割损失,对每个像素独立计算分类损失:
问题:当类别不平衡时(如前景只占图像 5%),模型倾向于全部预测为背景。
Dice Loss¶
直接优化 Dice 系数(F1 Score 的连续版本):
其中 \(p_i\) 是预测概率,\(g_i\) 是真实标签。
优势:对类别不平衡不敏感,即使前景很少也能有效训练。
Focal Loss¶
给简单样本降权,让模型关注困难像素(参见目标检测章节)。
实际使用¶
通常组合使用:
十、总结与对比¶
| 方法 | 类型 | 核心创新 | 适用场景 |
|---|---|---|---|
| FCN | 语义分割 | 全卷积化 + 跳跃连接 | 基础方法,教学理解 |
| U-Net | 语义分割 | 对称编码器-解码器 + 跳跃拼接 | 医学图像、小数据集 |
| DeepLab v3+ | 语义分割 | 空洞卷积 + ASPP | 自动驾驶、通用分割 |
| Mask R-CNN | 实例分割 | Faster R-CNN + 掩码分支 | 需要区分实例的场景 |
| Panoptic FPN | 全景分割 | 实例 + 语义统一 | 完整场景理解 |
| SAM | 通用分割 | 大规模预训练 + 提示交互 | 零样本泛化 |