4.3 区域分割


4.3 区域分割

本节摘要:SOURCE 4.3 区域生长:从种子点合并相似邻域。本节动手实现 4-连通区域生长,并与 floodFill、分水岭概念对照。

阅读收获

  1. 实现基于灰度差的区域生长
  2. 使用 cv2.floodFill 快速填充
  3. 说明分水岭对过度分割的处理

一、区域生长算法

import cv2, numpy as np def region_grow(img, seed, thresh=10): h, w = img.shape out = np.zeros((h,w), np.uint8) stack = [seed] val = int(img[seed[1], seed[0]]) while stack: x, y = stack.pop() if out[y,x]: continue if abs(int(img[y,x]) - val) > thresh: continue out[y,x] = 255 for dx, dy in [(1,0),(-1,0),(0,1),(0,-1)]: nx, ny = x+dx, y+dy if 0<=nx<w and 0<=ny<h: stack.append((nx, ny)) return out

相似准则:|I(p)-I(seed)| ≤ thresh。

二、floodFill

img_color = cv2.imread('color.jpg') cv2.floodFill(img_color, None, (100,100), (0,255,0), loDiff=(10,10,10), upDiff=(10,10,10))

OpenCV 内置连通填充 — 交互选点常用。

三、分水岭(概念)

梯度图作地形,标记前景/背景种子,cv2.watershed 解决粘连物体分割。过度分割时用标记控制

区域分割方法

区域分割方法

区域分割方法

四、实验

  1. 在均匀物体上选种子,thresh=5/15/30 对比
  2. floodFill 与自写 region_grow 结果 diff
  3. 读 OpenCV watershed 教程样例(可选)

⚠️ 常见坑:种子点在边缘 — 生长跨界;换种子或先平滑。

💡 关键直觉:区域法用相似性;边缘法用不连续性 — 互补。

要点串联

  • 区域生长需种子+阈值
  • floodFill 是工程快捷方式
  • 分水岭处理粘连
  • 常与边缘/阈值结果融合

第 5 章特征提取与匹配。

区域生长:从种子到同质区域

区域生长是最直观的分割方法:选一个种子点,把它周围满足"相似准则"的像素纳入区域,再以新像素为起点继续扩张,直到没有新的可纳入像素。相似准则最常见的是灰度差:|I(p) - I(seed)| 小于阈值即纳入。它的优点是简单、可控、结果直接是连通区域;缺点是结果依赖种子点和阈值,且对光照渐变敏感(远离种子后灰度漂移会被阈值拦住)。适合"目标内部灰度均匀、与背景差异明显"的场景。

# 相似准则还可以基于邻域均值而不是固定种子值 def region_grow_mean(img, seed, thresh=8, max_iters=50000): h, w = img.shape out = np.zeros((h, w), np.uint8) stack = [seed] xs, ys = [], [] while stack and len(xs) < max_iters: x, y = stack.pop() if out[y, x]: continue out[y, x] = 255 xs.append(x); ys.append(y) # 动态更新区域均值,容忍缓慢灰度漂移 region_mean = int(img[ys, xs].mean()) for dx, dy in [(1,0),(-1,0),(0,1),(0,-1)]: nx, ny = x+dx, y+dy if 0 <= nx < w and 0 <= ny < h and not out[ny, nx]: if abs(int(img[ny, nx]) - region_mean) <= thresh: stack.append((nx, ny)) return out

floodFill 与区域生长的关系

floodFill 是 OpenCV 内置的填充算法,与区域生长思想一致:从种子点出发,把与种子连通且落在指定差值范围内的区域填充成新颜色。区别在于实现是高度优化的 C 代码,速度远快于 Python 自写版本,且支持 8 邻域、带掩膜、限定范围。工程上"交互式选点分割"(用户点一下,目标被抠出来)就是 floodFill 的典型应用。理解自己写的 region_grow 能帮助你读懂 floodFill 的 loDiff/upDiff 参数含义——它们就是相似准则的上下界。

分水岭:从地形图到粘连分离

分水岭把梯度图想象成地形:灰度梯度高的地方是山脊(分水岭),低的地方是山谷(集水盆)。从用户标记的种子(前景标记和背景标记)往盆地里灌水,水从各盆底涨到山脊相遇即停止,相遇的边界就是分割线。它的优势是能分离相互粘连的物体(如堆叠的工件、重叠的细胞),这是阈值和区域生长做不到的;问题是噪声会产生大量伪盆地,导致过分割。对策是"标记控制"——先用形态学距离变换等确定可靠的前景和背景标记,只在这些标记间灌水,过分割问题大幅缓解。

分割方法的选型逻辑值得总结:目标与背景灰度分离明显、光照均匀 → 阈值分割;边界清晰需要轮廓线 → 边缘检测;目标内部均匀但边界模糊 → 区域生长;目标相互粘连 → 分水岭(加标记控制)。三种方法可以融合使用,比如先阈值得粗掩膜,再区域生长细化,或先边缘后填充内部。

实验建议:对同一目标选三个不同种子点(目标中心、目标边缘、背景),观察区域生长结果的差异,直观体会"种子质量决定结果质量";再把 thresh 从 5 调到 30,观察区域从欠分割到过分割的渐变过程。

一个工程提醒:区域生长对噪声敏感,种子点附近的噪声可能让区域"漏"到背景里。先做轻微高斯平滑再生长,或者在相似准则里加邻域一致性约束,都能显著提升稳定性。

补一个与深度学习分割的衔接:区域生长"基于相似性合并"的思想,与深度语义分割的"像素聚类"在本质上一致,只是相似性的度量从手工的灰度差变成了学习到的特征距离。超像素算法(SLIC)把像素聚成紧凑的超像素块,就是区域思想的现代延伸,常被用作深度分割的前处理以降低计算量。分水岭的"标记控制"思想也启发了现代实例分割里的种子点方法。理解传统区域方法,等于掌握了理解这些现代算法的底层框架,这也是本章虽然古老却仍然值得精读的原因。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U