交互式前景提取使用GrabCut算法
cv.grabCut() 是 OpenCV 中用于执行 GrabCut 算法的函数。该函数可以将输入图像分割为前景和背景。
下面是 cv.grabCut() 函数的基本语法:
cv.grabCut(img, mask, rect, bgdModel, fgdModel, iterCount, mode=None)
参数说明:
- img:输入图像,通常是一个三通道的彩色图像。
- mask:掩膜(Mask)图像,与输入图像具有相同的尺寸,用于初始化和更新算法的分割结果。
- rect:一个矩形区域,表示待提取前景的初始矩形框。它的格式为 (x, y, width, height)。
- bgdModel 和 fgdModel:这些是内部使用的数组,用于存储算法得到的背景模型和前景模型。它们应该初始化为全零数组,大小为 (1, 65)。
- iterCount:迭代次数,用于控制算法的收敛性。
- mode(可选):指定执行算法的模式,可选择的值包括 cv.GC_INIT_WITH_RECT(使用矩形和输入图像初始化算法)和 cv.GC_INIT_WITH_MASK(使用掩膜和输入图像初始化算法)。
在调用 cv.grabCut() 函数之后,算法会根据给定的参数对图像进行分割,并更新掩膜的值。通常,前景像素被标记为 cv.GC_FGD 或 cv.GC_PR_FGD,背景像素被标记为 cv.GC_BGD 或 cv.GC_PR_BGD。
- 计算机根据我们提供的数据进行初 始标记。它标记前景和背景像素(或对其进行硬标记),现在使用高斯混合模型(GMM)对前景和 背景进行建模。
- 根据我们提供的数据,GMM可以学习并创建新的像素分布。也就是说,未知像素根据颜色统计上与其他硬标记像素的关系而被标记为可能的前景或可能的背景(就像聚类一 样)。
要根据 GrabCut 分割结果提取前景区域,可以使用如下代码:
mask2 = np.where((mask==cv.GC_FGD) | (mask==cv.GC_PR_FGD), 255, 0).astype('uint8')
# 或者
mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
img = img * mask2[:, :, np.newaxis]
其中,mask 是 cv.grabCut() 函数执行后得到的掩膜,mask2 是提取的前景区域的二值图像。
import numpy as np
import cv2 as cv
# 读取图像
img = cv.imread('pic1.jpg')
mask = np.zeros(img.shape[:2], np.uint8)
bgdModel = np.zeros((1, 65), np.float64)
fgdModel = np.zeros((1, 65), np.float64)
rect = (400, 175, 450, 675)
cv.grabCut(img, mask, rect, bgdModel, fgdModel, 10, cv.GC_INIT_WITH_RECT)
mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
img = img * mask2[:, :, np.newaxis]
# 显示结果
cv.imwrite('pic.jpg', img)
cv.waitKey(0)
cv.destroyAllWindows()