当前位置:首页>python>OpenCV-Python实战|图像分割全解析:分水岭算法+GrabCut交互式前景提取(附完整代码)

OpenCV-Python实战|图像分割全解析:分水岭算法+GrabCut交互式前景提取(附完整代码)

  • 2026-10-11 08:01:18
OpenCV-Python实战|图像分割全解析:分水岭算法+GrabCut交互式前景提取(附完整代码)

在前几天的分享中,我们从图像预处理、边缘检测、轮廓处理,到傅里叶变换、模板匹配、霍夫变换,逐步解锁了OpenCV图像处理的核心技巧,覆盖了“预处理→特征提取→目标定位→形状检测”的全流程。而今天要讲的图像分割,是计算机视觉的核心技术之一——它将图像划分为多个互不重叠的区域,实现“前景与背景分离”“目标与目标分离”,是后续目标识别、图像分析、语义分割的基础。

图像分割的应用场景极为广泛:比如人像抠图(前景人物与背景分离)、工业零件分割(零件与背景分离)、医学图像分割(病灶与正常组织分离)、农作物分割(作物与土壤分离)。今天这篇实操教程,将重点拆解两种最常用的图像分割算法:分水岭算法(适合粘连目标分割)和GrabCut算法(交互式前景提取,适合前景背景分离),全程聚焦OpenCV-Python落地,避开晦涩理论,每一部分都附可复制代码、效果对比和新手避坑技巧,完美衔接此前系列内容,让新手能快速上手,轻松实现图像分割。

一、前置基础(新手必看,衔接前文)

1. 核心前提:环境配置

所有操作均基于OpenCV-Python,若未配置环境,执行以下命令一键安装/升级,适配Python 3.7-3.12,Windows/Mac/Linux全兼容(与前几篇保持一致,降低新手学习成本):

python# 安装/升级OpenCV-Python(核心依赖)pip install opencv-python -U# 安装辅助库(图像显示、数据处理、交互式操作)pip install numpy matplotlib

2. 核心概念:图像分割是什么?(通俗解读)

图像分割的核心逻辑,用一句话就能讲清:根据图像的灰度、颜色、纹理等特征,将图像划分为多个具有相似特征的区域,实现“同类区域合并、异类区域分离”。简单来说,就是“给图像中的不同目标‘贴标签’”,让前景、背景、不同目标清晰区分开来。

关键区分(新手必记):

•分水岭算法:核心解决“粘连目标分割”问题,比如一堆粘连的硬币、粘连的零件,通过“模拟水位上涨”的逻辑,将粘连目标分开,适合目标边界模糊、粘连严重的场景;

•GrabCut算法:核心解决“前景与背景分离”问题,通过交互式操作(标记前景/背景),精准提取前景目标,比如人像抠图、物体提取,适合前景背景差异较明显的场景。

举个通俗例子:一张图片中有5枚粘连在一起的硬币,用分水岭算法可以将5枚硬币清晰分开;一张图片中有一个人物和复杂背景,用GrabCut算法可以通过简单标记,将人物(前景)从背景中精准提取出来,实现抠图效果——这就是两种算法的核心应用场景差异。

3. 测试图像准备(统一对比,保持连贯)

为了让图像分割的效果更直观,同时与前几篇文章保持连贯,我们准备两类测试图:① 粘连目标图(用于分水岭算法测试);② 前景背景混合图(用于GrabCut算法测试),同时添加轻微噪声(模拟真实场景),代码如下,可直接复用(也可替换为自己的图像):

pythonimport cv2import numpy as npimport matplotlib.pyplot as plt# 1. 读取两类测试图(灰度图/彩色图,根据算法需求选择)# 测试图1:粘连目标图(用于分水岭算法,灰度图)img_watershed = cv2.imread("watershed_test.jpg", 0) # 替换为自己的图像路径# 测试图2:前景背景混合图(用于GrabCut算法,彩色图)img_grabcut = cv2.imread("grabcut_test.jpg") # 替换为自己的图像路径img_grabcut_gray = cv2.cvtColor(img_grabcut, cv2.COLOR_BGR2GRAY)# 2. 图像预处理:高斯平滑(降噪),衔接前文技巧img_watershed_blur = cv2.GaussianBlur(img_watershed, (3, 3), sigmaX=1)img_grabcut_blur = cv2.GaussianBlur(img_grabcut, (3, 3), sigmaX=1)# 显示测试图plt.figure(figsize=(10, 5))# 粘连目标图plt.subplot(1, 2, 1)plt.imshow(img_watershed_blur, cmap="gray")plt.title("粘连目标图(分水岭测试图)")plt.axis("off")# 前景背景混合图plt.subplot(1, 2, 2)plt.imshow(cv2.cvtColor(img_grabcut_blur, cv2.COLOR_BGR2RGB))plt.title("前景背景混合图(GrabCut测试图)")plt.axis("off")plt.show()

关键说明:分水岭算法通常使用灰度图(聚焦灰度特征分割),GrabCut算法通常使用彩色图(聚焦颜色特征分割),两者均需先进行高斯平滑降噪,减少噪声对分割效果的影响——这也是衔接前文边缘检测、霍夫变换预处理知识点的核心环节。

二、核心实战一:分水岭算法(粘连目标分割)

分水岭算法的核心痛点是“解决粘连目标分割”,其原理模拟“地形水位上涨”:将图像灰度值视为海拔,灰度值低的区域(暗区)先被水淹没,灰度值高的区域(亮区)作为分水岭(分割线),通过标记“种子点”,让水从种子点上涨,最终被分水岭分开的区域,就是不同的目标。

OpenCV中,分水岭算法的核心流程是:图像预处理→二值化→距离变换→寻找种子点→执行分水岭分割,全程封装完善,新手只需按流程调用函数即可。

1. 核心函数(必记)

实操中常用3个核心函数,配合完成分水岭分割,参数简单易记:

•cv2.threshold():二值化处理,将图像转为黑白二值图,突出目标与背景(复用前文二值化知识点);

•cv2.distanceTransform():距离变换,计算前景目标内部点到背景的距离,用于寻找种子点;

•cv2.watershed():核心函数,执行分水岭分割,返回分割后的标签图像。

2. 实操代码:分水岭算法分割粘连目标

结合图像预处理、二值化、距离变换,实现分水岭算法分割粘连目标,代码可直接复制运行,附详细解读:

pythonimport cv2import numpy as npimport matplotlib.pyplot as plt# 1. 读取图像并预处理(平滑降噪)img = cv2.imread("watershed_test.jpg", 0)img_blur = cv2.GaussianBlur(img, (3, 3), sigmaX=1)# 2. 二值化处理(突出目标,阈值可调整)# 反二值化:目标为白色(255),背景为黑色(0)ret, thresh = cv2.threshold(img_blur, 127, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)# 3. 形态学操作:去除噪声,填补目标内部孔洞(衔接前文形态学知识点)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)# 4. 距离变换:计算前景内部点到背景的距离,用于寻找种子点dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)# 阈值处理,得到确定的前景区域(种子点区域)ret, sure_fg = cv2.threshold(dist_transform, 0.7*dist_transform.max(), 255, 0)sure_fg = np.uint8(sure_fg)# 5. 计算不确定区域(前景与背景之间的区域)unknown = cv2.subtract(sure_bg, sure_fg)# 6. 标记种子点(为每个前景目标分配唯一标签)ret, markers = cv2.connectedComponents(sure_fg)# 所有标签+1,让背景标签从0变为1(避免与分水岭标记冲突)markers = markers + 1# 将不确定区域标记为0(让算法自动分割该区域)markers[unknown == 255] = 0# 7. 执行分水岭分割(需将灰度图转为彩色图,用于绘制分割线)img_color = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)markers = cv2.watershed(img_color, markers)# 绘制分水岭分割线(标记为红色,厚度1)img_color[markers == -1] = [0, 0, 255]# 显示效果(预处理→二值化→分割结果)plt.figure(figsize=(12, 4))# 预处理后的图像plt.subplot(1, 3, 1)plt.imshow(img_blur, cmap="gray")plt.title("预处理后图像")plt.axis("off")# 二值化图像plt.subplot(1, 3, 2)plt.imshow(thresh, cmap="gray")plt.title("二值化图像")plt.axis("off")# 分水岭分割结果plt.subplot(1, 3, 3)plt.imshow(cv2.cvtColor(img_color, cv2.COLOR_BGR2RGB))plt.title("分水岭算法分割结果")plt.axis("off")plt.tight_layout()plt.show()# 统计分割后的目标数量(标签从2开始,因为背景为1,不确定区域为0)target_count = len(np.unique(markers)) - 2print(f"共分割出{target_count}个目标")

调优技巧:

•二值化阈值:若目标与背景对比不明显,可调整cv2.threshold()的阈值(如100-150之间),或使用OTSU自动阈值(代码中已启用);

•距离变换阈值:调整0.7*dist_transform.max()中的0.7(0.5-0.8为宜),值越大,种子点越少,分割越粗;值越小,种子点越多,分割越细;

•形态学迭代次数:若目标内部有孔洞,可增加膨胀迭代次数;若有小噪声,可增加开运算迭代次数。

三、核心实战二:GrabCut算法(交互式前景提取)

GrabCut算法是一种“交互式前景提取”算法,核心优势是“无需精准标记,只需简单框选前景区域,就能自动分割前景与背景”,操作简单、提取精度高,是日常抠图、前景提取的首选算法。

其核心逻辑:先手动框选前景区域(矩形框),算法自动初始化前景、背景、不确定区域,再通过迭代优化,逐步细化前景与背景的分割边界,最终实现精准的前景提取。

1. 核心函数(必记)

GrabCut算法的核心函数为cv2.grabCut(),参数稍多但逻辑简单,核心参数如下:

pythoncv2.grabCut(img, mask, rect, bgdModel, fgdModel, iterCount, mode)

•img:输入彩色图像(必须是彩色图);

•mask:掩码图像,用于标记前景、背景、不确定区域(初始为全0);

•rect:手动框选的前景区域(x, y, w, h),x、y为矩形左上角坐标,w、h为矩形宽度、高度;

•bgdModel:背景模型(无需手动设置,初始化一个全0数组即可);

•fgdModel:前景模型(无需手动设置,初始化一个全0数组即可);

•iterCount:迭代次数(一般取5-10次,次数越多,分割越精准,速度越慢);

•mode:操作模式,新手常用cv2.GC_INIT_WITH_RECT(基于矩形框初始化)。

2. 实操代码:GrabCut交互式前景提取(抠图)

结合手动框选,实现GrabCut算法前景提取,代码可直接复制运行,附详细解读(可根据自己的图像调整矩形框坐标):

pythonimport cv2import numpy as npimport matplotlib.pyplot as plt# 1. 读取彩色图像并预处理(平滑降噪)img = cv2.imread("grabcut_test.jpg")img_blur = cv2.GaussianBlur(img, (3, 3), sigmaX=1)# 复制原始图像,用于绘制矩形框img_copy = img_blur.copy()# 2. 手动框选前景区域(x, y, w, h),需根据自己的图像调整坐标# 示例:x=50, y=50, w=300, h=400(可通过图像查看工具获取坐标)rect = (50, 50, 300, 400)# 3. 初始化掩码、背景模型、前景模型mask = np.zeros(img.shape[:2], np.uint8) # 掩码初始全0bgdModel = np.zeros((1, 65), np.float64) # 背景模型(固定格式)fgdModel = np.zeros((1, 65), np.float64) # 前景模型(固定格式)# 4. 执行GrabCut算法cv2.grabCut(img_blur,mask,rect,bgdModel,fgdModel,iterCount=5, # 迭代5次,兼顾精度和速度mode=cv2.GC_INIT_WITH_RECT # 基于矩形框初始化)# 5. 处理掩码,提取前景区域# 掩码值说明:0=背景,1=前景,2=不确定背景,3=不确定前景# 将不确定背景(2)和确定背景(0)设为0,确定前景(1)和不确定前景(3)设为255mask2 = np.where((mask == 2) | (mask == 0), 0, 255)# 将掩码转为3通道,与原始图像叠加,得到前景提取结果foreground = cv2.bitwise_and(img, img, mask=mask2.astype(np.uint8))# 6. 绘制手动框选的矩形框(用于展示)cv2.rectangle(img_copy, (rect[0], rect[1]), (rect[0]+rect[2], rect[1]+rect[3]), (0, 255, 0), 2)cv2.putText(img_copy, "Foreground Area", (rect[0], rect[1]-10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)# 显示效果(原始图+框选→掩码图→前景提取结果)plt.figure(figsize=(12, 4))# 原始图+手动框选plt.subplot(1, 3, 1)plt.imshow(cv2.cvtColor(img_copy, cv2.COLOR_BGR2RGB))plt.title("原始图+前景框选")plt.axis("off")# 掩码图plt.subplot(1, 3, 2)plt.imshow(mask2, cmap="gray")plt.title("掩码图(白色=前景)")plt.axis("off")# 前景提取结果plt.subplot(1, 3, 3)plt.imshow(cv2.cvtColor(foreground, cv2.COLOR_BGR2RGB))plt.title("GrabCut前景提取结果")plt.axis("off")plt.tight_layout()plt.show()# 保存前景提取结果(可选)cv2.imwrite("grabcut_foreground.jpg", foreground)

调优技巧:

•矩形框坐标:尽量精准框选前景区域,避免框选过多背景,减少算法迭代压力,提升提取精度;

•迭代次数:一般取5-10次,若前景与背景边界复杂,可增加到10-15次,速度会略有下降;

•手动修正(进阶):若提取结果有偏差,可手动修改掩码图(将误判的背景设为0,误判的前景设为255),再重新执行算法,提升精度。

四、进阶实操:两种算法综合应用(分割+提取)

实际场景中,常需要结合两种算法的优势:先用分水岭算法分割粘连目标,再用GrabCut算法提取单个目标的前景,形成“分割→提取→单独分析”的完整流程,我们结合前面的代码,实现综合应用,衔接前文知识点:

pythonimport cv2import numpy as npimport matplotlib.pyplot as plt# 第一步:用分水岭算法分割粘连目标img_watershed = cv2.imread("watershed_test.jpg", 0)img_watershed_blur = cv2.GaussianBlur(img_watershed, (3, 3), sigmaX=1)# 二值化+形态学操作ret, thresh = cv2.threshold(img_watershed_blur, 127, 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_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)ret, sure_fg = cv2.threshold(dist_transform, 0.7*dist_transform.max(), 255, 0)sure_fg = np.uint8(sure_fg)unknown = cv2.subtract(sure_bg, sure_fg)ret, markers = cv2.connectedComponents(sure_fg)markers = markers + 1markers[unknown == 255] = 0# 分水岭分割img_watershed_color = cv2.cvtColor(img_watershed, cv2.COLOR_GRAY2BGR)markers = cv2.watershed(img_watershed_color, markers)img_watershed_color[markers == -1] = [0, 0, 255]# 第二步:用GrabCut算法提取单个分割目标(以第一个目标为例)# 找到第一个目标的坐标范围(根据标记值筛选)target_label = 2 # 第一个目标的标记值(从2开始)target_mask = np.where(markers == target_label, 255, 0)target_mask = np.uint8(target_mask)# 找到目标的边界框(用于GrabCut框选)contours, _ = cv2.findContours(target_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)x, y, w, h = cv2.boundingRect(contours[0])rect = (x, y, w, h)# 读取彩色版粘连目标图(用于GrabCut提取)img_color = cv2.imread("watershed_test.jpg")img_color_blur = cv2.GaussianBlur(img_color, (3, 3), sigmaX=1)# 执行GrabCut提取单个目标mask_grabcut = np.zeros(img_color.shape[:2], np.uint8)bgdModel = np.zeros((1, 65), np.float64)fgdModel = np.zeros((1, 65), np.float64)cv2.grabCut(img_color_blur, mask_grabcut, rect, bgdModel, fgdModel, iterCount=5, mode=cv2.GC_INIT_WITH_RECT)# 处理掩码,得到单个目标前景mask_grabcut2 = np.where((mask_grabcut == 2) | (mask_grabcut == 0), 0, 255)single_foreground = cv2.bitwise_and(img_color, img_color, mask=mask_grabcut2.astype(np.uint8))# 显示综合应用效果plt.figure(figsize=(15, 5))# 原始粘连目标图plt.subplot(1, 3, 1)plt.imshow(cv2.cvtColor(img_color, cv2.COLOR_BGR2RGB))plt.title("原始粘连目标图")plt.axis("off")# 分水岭分割结果plt.subplot(1, 3, 2)plt.imshow(cv2.cvtColor(img_watershed_color, cv2.COLOR_BGR2RGB))plt.title("分水岭分割结果(粘连目标分离)")plt.axis("off")# GrabCut提取单个目标plt.subplot(1, 3, 3)plt.imshow(cv2.cvtColor(single_foreground, cv2.COLOR_BGR2RGB))plt.title("GrabCut提取单个目标前景")plt.axis("off")plt.tight_layout()plt.show()# 输出结果统计target_count = len(np.unique(markers)) - 2print(f"共分割出{target_count}个粘连目标,成功提取1个目标前景")

核心思路:复用分水岭算法分割粘连目标,再通过轮廓处理(衔接前文轮廓知识点)找到单个目标的边界框,最后用GrabCut算法提取该目标的前景,模拟实际项目中“先分割、再提取、再分析”的完整流程,体现系列知识的连贯性和实用性。

五、实操避坑指南(新手必看)

•分水岭算法必须做好预处理和二值化:若二值化不彻底、噪声未去除,会导致分割失败或大量误分割;建议结合形态学操作(开运算、膨胀),优化二值化效果。

•分水岭算法的“种子点”是关键:种子点不准确会导致分割偏差,可通过调整距离变换的阈值,优化种子点的数量和位置,确保每个目标都有独立的种子点。

•GrabCut算法必须使用彩色图像,若输入灰度图,会导致分割效果极差;矩形框尽量精准框选前景,避免框选过多背景,减少算法迭代压力。

•GrabCut算法的迭代次数不宜过多:迭代次数越多,分割精度略有提升,但速度会明显下降,新手优先取5-10次,满足绝大多数场景需求。

•两种算法的适用场景要区分清楚:粘连目标分割用分水岭算法,前景背景分离、抠图用GrabCut算法,避免用错场景导致效果不佳。

•处理掩码时,注意掩码的格式:必须是uint8类型,否则会导致cv2.bitwise_and()等函数报错,影响前景提取效果。

六、完整实战代码(一键复制运行)

整合以上所有操作,包含“图像预处理+分水岭算法分割+GrabCut算法提取+综合应用”,替换自己的图像路径和矩形框坐标,即可一键跑通,适合新手直接实操,巩固所有知识点,同时衔接前文系列内容:

pythonimport cv2import numpy as npimport matplotlib.pyplot as plt# 1. 环境验证(可选)print("OpenCV版本:", cv2.__version__)# 2. 读取图像(替换为自己的图像路径)# 分水岭测试图(粘连目标,灰度图)img_watershed = cv2.imread("watershed_test.jpg", 0)# GrabCut测试图(前景背景混合,彩色图)img_grabcut = cv2.imread("grabcut_test.jpg")if img_watershed is None or img_grabcut is None:print("错误:未找到图像,请检查图像路径!")else:# 3. 分水岭算法:分割粘连目标# 预处理img_watershed_blur = cv2.GaussianBlur(img_watershed, (3, 3), sigmaX=1)# 二值化+形态学操作ret, thresh = cv2.threshold(img_watershed_blur, 127, 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_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)ret, sure_fg = cv2.threshold(dist_transform, 0.7*dist_transform.max(), 255, 0)sure_fg = np.uint8(sure_fg)unknown = cv2.subtract(sure_bg, sure_fg)ret, markers = cv2.connectedComponents(sure_fg)markers = markers + 1markers[unknown == 255] = 0# 执行分水岭分割img_watershed_color = cv2.cvtColor(img_watershed, cv2.COLOR_GRAY2BGR)markers = cv2.watershed(img_watershed_color, markers)img_watershed_color[markers == -1] = [0, 0, 255]# 统计分割目标数量target_count = len(np.unique(markers)) - 2# 4. GrabCut算法:交互式前景提取# 预处理img_grabcut_blur = cv2.GaussianBlur(img_grabcut, (3, 3), sigmaX=1)img_grabcut_copy = img_grabcut_blur.copy()# 手动框选前景区域(根据自己的图像调整坐标)rect = (50, 50, 300, 400)# 初始化掩码和模型mask_grabcut = np.zeros(img_grabcut.shape[:2], np.uint8)bgdModel = np.zeros((1, 65), np.float64)fgdModel = np.zeros((1, 65), np.float64)# 执行GrabCutcv2.grabCut(img_grabcut_blur, mask_grabcut, rect, bgdModel, fgdModel, iterCount=5, mode=cv2.GC_INIT_WITH_RECT)# 处理掩码,提取前景mask_grabcut2 = np.where((mask_grabcut == 2) | (mask_grabcut == 0), 0, 255)foreground = cv2.bitwise_and(img_grabcut, img_grabcut, mask=mask_grabcut2.astype(np.uint8))# 绘制矩形框cv2.rectangle(img_grabcut_copy, (rect[0], rect[1]), (rect[0]+rect[2], rect[1]+rect[3]), (0, 255, 0), 2)cv2.putText(img_grabcut_copy, "Foreground Area", (rect[0], rect[1]-10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)# 5. 综合应用:分水岭分割+GrabCut提取单个目标# 读取彩色版粘连目标图img_color = cv2.imread("watershed_test.jpg")img_color_blur = cv2.GaussianBlur(img_color, (3, 3), sigmaX=1)# 找到第一个目标的边界框target_label = 2target_mask = np.where(markers == target_label, 255, 0)target_mask = np.uint8(target_mask)contours, _ = cv2.findContours(target_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)x, y, w, h = cv2.boundingRect(contours[0])rect_single = (x, y, w, h)# 执行GrabCut提取单个目标mask_single = np.zeros(img_color.shape[:2], np.uint8)bgdModel_single = np.zeros((1, 65), np.float64)fgdModel_single = np.zeros((1, 65), np.float64)cv2.grabCut(img_color_blur, mask_single, rect_single, bgdModel_single, fgdModel_single, iterCount=5, mode=cv2.GC_INIT_WITH_RECT)mask_single2 = np.where((mask_single == 2) | (mask_single == 0), 0, 255)single_foreground = cv2.bitwise_and(img_color, img_color, mask=mask_single2.astype(np.uint8))# 6. 统一显示所有效果plt.figure(figsize=(15, 10))# 第一行:分水岭相关plt.subplot(2, 3, 1)plt.imshow(img_watershed_blur, cmap="gray")plt.title("分水岭预处理图")plt.axis("off")plt.subplot(2, 3, 2)plt.imshow(thresh, cmap="gray")plt.title("分水岭二值化图")plt.axis("off")plt.subplot(2, 3, 3)plt.imshow(cv2.cvtColor(img_watershed_color, cv2.COLOR_BGR2RGB))plt.title(f"分水岭分割({target_count}个目标)")plt.axis("off")# 第二行:GrabCut相关+综合应用plt.subplot(2, 3, 4)plt.imshow(cv2.cvtColor(img_grabcut_copy, cv2.COLOR_BGR2RGB))plt.title("GrabCut框选前景")plt.axis("off")plt.subplot(2, 3, 5)plt.imshow(cv2.cvtColor(foreground, cv2.COLOR_BGR2RGB))plt.title("GrabCut前景提取")plt.axis("off")plt.subplot(2, 3, 6)plt.imshow(cv2.cvtColor(single_foreground, cv2.COLOR_BGR2RGB))plt.title("综合应用:提取单个分割目标")plt.axis("off")plt.tight_layout()plt.show()# 7. 保存结果(可选)cv2.imwrite("watershed_result.jpg", img_watershed_color)cv2.imwrite("grabcut_result.jpg", foreground)cv2.imwrite("single_target_result.jpg", single_foreground)

最后总结(衔接系列,强化记忆)

从图像预处理、边缘检测、轮廓处理、傅里叶变换、模板匹配、霍夫变换,到今天的图像分割(分水岭+GrabCut),我们已经完整掌握了OpenCV图像处理的核心技术体系——预处理→特征提取→目标定位→形状检测→图像分割,图像分割作为后续目标识别、语义分割的基础,填补了“目标分离”的空白,是工业质检、人像抠图等实际项目的核心工具。

两种算法的核心记忆点:分水岭算法解决“粘连目标分割”,核心流程是“预处理→二值化→距离变换→种子点→分割”;GrabCut算法解决“前景背景分离”,核心是“手动框选→迭代优化→前景提取”,新手只需区分清楚适用场景,结合前文的预处理、轮廓处理技巧,调整好关键参数,就能轻松实现精准分割。

实际项目中,图像分割常与前面所学的技术结合使用——先用霍夫变换检测目标形状,再用分水岭算法分割粘连目标,最后用GrabCut算法提取前景,结合轮廓处理分析目标尺寸、形状,形成“检测→分割→提取→分析”的完整流程,这也是后续我们要讲解的核心内容。

辛苦大家看到这里啦,如果你觉得这篇OpenCV实操教程对你有帮助,麻烦动动小手,点赞+在看,让更多学习计算机视觉、OpenCV的小伙伴看到,一起交流学习、共同进步~

关注【AI与计算机视觉】,后台回复「图像分割」,即可免费获取本文完整代码、测试素材(含粘连目标图、前景背景混合图),还有更多OpenCV实战教程,助力大家快速上手,搞定图像分割全流程!

评论区留言「分割实操」,我们一起打卡练习,互相交流遇到的问题,深耕计算机视觉,解锁更多实战技巧!后续我们将讲解图像分割与目标识别的结合应用,衔接今天的内容,记得持续关注哦~

最新文章

随机文章