GrabCut 中的错误参数(图像必须具有 CV_8UC3 类型)

Posted

技术标签:

【中文标题】GrabCut 中的错误参数(图像必须具有 CV_8UC3 类型)【英文标题】:Bad argument (image must have CV_8UC3 type) in grabCut 【发布时间】:2013-05-08 09:27:04 【问题描述】:

我正在使用grabCut算法,代码如下:

cv::Mat img=[self cvMatFromUIImage:image];

cv::Rect rectangle(10,10,300,150);

cv::Mat result; // segmentation (4 possible values)
cv::Mat bgModel,fgModel; // the models (internally used)
// GrabCut segmentation
cv::grabCut(img,    // input image
            result,      // segmentation result
            rectangle,   // rectangle containing foreground
            bgModel,fgModel, // models
            3,           // number of iterations
            cv::GC_INIT_WITH_RECT); // use rectangle
// Get the pixels marked as likely foreground
cv::compare(result,cv::GC_PR_FGD,result,cv::CMP_EQ);
// Generate output image
cv::Mat foreground(img.size(),CV_8UC3,
                   cv::Scalar(255,255,255));
result=result&1;
img.copyTo(foreground, result);
            result);

image=[self UIImageFromCVMat:foreground];
ImgView.image=image;

UIImage 转换为Mat image 的代码如下所示

- (cv::Mat)cvMatFromUIImage:(UIImage *)imge

    CGColorSpaceRef colorSpace = CGImageGetColorSpace(imge.CGImage);
    CGFloat cols = imge.size.width;
    CGFloat rows = imge.size.height;

    cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels

    CGContextRef contextRef = CGBitmapContextCreate(
                                        cvMat.data,     // Pointer to  data
                                        cols,           // Width of bitmap
                                        rows,           // Height of bitmap
                                        8,              // Bits per component
                                        cvMat.step[0],  // Bytes per row
                                        colorSpace,     // Colorspace
                                        kCGImageAlphaNoneSkipLast |
                                        kCGBitmapByteOrderDefault); 
                                               // Bitmap info flags

    CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), imge.CGImage);
    CGContextRelease(contextRef);
    CGColorSpaceRelease(colorSpace);

    return cvMat;

但我得到了错误

OpenCV 错误:grabCut 中的参数错误(图像必须具有 CV_8UC3 类型)。

如果我改变 cv::Mat cvMat(rows, cols, CV_8UC4); 转至cv::Mat cvMat(rows, cols, CV_8UC3); 然后我得到<Error>: CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 32 bits/pixel; 3-component color space; kCGImageAlphaNoneSkipLast; 342 bytes/row.

我对该怎么做感到困惑。

请帮忙

【问题讨论】:

【参考方案1】:

问题似乎是,你得到的图像有一个 alpha 通道,而 grabcut 需要一个没有 alpha 通道的 rgb 图像。所以你需要摆脱额外的频道。

你可以用这个函数来做这个:

cv::cvtColor(img , img , CV_RGBA2RGB);

【讨论】:

thanx @sietschie ,它有效,解决了错误。但我仍然无法获得所有前景物体。静止的背景图像以半屏显示。我可以从轮廓制作矩形区域吗? 没有看到您的图像就很难做出判断。但当然有可能,GrabCut 无法正确分割您的对象。当然也可以获得轮廓的边界框。但是,如果您想将其用作 GrabCut 的输入,我建议您将其转换为遮罩。这样您就可以利用轮廓提供的更多信息。 在 python 中? 对我来说是 cv::COLOR_RGBA2RGB

以上是关于GrabCut 中的错误参数(图像必须具有 CV_8UC3 类型)的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV实战——基于GrabCut算法的图像分割

32opencv入门GrabCut & FloodFill图像分割

如何在emgu-cv c#中将遮罩设置为GrabCut方法?

OpenCV中的图像处理 —— 霍夫线 / 圈变换 + 图像分割(分水岭算法) + 交互式前景提取(GrabCut算法)

python opencv3 grabcut前景检测

将图像从 CV_64F 转换为 CV_8U