OpenCV 4.12.0
开源计算机视觉
加载中...
搜索中...
无匹配项
使用GrabCut算法提取前景

目标

  • 我们将学习 GrabCut 算法以提取图像中的前景

理论

GrabCut 算法由英国剑桥微软研究院的 Carsten Rother、Vladimir Kolmogorov 和 Andrew Blake 在他们的论文 "GrabCut": interactive foreground extraction using iterated graph cuts 中设计。需要一种以最少用户交互进行前景提取的算法,GrabCut 就是成果。

从用户的角度来看,它是如何工作的?最初,用户在前景区域周围绘制一个矩形(前景区域应完全位于矩形内部)。然后,算法迭代地分割它以获得最佳结果。完成。但在某些情况下,分割可能不太好,例如,它可能将某些前景区域标记为背景,反之亦然。在这种情况下,用户需要进行细微的调整。只需在存在错误结果的图像上进行一些笔划。笔划基本上表示“嘿,这个区域应该是前景,你把它标记为背景,在下一次迭代中纠正它”,或者它的背景相反。然后在下一次迭代中,您会获得更好的结果。

背景发生了什么?

  • 用户输入矩形。此矩形之外的所有内容都将被视为确定的背景(这就是之前提到您的矩形应包含所有对象的原因)。矩形内的所有内容都是未知的。类似地,任何指定前景和背景的用户输入都被认为是硬标签,这意味着它们不会在过程中改变。
  • 计算机根据我们提供的数据进行初始标记。它标记前景和背景像素(或者说是硬标签)
  • 现在,使用高斯混合模型 (GMM) 来建模前景和背景。
  • 根据我们提供的数据,GMM 学习并创建新的像素分布。也就是说,未知像素被标记为可能的背景或可能的前景,这取决于它与其他硬标签像素在颜色统计方面的关系(就像聚类一样)。
  • 从该像素分布构建一个图。图中的节点是像素。添加了另外两个节点,源节点汇节点。每个前景像素都连接到源节点,每个背景像素都连接到汇节点。
  • 将像素连接到源节点/尾节点的边的权重由像素作为前景/背景的概率定义。像素之间的权重由边缘信息或像素相似度定义。如果像素颜色差异很大,则它们之间的边的权重将较低。
  • 然后使用最小割算法来分割图。它将图切割成两个分离的源节点和汇节点,并具有最小的成本函数。成本函数是被切割边的所有权重的总和。切割后,连接到源节点的所有像素都变为前景,而连接到汇节点的像素变为背景。
  • 该过程一直持续到分类收敛。

如下图所示(图片来源:http://www.cs.ru.ac.za/research/g02m1682/

image

演示

我们使用函数:cv.grabCut (image, mask, rect, bgdModel, fgdModel, iterCount, mode = cv.GC_EVAL)

参数
image输入 8 位 3 通道图像。
mask输入/输出 8 位单通道掩码。当模式设置为 GC_INIT_WITH_RECT 时,该掩码由函数初始化。它的元素可能具有 cv.grabCutClasses 之一。
rect包含分割对象的 ROI。 ROI 外部的像素被标记为“明显的背景”。该参数仅在 mode==GC_INIT_WITH_RECT 时使用。
bgdModel背景模型的临时数组。在您处理同一图像时,请勿修改它。
fgdModel前景模型的临时数组。在您处理同一图像时,请勿修改它。
iterCount算法在返回结果之前应进行的迭代次数。请注意,可以使用 mode==GC_INIT_WITH_MASK 或 mode==GC_EVAL 进一步优化结果。
mode可以是 cv::GrabCutModes 之一的操作模式

试试看