发布于 2019-03-04 08:02:43
计算图解中的数据项是计算t-链.它显示在grabcut.cpp源代码的第465行的源代码中,特别是在constructGCGraph函数:https://github.com/opencv/opencv/blob/master/modules/imgproc/src/grabcut.cpp#L465中。注意,函数的声明是static void,这意味着它是私有的,在cv工作区之外是不可见的。这意味着,除非您黑入源代码本身,否则您无法在源代码中调用它。
换言之:
// set t-weights
double fromSource, toSink;
if( mask.at<uchar>(p) == GC_PR_BGD || mask.at<uchar>(p) == GC_PR_FGD )
{
fromSource = -log( bgdGMM(color) );
toSink = -log( fgdGMM(color) );
}
else if( mask.at<uchar>(p) == GC_BGD )
{
fromSource = 0;
toSink = lambda;
}
else // GC_FGD
{
fromSource = lambda;
toSink = 0;
}
graph.addTermWeights( vtxIdx, fromSource, toSink );“源”和“汇”的术语来自图切分算法,其中“源”表示前景像素,“接收器”表示背景像素。还要注意,有四种类型的标签。这些都是在一个名为enum的cv::GrabCutClasses中定义的(您可以在这里找到它们:misc.html#gad43d3e4208d3cf025d8304156b02ba38)。
具体地说:
GC_BGD:一个明显的背景像素GC_FGD:一个明显的前景(对象)像素GC_PR_BGD:可能的背景像素GC_PR_FGD:可能的前景像素GC_BGD和GC_FGD是用来描绘图像的前景和背景笔画的像素。这些是您指定的内容。因此,对于GC_PR_BGD和GC_PR_FGD,我们依赖于为前景和背景构建GMM,并计算负日志概率。这背后的本质是,如果颜色确实属于前景,我们指定一个低成本的连接到接收器节点,使它更有吸引力的削减这一链接,以保持源节点完整,从而将其归类为前景像素。您也可以对源节点和背景进行类似的操作。对于那些我们肯定知道它们是前景还是背景的像素,我们将一个高成本的lambda应用到表示所需标签的链接上,这样相反的链接就会被切断,从而为像素保留所需的标签。例如,如果我们知道一个像素是背景,我们就确保t链接到源节点的成本为零,这样我们就可以在不产生任何影响的情况下切断这个链接,从而确保像素被分配到背景中。
要“更新”数据术语,可以通过在图像中指定更多的前景和背景笔画来更好地描述要分割的对象。没有其他方法可以做到这一点,除非你自己黑客源。
作为最后的说明,我建议阅读这个关于图形切割算法如何工作的摘要:基于最大流的图像分割。它为GrabCut的源代码提供了更多的视角。毕竟,GrabCut只是一个图形割集的高级抽象。
https://stackoverflow.com/questions/54977167
复制相似问题