【问题标题】:OpenCV GrabCut MaskOpenCV GrabCut 蒙版
【发布时间】:2017-07-17 05:18:21
【问题描述】:

我已经利用 OpenCV GrabCut 功能来执行图像分割。按照下面的代码查看分割后的图像时,分割是合理/正确的。但是,在查看(尝试使用)分段掩码值时,我得到了一些非常大的数字,而不是人们期望从 cv::GrabCutClasses 枚举中获得的枚举值。

void doGrabCut(){
        Vector2i imgDims = getImageDims();

        //Wite image to OpenCV Mat.
        const Vector4u *rgb = getRGB();
        cv::Mat rgbMat(imgDims.height, imgDims.width, CV_8UC3);
        for (int i = 0; i < imgDims.height; i++) {
            for (int j = 0; j < imgDims.width; j++) {
                int idx = i * imgDims.width + j;
                rgbMat.ptr<cv::Vec3b>(i)[j][2] = rgb[idx].x;
                rgbMat.ptr<cv::Vec3b>(i)[j][1] = rgb[idx].y;
                rgbMat.ptr<cv::Vec3b>(i)[j][0] = rgb[idx].z;
            }
        }

        //Do graph cut.
        cv::Mat res, fgModel, bgModel;
        cv::Rect bb(bb_begin.x, bb_begin.y, bb_end.x - bb_begin.x, bb_end.y - bb_begin.y);
        cv::grabCut(rgbMat, res, bb, bgModel, fgModel, 10, cv::GC_INIT_WITH_RECT);
        cv::compare(res, cv::GC_PR_FGD, res, cv::CMP_EQ);

        //Write mask.
        Vector4u *maskPtr = getMask();//uchar
        for (int i = 0; i < imgDims.height; i++) {
            for (int j = 0; j < imgDims.width; j++) {
                cv::GrabCutClasses classification = res.at<cv::GrabCutClasses>(i, j);
                int idx = i * imgDims.width + j;
                std::cout << classification << std::endl;//Strange numbers here.
                maskPtr[idx].x = (classification == cv::GC_PR_FGD) ? 255 : 0;//This always evaluates to 0.
            }
        }

        cv::Mat foreground(rgbMat.size(), CV_8UC3, cv::Scalar(255, 255, 255));
        rgbMat.copyTo(foreground, res);
        cv::imshow("GC Output", foreground);
}

当分割在质量上正确时,为什么会得到枚举之外的数字?

【问题讨论】:

    标签: c++ opencv computer-vision image-segmentation


    【解决方案1】:

    我怀疑您的//Write mask. 步骤,为什么您要重新迭代res 并将maskPtr 修改为maskPtr[idx].x = (classification == cv::GC_PR_FGD) ? 255 : 0;,基本上您已经有一个单通道二进制图像存储在res 变量中, cv::compare() 返回二值图像

    但是,如果您仍然想通过迭代来调试值,那么您应该使用标准技术来迭代单通道图像:

    for (int i = 0; i < m.rows; i++) {
        for (int j = 0; j < m.cols; j++) {
            uchar classification = res.at<uchar>(i, j);
            std::cout << int(classification) << ", ";
        }
    }
    

    当您迭代单通道垫时,您必须使用 res.at&lt;uchar&gt;(i, j) 而不是 res.at&lt;cv::GrabCutClasses&gt;

    【讨论】:

      猜你喜欢
      • 2012-12-16
      • 1970-01-01
      • 2014-08-29
      • 2011-03-16
      • 2019-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多