【问题标题】:GrabCut reading mask from PNG file in OpenCV (C++)GrabCut 从 OpenCV 中的 PNG 文件读取掩码(C++)
【发布时间】:2014-07-08 18:43:58
【问题描述】:

此功能在 Python 中的实现似乎非常简单,如下所示:http://docs.opencv.org/trunk/doc/py_tutorials/py_imgproc/py_grabcut/py_grabcut.html

然而,当我尝试在 C++ 中做同样的事情时,我得到了错误的参数错误(对于抓取函数)。如何以正确的格式放置蒙版图像?
我是这方面的新手,所以如果有人能帮助我更好地理解,我将不胜感激。谢谢! 这是我目前所拥有的:

    Mat image;
    image= imread(file);

    Mat mask;
    mask.setTo( GC_BGD );

    mask = imread("messi5.png");    

    Mat image2 = image.clone();

    // define bounding rectangle

    cv::Rect rectangle(startX, startY, width, height);
    cv::Mat result; // segmentation result (4 possible values)
    cv::Mat bgModel,fgModel; // the models (internally used)

    //// GrabCut segmentation that works, but with a rectangle, not with the mask I need
    //cv::grabCut(image,    // input image
    //  result,   // segmentation result
    //  rectangle,// rectangle containing foreground
    //  bgModel,fgModel, // models
    //  1,        // number of iterations
    //  cv::GC_INIT_WITH_RECT); // use rectangle


    grabCut( image, mask, rectangle, bgModel, fgModel, 1, GC_INIT_WITH_MASK);


    cv::compare(mask,cv::GC_PR_FGD,mask,cv::CMP_EQ);
    cv::Mat foreground(image.size(),CV_8UC3,cv::Scalar(255,255,255));
    image.copyTo(foreground,mask); // bg pixels not copied

    namedWindow( "Display window", WINDOW_AUTOSIZE );
    imshow( "Display window", foreground ); 
    waitKey(0); 

    return 0;

}

【问题讨论】:

  • 掩码必须是8bit单通道二进制

标签: c++ opencv image-processing image-segmentation


【解决方案1】:

您似乎误解了该指南,在此从问题中的链接指南中重复:

   # newmask is the mask image I manually labelled
   newmask = cv2.imread('newmask.png',0)

   # whereever it is marked white (sure foreground), change mask=1
   # whereever it is marked black (sure background), change mask=0
   mask[newmask == 0] = 0
   mask[newmask == 255] = 1

   mask, bgdModel, fgdModel = cv2.grabCut(img,mask,None,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_MASK)

   mask = np.where((mask==2)|(mask==0),0,1).astype('uint8')
   img = img*mask[:,:,np.newaxis]
   plt.imshow(img),plt.colorbar(),plt.show()

恐怕这不是你所做的。首先,您似乎已将掩码设置为 rgb 图像:

   mask = imread("messi5.png");  

而 is 应该设置为掩码图像:

   mask = imread("newmask.png",CV_LOAD_IMAGE_GRAYSCALE);  

从 cmets 编辑:

来自涂在图像上的纯红色蒙版(实际蒙版会更好)。

 maskTmp = imread("messi5.png"); 
 std::vector<cv::Mat> channels(3)
 split( messi5, channels);
 cv::Mat maskRed = channels[2];  

现在红色通道上的阈值来获取您的二进制掩码。

【讨论】:

  • 不幸的是,自然图像不太可能有纯红色,如果你想要红色位,你可以手动制作一个在红色位上有涂鸦的蒙版,这就是grabcut的用途。掩码也应该是 0 和 1,而不是 255s。
  • 我正在使用 jQuery 创建蒙版,使用纯红色的画笔。
  • 那么为什么不把它放在它自己的层中,这样你就得到了一个合适的蒙版呢?如果你设置为 255,它无论如何都不会工作。如果红色与否,设置为 1 或 0。就像在示例中 # 无论它被标记为红色(确定前景),更改掩码 = 1 # 无论它被标记为非红色(确定背景),更改掩码 = 0。还有一点就是mask应该是单通道的,你的现在是3通道。
  • 难以置信,我错过了mask.create( image.size(), CV_8UC1); 非常感谢您的帮助。
  • 您现在将掩码作为一个通道,但您的循环正在处理它,就好像它有 3 个通道。
猜你喜欢
  • 2019-05-22
  • 1970-01-01
  • 2014-07-17
  • 2022-01-02
  • 2020-02-01
  • 2020-07-06
  • 2021-05-23
  • 2016-04-05
  • 2015-11-30
相关资源
最近更新 更多