OpenCV - 带有自定义前景/背景模型的 GrabCut

Xoc*_*zin 5 c++ opencv computer-vision image-segmentation

我想使用在 OpenCV 上实现的 GrabCut 算法。

文档中所示,这是函数签名:

void grabCut(
    InputArray img, 
    InputOutputArray mask, 
    Rect rect, 
    InputOutputArray bgdModel, // *
    InputOutputArray fgdModel, // *
    int iterCount, 
    int mode=GC_EVAL) 
Run Code Online (Sandbox Code Playgroud)

模式PARAM,指示如何初始化该算法,或者与矩形(矩形边界框),或与所述掩模(一个矩阵,它的值对应于前景/背景区域的用户绘画。

我已经有了 FG 和 BG 的颜色模型,所以理想情况下我不需要提供遮罩或矩形,而是使用这些模型作为初始化(我想阻止 OpenCV 计算新模型并使用我的模型代替) )。我看到bgdModelfgdModel参数以某种方式包含此模型信息。不幸的是,该文档没有提供有关如何在其中存储模型信息的任何详细信息。

是否可以使用现有数据填充这些模型并使用 运行该方法 mode=GC_EVAL,如果是这样,我需要如何对模型进行编码?

Rev*_*ohn 3

在 opencv/sources/modules/imgproc/src/grabcut.cpp 中,您可以查看模型(GMM)是如何编码的:

GMM::GMM( Mat& _model )
{
    const int modelSize = 3/*mean*/ + 9/*covariance*/ + 1/*component weight*/;
    if( _model.empty() )
    {
        _model.create( 1, modelSize*componentsCount, CV_64FC1 );
        _model.setTo(Scalar(0));
    }
    else if( (_model.type() != CV_64FC1) || (_model.rows != 1) || (_model.cols != modelSize*componentsCount) )
        CV_Error( CV_StsBadArg, "_model must have CV_64FC1 type, rows == 1 and cols == 13*componentsCount" );

    model = _model;

    coefs = model.ptr<double>(0);
    mean = coefs + componentsCount;
    cov = mean + 3*componentsCount;

    for( int ci = 0; ci < componentsCount; ci++ )
        if( coefs[ci] > 0 )
             calcInverseCovAndDeterm( ci );
}
Run Code Online (Sandbox Code Playgroud)

因此,每个模型都需要一个 1 x 65 双精度的 cv::Mat(componentsCount 等于 5)。每个分量有 3 个均值,因为它是在 RGB 色彩空间中计算的。使用 GC_EVAL 确实会使模型保持完整,但我从未尝试过使用预先计算的模型。