youcans 的 OpenCV 例程200篇179.图像分割之 GrabCut 图割法(掩模图像)
Posted 小白YouCans
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了youcans 的 OpenCV 例程200篇179.图像分割之 GrabCut 图割法(掩模图像)相关的知识,希望对你有一定的参考价值。
【youcans 的 OpenCV 例程200篇】177.图像分割之 GraphCuts 图割法
【youcans 的 OpenCV 例程200篇】178.图像分割之 GrabCut 图割法(框选前景)
【youcans 的 OpenCV 例程200篇】179.图像分割之 GrabCut 图割法(掩模图像)
【youcans 的 OpenCV 例程200篇】179.图像分割之 GrabCut 图割法(掩模图像)
6. 图像分割之图割法
基于图论的图像分割技术的基本思想是:将图像映射为带权的无向图,把像素视为节点,两个节点之间的边的权重对应于两个像素之间相似性的度量,割的容量就对应于能量函数;使用最大流最小割算法对图进行切割,得到的最小割就对应于最优图像分割。
6.3 图割分割算法 GrabCut
GrabCut 算法是对 GraphCut 的改进,使用高斯混合模型(GMM)对背景和目标建立模型,采用迭代方法实现分割能量的最小化,同时支持不完整的标记。
GrabCut 算法有效利用了图像中的纹理(颜色)信息和边界(反差)信息,只需要要少量的人工交互操作就可以对目标实现较好的分割效果。
OpenCV 也提供了函数 cv.grabCut 实现 GrabCut 图割算法。
函数说明:
cv.grabCut(img, mask, rect, bgdModel, fgdModel, iterCount[, mode=GC_EVAL]) → mask, bgdModel, fgdModel
参数说明:
- image:输入图像,8-bit/3-channel 彩色图像
- mask:输入/输出掩模,8-bit 单通道图像,如边界框选则自动产生掩模图像
- rect:包含分割对象的边框矩形,格式为 (x,y,w,h),仅在 mode 为 cv2.GC_INIT_WITH_MASK 时适用
- bgdModel:建模背景使用的临时数组,形状为 (1,65) 的 np.float 数组
- fgdModel:建模前景时使用的临时数组,形状为 (1,65) 的 np.float 数组
- iterCount:迭代次数
- mode:操作模式
- cv.GC_INIT_WITH_RECT:使用边界矩形初始化状态和掩模图像,运行迭代算法
- cv.GC_INIT_WITH_MASK:使用提供的掩模图像进行状态初始化
- cv.GC_EVAL:表示算法应该恢复
- cv.GC_EVAL_FREEZE_MODEL:用固定模型执行一次迭代算法
OpenCV 的 GrabCut 返回一个3元组 (mask, bgdModel, fgdModel)
- mask: 应用GrabCut后的输出掩模
- bgModel: 用于建模背景的临时数组(可以忽略此值)
- fgModel: 用于建模前景的临时数组(同样,你可以忽略此值)
注意事项:
- OpenCV 的 GrabCut 返回元组 (mask, bgdModel, fgdModel),mask 是应用 GrabCut 算法后的输出掩模。
- 迭代次数越多,GrabCut 运行的时间越长,理想情况下的性能会更好。
- cv.GC_INIT_WITH_RECT 和 cv.GC_INIT_WITH_MASK 可以组合使用。
例程 11.36: GrabCut 图割分割算法(掩模图像)
例程11.34 通过手动设置边界框对 GrabCut 算法进行初始化,我们也可以使用掩模图像进行初始化。掩模图像提供了图像中物体的近似分割,GrabCut 算法可以迭代地应用图割对分割结果进行改进,从图像中提取前景。
如何生成掩模图像与 GrabCut 算法无关,掩模图像也并不需要很精确。掩模图像可以通过 Photoshop 等编辑软件手动创建,也可以应用阈值分割、边缘检测、轮廓滤波等方法获取,还可以利用深度学习方法获得。
# Copyright 2022 Youcans, XUPT
# Crated:2021-12-27
# 11.36 GrabCut 图割分割算法(掩模图像)
image = cv2.imread("../images/imgDeer.png", flags=1) # 读取彩色图像(BGR)
maskImg = cv2.imread("../images/imgDeerMask.png", flags=0) # 读取掩模图像(xupt)
# 生成掩模图像 mask,大于 0 的像素设为可能前景
mask = np.zeros(image.shape[:2], dtype="uint8")
mask[maskImg > 0] = cv2.GC_PR_FGD
mask[maskImg == 0] = cv2.GC_BGD
# print(mask.shape, maskInv.shape)
# apply GrabCut using the the mask segmentation method
fgModel = np.zeros((1, 65), dtype="float") # 前景模型, 13*5
bgModel = np.zeros((1, 65), dtype="float") # 背景模型, 13*5
iter = 5
(mask, bgModel, fgModel) = cv2.grabCut(image, mask, None, bgModel, fgModel, iter,
mode=cv2.GC_INIT_WITH_MASK) # 基于掩模图像初始化
# 将所有确定背景和可能背景像素设置为 0,而确定前景和可能前景像素设置为 1
maskOutput = np.where((mask == cv2.GC_BGD) | (mask == cv2.GC_PR_BGD), 0, 1)
maskGrabCut = 255 - (maskOutput * 255).astype("uint8")
imgGrabCut = cv2.bitwise_and(image, image, mask=maskGrabCut)
plt.figure(figsize=(10, 6))
plt.subplot(231), plt.axis('off'), plt.title("Origin image")
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) # 显示 img(RGB)
plt.subplot(232), plt.axis('off'), plt.title("Mask image")
plt.imshow(maskImg, 'gray') # definite background
plt.subplot(233), plt.axis('off'), plt.title("GrabCut mask")
plt.imshow(mask, 'gray')
plt.subplot(234), plt.axis('off'), plt.title("Mask for definite background")
maskBGD = (mask == cv2.GC_BGD).astype("uint8") * 255
plt.imshow(maskBGD, 'gray') # definite background
plt.subplot(235), plt.axis('off'), plt.title("Mask for probable background")
maskPBGD = (mask == cv2.GC_PR_BGD).astype("uint8") * 255
plt.imshow(maskPBGD, 'gray') # probable background
# plt.subplot(235), plt.axis('off'), plt.title("GrabCut Mask")
# plt.imshow(maskGrabCut, 'gray') # mask generated by GrabCut
plt.subplot(236), plt.axis('off'), plt.title("Youcans Output")
plt.imshow(cv2.cvtColor(imgGrabCut, cv2.COLOR_BGR2RGB)) # GrabCut Output
plt.tight_layout()
plt.show()
(本节完)
版权声明:
OpenCV 例程200篇 总目录-202205更新
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/124744517)
Copyright 2022 youcans, XUPT
Crated:2022-5-12
欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中
欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中【youcans 的 OpenCV 例程200篇】147. 图像分割之孤立点检测
【youcans 的 OpenCV 例程200篇】148. 图像分割之线检测
【youcans 的 OpenCV 例程200篇】149. 图像分割之边缘模型
【youcans 的 OpenCV 例程200篇】150. 边缘检测梯度算子
【youcans 的 OpenCV 例程200篇】151. 边缘检测中的平滑处理
【youcans 的 OpenCV 例程200篇】152. 边缘检测之 LoG 算子
【youcans 的 OpenCV 例程200篇】153. 边缘检测之 DoG 算子
【youcans 的 OpenCV 例程200篇】154. 边缘检测之 Canny 算子
【youcans 的 OpenCV 例程200篇】155. 边缘连接的局部处理方法
【youcans 的 OpenCV 例程200篇】156. 边缘连接局部处理的简化算法
【youcans 的 OpenCV 例程200篇】157. 霍夫变换直线检测
【youcans 的 OpenCV 例程200篇】158. 阈值处理之固定阈值法
【youcans 的 OpenCV 例程200篇】159. 图像分割之全局阈值处理
【youcans 的 OpenCV 例程200篇】160. 图像处理之OTSU 方法
【youcans 的 OpenCV 例程200篇】161. OTSU 阈值处理算法的实现
【youcans 的 OpenCV 例程200篇】162. 全局阈值处理改进方法
【youcans 的 OpenCV 例程200篇】163. 基于边缘信息改进全局阈值处理
【youcans 的 OpenCV 例程200篇】164.使用 Laplace 边缘信息改进全局阈值处理
【youcans 的 OpenCV 例程200篇】165.多阈值 OTSU 处理方法
【youcans 的 OpenCV 例程200篇】166.自适应阈值处理
【youcans 的 OpenCV 例程200篇】167.基于移动平均的可变阈值处理
【youcans 的 OpenCV 例程200篇】168.图像分割之区域生长
【youcans 的 OpenCV 例程200篇】169.图像分割之区域分离
【youcans 的 OpenCV 例程200篇】170.图像分割之K均值聚类
【youcans 的 OpenCV 例程200篇】171.SLIC 超像素区域分割
【youcans 的 OpenCV 例程200篇】172.SLIC 超像素区域分割算法比较
【youcans 的 OpenCV 例程200篇】173.SEEDS 超像素区域分割
【youcans 的 OpenCV 例程200篇】174.LSC 超像素区域分割
【youcans 的 OpenCV 例程200篇】175.超像素区域分割方法比较
【youcans 的 OpenCV 例程200篇】176.图像分割之均值漂移算法
【youcans 的 OpenCV 例程200篇】177.图像分割之 GraphCuts 图割法
【youcans 的 OpenCV 例程200篇】178.图像分割之 GrabCut 图割法(框选前景)
【youcans 的 OpenCV 例程200篇】179.图像分割之 GrabCut 图割法(掩模图像)
以上是关于youcans 的 OpenCV 例程200篇179.图像分割之 GrabCut 图割法(掩模图像)的主要内容,如果未能解决你的问题,请参考以下文章
youcans 的 OpenCV 例程200篇184.鼠标交互标记的分水岭算法
youcans 的 OpenCV 例程200篇183.基于轮廓标记的分水岭算法