mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6mobile wallpaper 7mobile wallpaper 8mobile wallpaper 9mobile wallpaper 10mobile wallpaper 11mobile wallpaper 12mobile wallpaper 13
4169 字
13 分鐘
图像分割
2026-04-27

第 10 章 图像分割#

学习目标:系统掌握把图像划分为有意义区域的所有经典方法——阈值、边缘、区域、聚类、图论、变分——及其在工业场景中的选择依据。 分割 (Segmentation) 是”从像素到语义”的桥梁,也是计算机视觉几乎所有高层任务的前置。


10.1 什么是图像分割?#

10.1.1 形式化定义#

定义 10.1:给定图像 (I),分割是把像素集 (P) 划分为不相交子集 ({R_1, \ldots, R_k}): [ \bigcup_{i=1}^{k} R_i = P, \quad R_i \cap R_j = \emptyset (i \neq j) ]

并满足:

  1. 每个 (R_i) 是连通
  2. 同一 (R_i) 内的像素满足某种均匀性(灰度近似、纹理相似)
  3. 不同 (R_i) 间有显著差异

10.1.2 分割的三种抽象层次#

层次输出示例
语义分割 (Semantic)每像素赋”类别”所有人 = 人
实例分割 (Instance)每像素赋”物体 ID”人 1、人 2、人 3
全景分割 (Panoptic)上两者融合天空 + 人 1 + 人 2

10.1.3 分割方法的分类#

分割方法
├─ 基于阈值 (Threshold)
├─ 基于边缘 (Edge-based)
├─ 基于区域 (Region-based)
├─ 基于聚类 (Clustering)
├─ 基于图论 (Graph-based)
├─ 基于变分 (Variational / Level Set)
├─ 基于特征/模板
└─ 基于深度学习 (CNN, Transformer)

本章讲前 6 类经典方法;深度学习在第 12 章。


10.2 基于阈值的分割#

10.2.1 全局阈值#

最简单: [ g(x, y) = \begin{cases} 1 & f(x, y) > T \ 0 & f(x, y) \le T \end{cases} ]

关键:如何选 T?

10.2.2 基础算法(迭代)#

1. 初始 T = mean(image)
2. 用 T 分割成前景/背景
3. T' = (mean_fg + mean_bg) / 2
4. 若 |T' - T| < ε 停止,否则 T = T',回到 2

快速但对直方图依赖。

10.2.3 Otsu 方法(必会)#

Nobuyuki Otsu 1979 的经典方法,基于最大化类间方差

推导#

设阈值 (T),前景 (C_1)(灰度 (\le T))、背景 (C_2)(> T)。

  • 概率:(P_1(T) = \sum_{i=0}^{T} p_i),(P_2(T) = 1 - P_1)
  • 均值:(m_1(T) = \frac{1}{P_1} \sum_{i=0}^{T} i p_i),(m_2 = \frac{1}{P_2} \sum_{i=T+1}^{L-1} i p_i)
  • 全局均值:(m_G = P_1 m_1 + P_2 m_2)

类间方差: [ \sigma_B^2(T) = P_1 (m_1 - m_G)^2 + P_2 (m_2 - m_G)^2 = P_1 P_2 (m_1 - m_2)^2 ]

Otsu:选 (T^* = \arg\max_T \sigma_B^2(T))。

几何直觉#

两类方差总和 = 组内方差 + 组间方差(ANOVA 方差分解)。

  • 总方差固定(图像内禀属性)
  • 最大化组间 = 最小化组内
  • 组间大 = 两类均值距离大 → 最”分得开”

实现#

_, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

适用条件#

Otsu 假设双峰直方图(前景 + 背景两个明显聚集)。当直方图单峰(如光照均匀的文字),Otsu 也可给出合理结果。但直方图扁平(如噪声大、渐变光照),效果差。

10.2.4 多级 Otsu#

推广到 (K) 类: [ \sigma_B^2 = \sum_{k=1}^{K} P_k (m_k - m_G)^2 ] 搜索 (K-1) 个阈值使上式最大。

复杂度指数级 (L^{K-1}),(K = 3, L = 256) 可枚举;更多类要动态规划 / GA。

10.2.5 基于噪声抗性的改进#

Otsu 对噪声敏感。改进:

  • 先高斯平滑再 Otsu
  • 基于梯度加权:对梯度大的像素权重大(它们更可能在类边界)

10.2.6 自适应(局部)阈值#

全局阈值对非均匀光照无能为力。

方法:每个像素的阈值由其局部邻域计算。 [ T(x, y) = \text{mean}(邻域) - C ] 或 [ T(x, y) = \text{Gaussian_weighted_mean}(邻域) - C ]

Niblack: [ T = m + k \sigma, \quad k \in (-0.5, 0) ]

Sauvola(文档处理): [ T = m \left[1 + k \left(\frac{\sigma}{R} - 1\right)\right] ]

adaptive = cv2.adaptiveThreshold(
gray, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY,
blockSize=11, C=2
)

适合:OCR、车牌、扫描文档的预处理。


10.3 基于边缘的分割#

10.3.1 边缘的物理本质#

图像中灰度发生剧变的地方 → 对应三维场景中的:

  • 物体与背景的交界
  • 不同物体的交界
  • 表面法线突变(角、棱)
  • 不同材质的交界
  • 阴影边界

理想边缘:阶跃 (step) 实际边缘:斜坡 (ramp) + 噪声

10.3.2 Canny 边缘检测(工业标准)#

John Canny 1986 设计了满足三个最优性的边缘检测器:

  1. 良好检测:真边缘被检测出(低漏检)
  2. 精确定位:检测位置准(低偏差)
  3. 单响应:每个真边缘仅响应一次(不重影)

Canny 证明这三者下的最优核 ≈ 高斯函数的一阶导。

Canny 算法(5 步)#

Step 1: 高斯平滑
I_s = G_σ * I
Step 2: 计算梯度
g_x = Sobel_x(I_s), g_y = Sobel_y(I_s)
M = sqrt(g_x² + g_y²)
θ = atan2(g_y, g_x)
Step 3: 非极大值抑制 (NMS)
沿梯度方向查看相邻两点
若 M(当前) 不是局部最大 → 置 0
→ 把粗边缘变成 1 像素宽
Step 4: 双阈值
M > T_high : 强边缘
T_low < M < T_high : 弱边缘
M < T_low : 非边缘
Step 5: 滞后连接
保留强边缘
若弱边缘与强边缘连通 → 保留
否则 → 丢弃

NMS 详解#

对每像素 (p),根据 (\theta) 把梯度方向离散化为 4 个方向之一:

  • 0° / 180°:水平
  • 45° / 225°:对角
  • 90° / 270°:垂直
  • 135° / 315°:反对角

比较 (M(p)) 与沿该方向两侧邻居的幅值,只保留最大。

双阈值的作用#

  • 若只有单阈值:低了噪声多,高了边缘断
  • 双阈值 + 滞后:强边缘作为”种子”,延伸到弱边缘 → 既降噪又保完整

经验:(T_{\text{high}} / T_{\text{low}} \approx 2-3)。

edges = cv2.Canny(gray, threshold1=50, threshold2=150)

10.3.3 其他一阶检测器#

回顾第 3 章:Sobel、Prewitt、Scharr。单独使用常不如 Canny。

10.3.4 LoG 与 Marr-Hildreth#

Laplacian of Gaussian (LoG): [ \text{LoG}(x, y) = \nabla^2 G_\sigma = -\frac{1}{\pi \sigma^4} \left[1 - \frac{x^2 + y^2}{2\sigma^2}\right] e^{-(x^2+y^2)/(2\sigma^2)} ]

  • 先高斯平滑再二阶导(合并为一个核更快)
  • 边缘 = 过零点 (zero-crossing)

Marr-Hildreth:LoG + 过零点检测 = 边缘。

LoG 核形如”墨西哥帽”:

▁▁▁ (零轴)
/ \
/ ▂ \
/ ╱ ╲ \
/ ╱ ╲ \
─╱ ╲─

DoG 近似:(\text{LoG} \approx G_{\sigma_1} - G_{\sigma_2})((\sigma_2 = 1.6 \sigma_1)),速度快。是 SIFT 的基础(第 11 章)。

10.3.5 从边缘到线段:Hough 变换#

线检测#

动机:边缘给出孤立的点,想把它们聚合成”整条直线”。

参数化:直线 (y = mx + c)?但垂直线 (m = \infty)。改用法向式: [ \rho = x \cos\theta + y \sin\theta ]

每个图像点 ((x, y)) 对应参数空间 ((\theta, \rho)) 的一条正弦曲线。

Hough 累加器

for each edge pixel (x, y):
for each θ in [0, π]:
ρ = x cos θ + y sin θ
accumulator[θ_bin, ρ_bin] += 1
找 accumulator 的局部极大 → 每个极大值对应一条检测到的直线
lines = cv2.HoughLines(edges, rho=1, theta=np.pi/180, threshold=200)
# 概率 Hough(返回端点)
lines_p = cv2.HoughLinesP(edges, rho=1, theta=np.pi/180, threshold=100,
minLineLength=50, maxLineGap=10)

圆检测#

圆参数 ((a, b, r)) 三维累加器。OpenCV 的 HoughCircles 先检测圆心,再估半径。

circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, dp=1, minDist=30,
param1=50, param2=30, minRadius=10, maxRadius=100)

广义 Hough(任意形状)#

R-表存储模板形状相对参考点的偏移。可检测任何固定形状。


10.4 基于区域的分割#

10.4.1 区域生长#

算法

1. 选 seed 点集 S
2. 对每个 seed s,初始化区域 R = {s}
3. 对 R 的 8-邻域像素 p:
若 p 满足相似准则 (|f(p) - f(s)| < T) → 加入 R
4. 重复直到无新像素加入

相似准则

  • 灰度差 < T
  • 与区域均值差 < T(自适应)
  • 纹理 / 颜色差

优点:生成连通区域,适合单物体分割。 缺点:seed 选择敏感、计算慢(每次扩展需遍历)。

10.4.2 区域分裂与合并 (Split & Merge)#

四叉树分裂

1. 把整幅图看作一个区域
2. 若区域内方差 > T → 分成 4 个子区域
3. 递归,直到每个叶子均匀

合并:相邻叶子若满足均匀性 → 合并。

优点:自适应、多尺度。 缺点:边界仍是方块状。

10.4.3 分水岭 (Watershed)#

直觉#

把图像灰度当作地形高度

  • 低处是”盆地”
  • 高处是”分水岭”

模拟洪水

  • 从每个局部极小点开始”注水”
  • 水位上涨,水向四周蔓延
  • 两个盆地的水相遇时 → 筑坝(标记为分割边界)
  • 继续直到所有区域被覆盖

最终分割线就是这些筑坝位置。

灰度地形: 分水岭:
╱╲ ╱╲ ┃ ┃ ┃
╱ ╲ ╱ ╲ ┃ ┃ ┃
╱ ╲╱ ╲ ┃ ┣━━━┫
┃ ┃ ┃

直接用梯度作为地形#

对原图求梯度,梯度作为高度 → 边界(高梯度处)成为分水岭。

过分割问题#

图像中每个局部极小都会产生一个区域 → 典型图像有几百上千个 → 严重过分割。

Marker-based Watershed(解决方案)#

思路:用户指定合理数量的 marker(前景 + 背景),只在 marker 处”注水”。

# 典型流程:金币分割
img = cv2.imread('coins.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
# 去小噪
kernel = np.ones((3, 3), np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)
# 确定背景(膨胀后仍是背景的区域)
sure_bg = cv2.dilate(opening, kernel, iterations=3)
# 确定前景(距离变换远离边界的区域)
dist = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
_, sure_fg = cv2.threshold(dist, 0.7 * dist.max(), 255, 0)
sure_fg = np.uint8(sure_fg)
# 未确定区域
unknown = cv2.subtract(sure_bg, sure_fg)
# 标记
_, markers = cv2.connectedComponents(sure_fg)
markers += 1 # 背景从 1 开始(0 留给未知)
markers[unknown == 255] = 0
# 分水岭
markers = cv2.watershed(img, markers)
img[markers == -1] = [0, 0, 255] # 边界标红

经典应用:细胞计数、金币分割、粘连物体分离。

10.4.4 Mean-Shift 分割#

思想:把每个像素 ((x, y, R, G, B)) 视为 5D 特征空间的点。对每个点做均值漂移聚类: [ \mathbf{m}(\mathbf{x}) = \frac{\sum_{\mathbf{x}_i \in B(\mathbf{x}, r)} \mathbf{x}_i}{|B(\mathbf{x}, r)|} - \mathbf{x} ] 每次向局部密度中心移动,直至收敛。收敛到同一模式的所有点 → 同一簇。

参数

  • sp:空间带宽(像素位置尺度)
  • sr:颜色带宽
smoothed = cv2.pyrMeanShiftFiltering(img, sp=20, sr=50)

特点

  • 不需指定聚类数
  • 保留边缘,视觉效果好
  • (5D 邻域搜索)

10.5 基于聚类的分割#

10.5.1 K-Means#

回忆机器学习经典算法:

1. 随机初始化 K 个中心
2. 每点 → 最近中心(分配)
3. 每中心 ← 所属点的均值(更新)
4. 迭代到收敛

在图像分割中:把每像素看作 3D (RGB) 或 5D (RGBXY) 点,聚类。

data = img.reshape(-1, 3).astype(np.float32)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 4
_, labels, centers = cv2.kmeans(data, K, None, criteria, 10, cv2.KMEANS_PP_CENTERS)
segmented = centers[labels.flatten()].reshape(img.shape).astype(np.uint8)

优点:简单、快。 缺点

  • 需指定 K
  • 非凸簇分不好
  • 不保证空间连通

10.5.2 SLIC 超像素#

Simple Linear Iterative Clustering (Achanta 2012)。

超像素 (Superpixel):一组空间邻近且颜色相似的像素 → 保留边缘的”大像素”。

算法:K-Means 在 5D (LAB + XY) 空间,空间距离约束在某个步长 S 内: [ D = \sqrt{\left(\frac{d_{\text{color}}}{m}\right)^2 + \left(\frac{d_{\text{spatial}}}{S}\right)^2} ]

from skimage.segmentation import slic
segments = slic(img, n_segments=500, compactness=10)

用途

  • CNN 分割前的”降维”
  • 交互分割的基本单元
  • 降低后续算法复杂度(500 超像素 vs 500000 像素)

10.6 基于图论的分割#

10.6.1 图的构造#

把图像建模成图:

  • 节点 (V) = 像素(或超像素)
  • (E) = 相邻像素之间的连接
  • 权重 (w(i, j)) = 相似度(颜色、纹理)

[ w(i, j) = e^{-|F_i - F_j|^2 / \sigma^2} ]

分割 = 图划分。

10.6.2 Normalized Cut#

Shi & Malik 2000 的里程碑。

定义”切”: [ \text{cut}(A, B) = \sum_{i \in A, j \in B} w(i, j) ] (两分区之间的总权重)

minimum cut 的问题:倾向切出孤立小区域(边少)。

归一化切 (Ncut): [ \text{Ncut}(A, B) = \frac{\text{cut}(A, B)}{\text{assoc}(A, V)} + \frac{\text{cut}(A, B)}{\text{assoc}(B, V)} ] 其中 (\text{assoc}(A, V) = \sum_{i \in A, j \in V} w(i, j))。

求解:NP-hard。松弛后变为广义特征值问题: [ (D - W) y = \lambda D y ] 取第 2 小特征值对应的特征向量,阈值化即分割。

递归:对每个子图继续 Ncut,形成树状分层分割。

10.6.3 Graph Cut / GrabCut#

Boykov & Jolly 2001:把分割建模为最小能量问题: [ E(L) = \underbrace{\sum_i D_i(l_i)}{\text{data term}} + \lambda \underbrace{\sum{(i, j) \in N} V_{ij}(l_i, l_j)}_{\text{smoothness term}} ]

  • (D_i(l_i)):像素 (i) 被标为 (l_i \in {0, 1}) 的代价(基于颜色模型)
  • (V_{ij}):相邻像素标签不同的惩罚

最大流 / 最小割 算法求解全局最优。

GrabCut(Rother 2004):用户友好版本#

用户画一个(或涂几笔)标出前景 ROI:

  1. 框外 → 确定背景
  2. 框内 → 可能是前景
  3. 用 GMM 建前景/背景颜色模型
  4. Graph Cut 求解
  5. 用结果更新 GMM,迭代
mask = np.zeros(img.shape[:2], np.uint8)
bgdModel = np.zeros((1, 65), np.float64)
fgdModel = np.zeros((1, 65), np.float64)
rect = (50, 50, 300, 400)
cv2.grabCut(img, mask, rect, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_RECT)
mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
result = img * mask2[:, :, None]

经典应用:PS”魔术棒”/“快速选择”、证件照背景替换。


10.7 基于变分的分割:Level Set#

10.7.1 思路:把曲线演化为能量下降#

主动轮廓 (Snake)(Kass 1988):曲线 (C),能量: [ E(C) = \underbrace{\int \alpha |C’|^2 + \beta |C”|^2}{\text{内能(平滑)}} + \underbrace{\int E{\text{image}}(C)}_{\text{外能(图像驱动)}} ]

外能常取负梯度幅值 (E_{\text{image}} = -|\nabla I|^2)(引导向边缘靠)。

梯度下降演化曲线到最小能量 → 分割。

10.7.2 Level Set (Osher & Sethian 1988)#

问题:Snake 不能自然处理拓扑变化(曲线分裂、合并)。

思路:用隐式函数 (\phi(x, y)) 表示曲线: [ C = {(x, y) : \phi(x, y) = 0} ]

  • (\phi > 0) 在内部
  • (\phi < 0) 在外部

曲线演化转为 (\phi) 的演化: [ \frac{\partial \phi}{\partial t} = -F |\nabla \phi| ] (F) 是演化速度(依赖于图像)。

优势

  • 拓扑变化自然((\phi = 0) 可以自动断开或合并)
  • 易推广到 3D

10.7.3 Chan-Vese 模型(2001)#

不依赖边缘的变分分割: [ E(\phi) = \mu \int \delta(\phi) |\nabla \phi| + \lambda_1 \int (I - c_1)^2 H(\phi) + \lambda_2 \int (I - c_2)^2 (1 - H(\phi)) ]

  • (c_1, c_2):前景 / 背景平均灰度
  • 目的:把图像划分为两个平均灰度最均匀的区域

适合无明显边缘、但前景背景色调一致的场景(医学超声、显微镜)。


10.8 各方法对比与选型#

方法速度准确性是否需参数适用场景
阈值 (Otsu)极快自动高对比度、背景简单
Adaptive Thresh光照不均文档
Canny + Hough高(线/圆)需调几何检测
区域生长需种子已知种子位置
分水岭需 marker粘连物体
Mean-Shift带宽自动色块
K-MeansK色调分组
SLIC 超像素n_segments作为中间表示
Ncut极高理论分析
GrabCut极高用户框交互抠图
Level Set极高医学成像
CNN (Unet 等)快(GPU)最高训练数据通用场景(Ch 12)

10.9 评估指标#

10.9.1 像素级#

[ \text{Pixel Acc} = \frac{\text{correct pixels}}{\text{total}} ]

问题:类别不平衡时不可靠。

10.9.2 IoU / Jaccard#

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

mIoU:各类 IoU 平均。

10.9.3 Dice#

[ \text{Dice} = \frac{2 |A \cap B|}{|A| + |B|} ]

与 IoU 等价:(\text{Dice} = 2 \text{IoU} / (1 + \text{IoU}))。

医学图像常用。

10.9.4 边界级#

  • Hausdorff 距离
  • 轮廓 F-score

10.10 本章要点与面试考点#

✅ 必须掌握#

  • 分割的严格定义与分类
  • Otsu 公式及推导(类间方差)
  • 自适应阈值的必要性
  • Canny 五步(高斯、梯度、NMS、双阈值、滞后)
  • Hough 变换的参数空间与累加器思想
  • 分水岭过分割 + Marker-based 解决方案
  • K-Means 在 RGB/LAB 空间分割
  • GrabCut = GMM + Graph Cut
  • 主要评估指标(IoU、Dice)

💡 高频面试题#

Q1. Otsu 的最大化类间方差为什么等价于最小化类内方差?

答:方差分解 (\sigma_{\text{total}}^2 = \sigma_W^2 + \sigma_B^2)(within + between)。因为 (\sigma_{\text{total}}) 对图像固定,最大化 (\sigma_B) = 最小化 (\sigma_W)。直觉:两类均值拉开得越远,同时组内越紧凑,就越”分得清”。

Q2. 为什么 Canny 要用双阈值?

答:

  • 单高阈值:强边缘清晰但容易断裂
  • 单低阈值:边缘完整但噪声很多假边
  • 双阈值 + 滞后:强边缘作种子,向连通的弱边缘延伸,兼顾降噪与完整

Q3. Hough 变换为什么用 ((\rho, \theta)) 而不是 ((k, b))?

答:(y = kx + b) 在垂直线时 (k = \infty),参数空间无法有限采样。法线式 (\rho = x \cos\theta + y \sin\theta) 中 (\theta \in [0, \pi))、(\rho) 有界,可以合理离散化累加器。

Q4. 分水岭为什么常过分割?如何解决?

答:每个局部极小点都会产生一个盆地。自然图像中几百个局部极小很常见 → 几百个区域。解决方法:

  1. 先平滑减少噪声极小
  2. Marker-based:只允许 marker 点作为种子
  3. 基于梯度后再平滑

Q5. GrabCut 的流程?

答:

  1. 用户画矩形框,框外标确定背景
  2. 对框内像素用 GMM(高斯混合模型)建颜色分布
  3. 建图(像素为节点,相邻连边,权重 = 颜色相似度)
  4. Graph Cut (min-cut / max-flow) 求最优分割
  5. 根据新标签更新 GMM,迭代

Q6. K-Means 分割和 Mean-Shift 分割的区别?

答:

  • K-Means:参数 K;寻找全局最小代价;对初值敏感
  • Mean-Shift:无需 K;局部密度上爬;自动聚类数;但慢

Q7. 为什么用 SLIC 超像素?

答:

  1. 降维:把 1000000 个像素变成 1000 个超像素,后续算法快 1000 倍
  2. 保边:超像素严格贴合物体边界
  3. 中间表示:许多高层分割算法(Ncut、CRF)本身对像素数敏感

Q8. 分割评价常用 IoU 而非像素准确率?

答:像素准确率在前景很小(如小肿瘤、小目标)时失真严重——“全预测为背景”可达到 99% 准确率但完全无效。IoU 只看交集与并集的比例,对前景大小不敏感,更反映真实分割质量。


10.11 延伸阅读#

  • Gonzalez, Digital Image Processing (4th), Ch. 10-11
  • Szeliski, Computer Vision (2nd), Ch. 4-5
  • Canny, “A Computational Approach to Edge Detection”, IEEE TPAMI 1986
  • Otsu, “A Threshold Selection Method from Gray-Level Histograms”, 1979
  • Shi & Malik, “Normalized Cuts and Image Segmentation”, IEEE TPAMI 2000
  • Rother et al., “GrabCut: Interactive Foreground Extraction”, SIGGRAPH 2004
  • Achanta et al., “SLIC Superpixels”, IEEE TPAMI 2012

下一章:分割告诉我们”像素属于谁”;特征提取要回答”它们代表什么”——如何把图像压缩成少量但强鲁棒的描述子,用于识别、匹配、检索?

分享

如果這篇文章對你有幫助,歡迎分享給更多人!

图像分割
https://lemusakuya.com/posts/study-notes/digital-image-processing/10_图像分割/
作者
レム・咲く夜
發布於
2026-04-27
許可協議
CC BY-NC-SA 4.0

部分資訊可能已經過時

目錄