Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV - GrabCut with custom foreground/background models

I want to use the GrabCut algorithm implemented on OpenCV.

As shown in the documentation this is the function signature:

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

The mode param, indicates how to initialize the algorithm, either with the rect (a rectangle bounding box) or with the mask (a matrix whose values correspond to user paintings of the foreground/background regions.

I already have the color models for both the FG and the BG, so ideally I shouldn’t need to provide a mask or a rectangle, but use those models as an initialization (I want to prevent OpenCV to compute new models and use mine instead). I see that bgdModel and fgdModel parameters somehow contain this model information. Unfortunatelly, the documentation does not provide any details on how the model information is stored there.

Is it possible to populate those models whith existing data and run the method with mode=GC_EVAL?, if so, how do I need to encode the models?

like image 651
ButterDog Avatar asked Oct 01 '22 18:10

ButterDog


1 Answers

In opencv/sources/modules/imgproc/src/grabcut.cpp you can have a look how the models (GMMs) are encoded:

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 );
}

So you need for every model a cv::Mat of 1 x 65 doubles (componentsCount equals 5). There are 3 means per component because its computing in RGB colorspace. Using GC_EVAL would indeed leave the models intact but I never tried it with pre-computed models.

like image 141
RevJohn Avatar answered Oct 27 '22 20:10

RevJohn