Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Grabcut mask values

The documentation for GrabCut says this about the mask parameter:

@param mask Input/output 8-bit single-channel mask. The mask is initialized by the function when mode is set to GC_INIT_WITH_RECT. Its elements may have one of the cv::GrabCutClasses.

The first time I invoke grabCut it runs successfully and the mask is initialised. But the second time I do it, using the mask and mode == GC_INIT_WITH_MASK, I get the following error:

OpenCV Error: Bad argument (mask element value must be equal GC_BGD or GC_FGD or GC_PR_BGD or GC_PR_FGD) in checkMask, file /Volumes/build-storage/build/master_iOS-mac/opencv/modules/imgproc/src/grabcut.cpp, line 337

The values in the mask matrix are either 0 or 255, when I was expecting 0-3. Does this make sense? I am doing anything wrong?

Grabcut mask values

The documentation for GrabCut says this about the mask parameter:

@param mask Input/output 8-bit single-channel mask. The mask is initialized by the function when mode is set to GC_INIT_WITH_RECT. Its elements may have one of the cv::GrabCutClasses.

The first time I invoke grabCut it runs successfully and the mask is initialised. But the second time I do it, using the mask and mode == GC_INIT_WITH_MASK, I get the following error:

OpenCV Error: Bad argument (mask element value must be equal GC_BGD or GC_FGD or GC_PR_BGD or GC_PR_FGD) in checkMask, file /Volumes/build-storage/build/master_iOS-mac/opencv/modules/imgproc/src/grabcut.cpp, line 337

The values in the mask matrix are either 0 or 255, when I was expecting 0-3. Does this make sense? I am doing anything wrong?

Update: I am using version 3.2.0 for the iPhone. The crash does not happen if I replace pixels with 255 with 1 (GC_FGD), but then all I get is a completely transparent image.

Here is my main code block, in Objective C. Some ivar and properties (i.e., _mask and self.mask are the same thing.

- (UIImage *)processImage {
    if (!self.firstRun) {
        for( int y = 0; y < _mask.rows; y++ ) {
            for( int x = 0; x < _mask.cols; x++ ) {
                uchar val = _mask.at<uchar>(y,x);
                if (val == 255) {
                    _mask.at<uchar>(y,x) = GC_FGD;
                }
            }
        }
        for (NSValue *r in self.foregroundPoints) {
            rectangle(_mask, cvRectFromCGRect(r.CGRectValue), GC_FGD);
        }
        for (NSValue *r in self.backgroundPoints) {
            rectangle(_mask, cvRectFromCGRect(r.CGRectValue), GC_BGD);
        }
    }

    grabCut(_inputImageMat,
            _mask,
            cvRectFromCGRect(_rect),
            _bgModel,
            _fgModel,
            1, // number of iterations
            _firstRun ? cv::GC_INIT_WITH_RECT : cv::GC_INIT_WITH_MASK);

    self.firstRun = false;

    Mat image = self.inputImageMat.clone();

    // Get the pixels marked as likely foreground
    cv::compare(self.mask, cv::GC_PR_FGD, self.mask, cv::CMP_EQ);
    // Generate output image
    cv::Mat foreground(image.size(), CV_8UC3, cv::Scalar(255, 0, 255));
    image.copyTo(foreground, self.mask); // bg pixels not copied

    // image has magenta on transparent sections. replace before using
    return [UIImage imageWithCVMat:foreground];
}