OpenCV  4.10.0
开源计算机视觉
加载中...
搜索中...
没有匹配项
使用 GrabCut 算法进行前景提取

目标

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

理论

GrabCut 算法是由英国剑桥微软研究院的 Carsten Rother、Vladimir Kolmogorov 和 Andrew Blake 在其论文中设计的,“GrabCut”:使用迭代图剪切进行交互式前景提取。GrabCu">交互使用迭代图剪切进行前景提取。需要一种算法来以最少的用户交互进行前景提取,而 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 中的一个

尝试一下