OpenCV 4.11.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/

图像

演示

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

参数
图像输入 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 中的一个。

试一试