传统图像分割:阈值 / 区域生长 / 分水岭 / 图割全解析【计算机视觉】
- [传统图像分割(Traditional Image Segmentation)](#传统图像分割(Traditional Image Segmentation))
-
- Ⅰ、引言
- [Ⅱ、阈值分割(Threshold Segmentation)------ 基于灰度的基础分割方法](#Ⅱ、阈值分割(Threshold Segmentation)—— 基于灰度的基础分割方法)
- [Ⅲ、区域生长(Region Growing)------ 基于连通性的图像分割方法](#Ⅲ、区域生长(Region Growing)—— 基于连通性的图像分割方法)
- [Ⅳ、分水岭分割(Watershed)------ 基于拓扑结构的图像分割方法](#Ⅳ、分水岭分割(Watershed)—— 基于拓扑结构的图像分割方法)
- [Ⅴ、图割分割(Graph Cut)------ 基于能量最小化的图像分割方法](#Ⅴ、图割分割(Graph Cut)—— 基于能量最小化的图像分割方法)
- Ⅵ、总结
传统图像分割(Traditional Image Segmentation)
传统图像分割是计算机视觉领域中最基础、最经典的像素级划分任务,核心解决"将图像按照灰度、纹理、空间结构等特征自动分离为前景与背景、目标与区域"的问题,不依赖深度学习,完全基于数学规则与图像拓扑结构实现分割,是医学影像、工业检测、目标提取、图像分析等场景的经典技术支撑。
注意:本文所有代码均可导入Jupyter Notebook
完整代码仓库地址:🔗 GitHub:https://github.com/KnifeWen007/CV---StudyNotebook
Ⅰ、引言
在计算机视觉任务中,图像分割处于"从图像到目标"的关键环节------它不像滤波只做预处理,也不像特征检测只寻找关键点,而是直接对图像进行区域划分,让机器理解"哪里是目标、哪里是背景"。在深度学习普及之前,传统分割方法凭借可解释性强、运算速度快、无需数据集等优势,长期占据图像处理的核心地位。
传统图像分割的四大经典技术------阈值分割、区域生长、分水岭分割、图割分割,分别从灰度聚类、区域连通、地形模拟、图论优化四个角度实现分割,覆盖从简单到复杂、从快速到高精度的全场景需求,共同构成了传统视觉分割最完整、最经典的技术体系。本文将系统讲解四大算法的原理、优缺点、适用场景与代码实现,帮助你彻底掌握传统图像分割的核心思想。
Ⅱ、阈值分割(Threshold Segmentation)------ 基于灰度的基础分割方法
一、核心思想
阈值分割是最简单、最高效的传统图像分割算法,核心是通过选取一个或多个灰度阈值,将图像像素划分为不同类别,仅依靠像素灰度差异实现前景与背景分离,无需复杂迭代与拓扑计算,是灰度差异明显场景的首选分割方案。
二、数学原理
(1)基础定义
灰度图像像素灰度值 x ∈ [ 0 , 255 ] x \in [0,255] x∈[0,255],设定分割阈值 T T T,对所有像素执行二值化判决:
g ( x ) = { 255 ( 前景 ) , x > T 0 ( 背景 ) , x ≤ T g(x) = \begin{cases} 255 \quad (前景), & x > T \\ 0 \quad (背景), & x \le T \end{cases} g(x)={255(前景),0(背景),x>Tx≤T
解释:像素灰度大于阈值 T 判定为前景(白色255),小于等于 T 判定为背景(黑色0)。
多阈值分割( T 1 < T 2 < ⋯ < T k − 1 T_1<T_2<\dots<T_{k-1} T1<T2<⋯<Tk−1):
g ( x ) = { 0 , x < T 1 L 1 , T 1 ≤ x < T 2 ⋮ L n , x ≥ T k − 1 g(x) = \begin{cases} 0, & x<T_1 \\ L_1, & T_1\le x<T_2 \\ \vdots \\ L_n, & x\ge T_{k-1} \end{cases} g(x)=⎩ ⎨ ⎧0,L1,⋮Ln,x<T1T1≤x<T2x≥Tk−1
解释:使用多个阈值将灰度值分为多个区间,不同区间赋予不同灰度等级。
(2)最优阈值算法(Otsu 最大类间方差法)
Otsu 算法无需人工设定阈值,通过最大化前景与背景的类间方差自动求解最优阈值 T ∗ T^* T∗。
- 基础参数
总像素数 N N N,灰度级 0 ∼ L − 1 0 \sim L-1 0∼L−1,灰度 i i i 出现概率 p i = n i N p_i = \frac{n_i}{N} pi=Nni,满足 ∑ i = 0 L − 1 p i = 1 \sum_{i=0}^{L-1} p_i = 1 i=0∑L−1pi=1
解释:p_i 表示某一灰度值的出现概率,所有灰度概率之和为 1。
- 类别划分
以阈值 T T T 将像素分为两类:
C 0 C_0 C0(背景): 0 ∼ T 0 \sim T 0∼T; C 1 C_1 C1(前景): T + 1 ∼ L − 1 T+1 \sim L-1 T+1∼L−1
解释:阈值 T 将像素划分为背景(低灰度)与前景(高灰度)两类。
- 核心公式
类别概率:
ω 0 ( T ) = ∑ i = 0 T p i , ω 1 ( T ) = 1 − ω 0 ( T ) \omega_0(T) = \sum_{i=0}^{T} p_i, \quad \omega_1(T) = 1-\omega_0(T) ω0(T)=i=0∑Tpi,ω1(T)=1−ω0(T)
解释:ω0 是背景像素占比,ω1 是前景像素占比,两者之和为 1。
类别均值:
μ 0 = 1 ω 0 ∑ i = 0 T i p i , μ 1 = 1 ω 1 ∑ i = T + 1 L − 1 i p i \mu_0 = \frac{1}{\omega_0}\sum_{i=0}^T i p_i,\quad \mu_1 = \frac{1}{\omega_1}\sum_{i=T+1}^{L-1} i p_i μ0=ω01i=0∑Tipi,μ1=ω11i=T+1∑L−1ipi
解释:μ0 为背景平均灰度,μ1 为前景平均灰度。
全局均值: μ = ω 0 μ 0 + ω 1 μ 1 \mu = \omega_0\mu_0 + \omega_1\mu_1 μ=ω0μ0+ω1μ1
解释:整张图像所有像素的平均灰度。
类间方差:
σ b 2 ( T ) = ω 0 ω 1 ( μ 0 − μ 1 ) 2 \sigma_b^2(T) = \omega_0\omega_1(\mu_0-\mu_1)^2 σb2(T)=ω0ω1(μ0−μ1)2
解释:类间方差越大,说明前景与背景区分越明显,分割效果越好。
- 最优阈值
T ∗ = arg max 0 < T < L − 1 σ b 2 ( T ) T^* = \arg\max_{0<T<L-1} \sigma_b^2(T) T∗=arg0<T<L−1maxσb2(T)
解释:遍历所有可能阈值,选出使类间方差最大的阈值 T*,即为最佳分割阈值。
三、代码实现
python
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 绘图显示设置
plt.rcParams["font.family"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
%matplotlib inline
# 读取车牌图像
img = cv2.imread("car_plate.jpg")
if img is not None:
# 灰度化处理
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 高斯模糊去噪
blur = cv2.GaussianBlur(gray, (3, 3), 0)
# 自动阈值二值化
ret, thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 形态学闭运算,填充字符间隙
kernel = np.ones((2, 2), np.uint8)
th_clean = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
# 查找图像轮廓
contours, hierarchy = cv2.findContours(th_clean, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
char_list = []
h_img, w_img = th_clean.shape
# 筛选符合字符尺寸的轮廓
for cnt in contours:
x, y, w, h = cv2.boundingRect(cnt)
if 0.2 * h_img < h < 0.9 * h_img and 0.1 < w/h < 1.2 and w < 0.2 * w_img:
# 去重判断
is_duplicate = False
for (cx, cy, cw, ch) in char_list:
if abs(x - cx) < 5 and abs(y - cy) < 5:
is_duplicate = True
break
if not is_duplicate:
char_list.append((x, y, w, h))
# 按从左到右排序
char_list = sorted(char_list, key=lambda ch: ch[0])
print("分割字符数:", len(char_list))
# 横向显示分割结果
if len(char_list) > 0:
plt.figure(figsize=(len(char_list)*1.8, 2.5))
for i, (x, y, w, h) in enumerate(char_list):
char_img = th_clean[y:y+h, x:x+w]
char_img = cv2.resize(char_img, (40, 60))
plt.subplot(1, len(char_list), i+1)
plt.imshow(char_img, cmap="gray")
plt.axis("off")
plt.tight_layout()
plt.show()
else:
print("图片读取失败")


核心函数
python
ret, thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
| 项目 | 内容 |
|---|---|
| 作用 | 将灰度图转为黑白二值图,自动计算最优阈值,分离前景与背景 |
| 参数 | blur:输入灰度图像 0:启用自动计算阈值 255:前景像素设为白色 cv2.THRESH_BINARY:二值化方式 cv2.THRESH_OTSU:自动求最佳阈值 |
| 返回值 | ret:计算出的最优阈值 thresh:二值化后的黑白图像 |
四、算法特点
- 优点:计算速度极快、逻辑简单、可解释性强、无参数依赖(Otsu)
- 缺点:仅依赖灰度信息,对光照敏感、无法处理灰度重叠的复杂图像
- 适用场景:灰度对比度高、背景单一的图像(工业零件检测、文档二值化、简单目标提取)
Ⅲ、区域生长(Region Growing)------ 基于连通性的图像分割方法
一、核心思想
区域生长是一种基于区域连通性 的图像分割算法,从预先选定的种子点 出发,按照设定的相似性准则,将周围灰度、纹理等特征相近的像素不断合并到当前区域,最终形成完整的目标分割区域。
二、数学原理
(1)相似性判断公式
区域生长依据灰度相似性 实现像素合并。设种子点为 S ( x 0 , y 0 ) S(x_0,y_0) S(x0,y0),当前生长区域为 R R R,区域平均灰度为 μ R \mu_R μR,邻域待判断像素为 p ( x , y ) p(x,y) p(x,y),其灰度为 I ( x , y ) I(x,y) I(x,y),相似度阈值为 T T T。
像素合并规则为:
∣ I ( x , y ) − μ R ∣ ≤ T |I(x,y) - \mu_R| \le T ∣I(x,y)−μR∣≤T
I ( x , y ) I(x,y) I(x,y):待合并像素的灰度值
μ R \mu_R μR:当前生长区域所有像素的平均灰度值
T T T:灰度相似阈值(人工设定)满足条件则将该像素归入区域 R R R,并更新区域平均灰度。
(2)区域更新规则
每加入一个新像素,区域平均灰度重新计算:
μ R ′ = μ R × N + I ( x , y ) N + 1 \mu_R' = \frac{\mu_R \times N + I(x,y)}{N+1} μR′=N+1μR×N+I(x,y)
N N N:区域生长前的像素总数
μ R ′ \mu_R' μR′:加入新像素后的区域平均灰度
I ( x , y ) I(x,y) I(x,y):新加入像素的灰度值
(3)停止条件
当种子点的连通邻域内不存在满足相似条件的像素 时,生长终止,数学表达为:
∄ p ( x , y ) ∉ R 满足 ∣ I ( x , y ) − μ R ∣ ≤ T \nexists \ p(x,y) \notin R \quad \text{满足} \quad |I(x,y) - \mu_R| \le T ∄ p(x,y)∈/R满足∣I(x,y)−μR∣≤T
解释:所有外围像素与当前区域的灰度差都超过阈值,无法继续合并,区域生长结束。
三、算法步骤
python
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams["font.family"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
%matplotlib inline
# 区域生长算法
def region_growing(img, seed, threshold=10):
h, w = img.shape
result = np.zeros_like(img)
stack = [seed]
result[seed] = 255
mean_val = float(img[seed])
neighbors = [(-1,-1),(-1,0),(-1,1),
(0,-1), (0,1),
(1,-1), (1,0),(1,1)]
count = 1
while stack:
x, y = stack.pop()
for dx, dy in neighbors:
nx, ny = x + dx, y + dy
if 0 <= nx < h and 0 <= ny < w:
if result[nx, ny] == 0:
if abs(int(img[nx, ny]) - mean_val) <= threshold:
result[nx, ny] = 255
stack.append((nx, ny))
mean_val = (mean_val * count + img[nx, ny]) / (count + 1)
count += 1
return result
# ===================== 主程序 =====================
img = cv2.imread("brain_ct.jpg", 0)
seed = (320, 350) # 病灶中心点
# 三种阈值效果
res1 = region_growing(img, seed, threshold=3) # 太小 → 几乎不长
res2 = region_growing(img, seed, threshold=15) # 正好 → 完美分割
res3 = region_growing(img, seed, threshold=40) # 太大 → 长过头
# 画图对比
plt.figure(figsize=(16, 10))
plt.subplot(2, 2, 1)
plt.imshow(img, cmap="gray")
plt.title("脑部CT原图")
plt.subplot(2, 2, 2)
plt.imshow(res1, cmap="gray")
plt.title("阈值太小(分割失败)")
plt.subplot(2, 2, 3)
plt.imshow(res2, cmap="gray")
plt.title("阈值合适(分割成功)")
plt.subplot(2, 2, 4)
plt.imshow(res3, cmap="gray")
plt.title("阈值太大(过度生长)")
plt.show()

函数讲解
python
def region_growing(img, seed, threshold=10)
入参
img:输入的灰度图像
seed:种子点(生长起始坐标)
threshold:灰度相似阈值
核心逻辑
以种子点为起点,检查8 邻域像素,满足灰度差值≤阈值就标记为目标,持续扩散直至无符合条件的像素。
关键语句
边界判断:0 <= nx < h and 0 <= ny < w
生长规则:abs(int(img[nx, ny]) - mean_val) <= threshold
流程
- 选择种子点作为生长起点
- 设定相似性规则 与连通规则(4/8邻域)
- 遍历邻域像素,满足条件则加入生长区域
- 重复迭代直至无法继续扩展
- 输出最终分割区域
四、算法特点
- 优点:原理直观、连通目标分割效果好、可控制生长范围
- 缺点:依赖种子点、对噪声与阈值敏感、效率较低
Ⅳ、分水岭分割(Watershed)------ 基于拓扑结构的图像分割方法
一、核心思想
分水岭分割是一种基于图像拓扑形态 的分割算法,将图像灰度值看作地形高度,灰度低的区域视为山谷,灰度高的区域视为山脊。算法从预先标记的种子区域 开始注水,水位逐渐上升,不同区域的水相遇时形成分水岭(边界) ,最终实现粘连目标、复杂区域、多目标的精准分割。
二、数学原理
(1)地形模型
将灰度图像 I ( x , y ) I(x,y) I(x,y) 视为三维拓扑地形 ,灰度值 I I I 对应地形海拔高度。
灰度越低 → 地势越低(山谷)
灰度越高 → 地势越高(山脊)
(2)局部极小值与注水原理
分水岭算法从图像中的局部极小值点 开始模拟"注水"过程。
设极小值区域为 L i L_i Li,随着水位 h h h 逐渐升高,不同山谷的积水区域不断扩张。
当不同区域的水面相遇时,形成分隔坝 ,即分水岭边界。
(3)距离变换公式(核心标记依据)
用于提取可靠前景种子,避免过分割:
D ( x , y ) = min ( x 0 , y 0 ) ∈ 背景 ( x − x 0 ) 2 + ( y − y 0 ) 2 D(x,y) = \min_{(x_0,y_0) \in \text{背景}} \sqrt{(x-x_0)^2 + (y-y_0)^2} D(x,y)=(x0,y0)∈背景min(x−x0)2+(y−y0)2
D ( x , y ) D(x,y) D(x,y):当前像素到最近背景点的欧氏距离
距离越大 → 越靠近目标中心 → 越可靠作为前景标记
(4)标记生成规则
设最大距离为 max ( D ) \max(D) max(D),取比例系数 α \alpha α(如 0.1),则:
sure_fg ( x , y ) = { 255 , D ( x , y ) ≥ α ⋅ max ( D ) 0 , 其他 \text{sure\_fg}(x,y) = \begin{cases} 255, & D(x,y) \ge \alpha \cdot \max(D) \\ 0, & \text{其他} \end{cases} sure_fg(x,y)={255,0,D(x,y)≥α⋅max(D)其他
(5)分水岭分割数学表达
设输入图像为 I I I,输出分割区域为 R 1 , R 2 , . . . , R n R_1,R_2,...,R_n R1,R2,...,Rn,边界为 B B B:
watershed ( I ) = { R 1 , ( x , y ) ∈ 目标区域1 R 2 , ( x , y ) ∈ 目标区域2 ⋮ R n , ( x , y ) ∈ 目标区域n B , ( x , y ) ∈ 分水岭边界 \text{watershed}(I) = \begin{cases} R_1, & (x,y) \in \text{目标区域1} \\ R_2, & (x,y) \in \text{目标区域2} \\ \vdots & \\ R_n, & (x,y) \in \text{目标区域n} \\ B, & (x,y) \in \text{分水岭边界} \end{cases} watershed(I)=⎩ ⎨ ⎧R1,R2,⋮Rn,B,(x,y)∈目标区域1(x,y)∈目标区域2(x,y)∈目标区域n(x,y)∈分水岭边界
算法输出中,边界统一标记为 -1。
(6)过分割抑制原理
通过确定前景 + 确定背景 构建强制标记:
KaTeX parse error: Expected 'EOF', got '_' at position 29: ...n} = \text{sure_̲bg} - \text{sur...
未知区域不参与初始标记,让算法仅在可信区域间生成边界,大幅减少过分割。
三、算法步骤
python
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 支持中文显示
plt.rcParams["font.family"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
# 读取图像(换成你的图片路径)
img = cv2.imread("kodim01.png")
img_copy = img.copy()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# --------------------- 分水岭核心步骤 ---------------------
# 1. 二值化(Otsu自动阈值)
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 2. 形态学操作:去噪
kernel = np.ones((3, 3), np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)
# 3. 确定背景
sure_bg = cv2.dilate(opening, kernel, iterations=3)
# 4. 距离变换 → 确定前景
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
ret, sure_fg = cv2.threshold(dist_transform, 0.1 * dist_transform.max(), 255, 0)
# 5. 制作标记
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg, sure_fg)
ret, markers = cv2.connectedComponents(sure_fg)
markers += 1
markers[unknown == 255] = 0
# 6. 分水岭算法
markers = cv2.watershed(img_copy, markers)
# 7. 画出分割线(红色)
img_copy[markers == -1] = [0, 0, 255]
# --------------------- 显示结果 ---------------------
plt.figure(figsize=(16, 8))
plt.subplot(131)
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.title("原图")
plt.subplot(132)
plt.imshow(markers, cmap="jet")
plt.title("标记图")
plt.subplot(133)
plt.imshow(cv2.cvtColor(img_copy, cv2.COLOR_BGR2RGB))
plt.title("分水岭分割结果")
plt.tight_layout()
plt.show()

关键函数讲解
python
cv2.watershed(img_copy, markers)
-
入参
img_copy:执行分水岭的彩色图像,用于绘制分割边界
markers:自定义标记图像(未知区域=0,确定背景=1,确定前景≥2) -
核心逻辑
基于前期二值化、形态学操作、距离变换生成的可靠标记,
在图像中自动识别区域分界,生成分水岭分割线,
实现房屋、建筑等目标的区域分割。
-
关键规则
算法执行后,分水岭边界会被标记为 -1
通过
img_copy[markers == -1] = [0, 0, 255]将分割线标为红色标记质量直接决定分割效果,是分水岭算法的核心
四、算法特点
- 优点 :可分割粘连、重叠、复杂结构;分割精度高;OpenCV内置函数,速度快
- 缺点 :极度依赖标记;无标记易过分割;对噪声敏感
Ⅴ、图割分割(Graph Cut)------ 基于能量最小化的图像分割方法
一、核心思想
图割分割是一种基于图论与能量最小化 的图像分割算法。
将图像抽象为网络图结构 :像素作为节点,相邻像素间的相似度作为边权,同时构建前景(目标)、背景(非目标)两个终端节点。
算法通过最小化全局能量函数,寻找最优割集,将图像划分为目标与背景两类区域。
二、数学原理
(1)网络流模型
将图像映射为无向图 G = ( V , E ) G=(V,E) G=(V,E):
- V V V:节点集合(所有像素 + 前景源点 S S S + 背景汇点 T T T)
- E E E:边缘集合(相邻像素连接、像素与 S / T S/T S/T 连接)
(2)能量函数定义(核心)
算法最小化全局能量函数 E ( A ) E(A) E(A),由区域项 E r e g i o n E_{region} Eregion 和平滑项 E s m o o t h E_{smooth} Esmooth 组成:
E ( A ) = E r e g i o n ( A ) + λ ⋅ E s m o o t h ( A ) E(A) = E_{region}(A) + \lambda \cdot E_{smooth}(A) E(A)=Eregion(A)+λ⋅Esmooth(A)
- E r e g i o n ( A ) E_{region}(A) Eregion(A):区域项,衡量像素属于前景/背景的概率
- λ \lambda λ:平滑系数,控制区域连续性权重
- E s m o o t h ( A ) E_{smooth}(A) Esmooth(A):平滑项,保证相邻像素分割结果一致
(3)最小割/最大流原理
最优分割等价于最小割(Min Cut) ,即切断最少权重的边,使 S S S、 T T T 不连通。
根据最大流最小割定理,通过求解最大流得到最小割,完成分割。
(4)分割判定规则
G r a p h C u t ( I ) = { 1 , 像素属于前景目标 0 , 像素属于背景区域 GraphCut(I)= \begin{cases} 1, & \text{像素属于前景目标} \\ 0, & \text{像素属于背景区域} \end{cases} GraphCut(I)={1,0,像素属于前景目标像素属于背景区域
三、算法步骤
python
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams["font.family"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
# 读取图像(和.ipynb同目录,文件名完全一致)
img = cv2.imread("kodim20.png")
img_copy = img.copy()
h, w = img.shape[:2]
# 初始化掩模(必须创建)
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, w - 100, h - 100)
# 执行图割分割(GrabCut 基于图割实现)
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[:, :, np.newaxis]
# 结果可视化
plt.figure(figsize=(12, 6))
plt.subplot(121), plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)), plt.title("原图")
plt.subplot(122), plt.imshow(cv2.cvtColor(result, cv2.COLOR_BGR2RGB)), plt.title("图割分割结果")
plt.show()

关键函数讲解(图割 GrabCut)
python
cv2.grabCut(img, mask, rect, bgdModel, fgdModel, iterCount, mode)
-
输入参数
img:输入的彩色原图mask:掩模图像,标记前景、背景、可能前景、可能背景rect:用矩形框住想要分割的目标(x, y, width, height)bgdModel:背景模型(内部计算使用,固定格式)fgdModel:前景模型(内部计算使用,固定格式)iterCount:算法迭代次数(一般设 3~5)mode:初始化模式,使用矩形框初始化:cv2.GC_INIT_WITH_RECT
-
核心功能
基于图割理论 ,自动学习前景(房屋)和背景的颜色特征,
通过能量最小化实现精准前景提取,把目标从背景中分离出来。
-
执行效果
算法会自动更新
mask:- 0 = 确定背景
- 1 = 确定前景
- 2 = 可能背景
- 3 = 可能前景
最后通过掩模将背景置黑,只保留房屋主体。
四、算法特点
- 优点 :分割精度高、抗噪声强、适合复杂背景与不规则目标
对房屋、卫星图、人像等目标分割效果优异 - 缺点 :需要手动初始化矩形框/标记,无法全自动分割
复杂图像计算速度较慢
Ⅵ、总结
本文系统梳理了阈值分割、区域生长、分水岭分割、图割分割四大经典传统图像分割算法,从核心思想、数学原理、代码实现到算法特性进行了完整解析,四种算法各具优势与适用场景,共同构成了传统图像分割的核心技术体系,具体对比与总结如下:
四大传统图像分割算法对比表
| 算法类型 | 核心思想 | 核心优势 | 主要缺点 | 适用场景 |
|---|---|---|---|---|
| 阈值分割 | 基于像素灰度差异,通过阈值将图像二值化,分离前景与背景 | 运算速度极快、逻辑简单、可解释性强,Otsu算法无需手动调参 | 仅依赖灰度信息,对光照敏感,无法处理灰度重叠的复杂图像 | 灰度对比度高、背景单一的场景(文档二值化、工业零件检测、简单目标提取) |
| 区域生长 | 从种子点出发,依据灰度相似性准则,合并相邻相似像素形成目标区域 | 原理直观、连通目标分割效果好,可手动控制生长范围 | 依赖种子点选择,对噪声与阈值敏感,运算效率较低 | 目标结构明确、连通性好的图像(医学影像病灶分割、单一连通目标提取) |
| 分水岭分割 | 将图像视为三维地形,通过模拟注水过程,构建分水岭边界实现区域分割 | 擅长分割粘连、重叠目标,分割精度高,OpenCV内置函数易实现 | 极度依赖前景/背景标记,无标记易出现过分割,对噪声敏感 | 多目标、粘连目标、复杂拓扑结构的图像(建筑分割、密集目标划分) |
| 图割分割 | 将图像抽象为网络图,通过最小化能量函数、求解最大流实现前景与背景分离 | 分割精度高、抗噪声强,边缘平滑,适合复杂背景下的目标提取 | 需要手动初始化矩形框/标记,无法全自动分割,复杂图像运算速度较慢 | 复杂背景、不规则目标的前景提取(房屋分割、人像抠图、卫星图目标提取) |
综上,传统图像分割算法无需依赖数据集训练,具有可解释性强、运算效率高、部署成本低的优势,尽管在复杂场景下的表现不及深度学习分割方法,但在工业检测、医学影像初筛、简单目标提取等实际工程场景中,仍具有不可替代的应用价值。在实际应用中,可根据图像特征、目标类型与任务需求,选择合适的分割算法,或结合多种算法的优势实现更精准的分割效果。
上一章
霍夫变换:几何特征检测与量化验证【计算机视觉】https://blog.csdn.net/R_Feynman_/article/details/158855945