简体   繁体   English

从OpenCV(C ++)中的PNG文件读取GrabCut遮罩

[英]GrabCut reading mask from PNG file in OpenCV (C++)

The implementation of this functionality seems pretty straightforward in Python, as shown here: http://docs.opencv.org/trunk/doc/py_tutorials/py_imgproc/py_grabcut/py_grabcut.html 如下所示,此功能的实现在Python中似乎非常简单: http//docs.opencv.org/trunk/doc/py_tutorials/py_imgproc/py_grabcut/py_grabcut.html

Yet, when I tried to do exactly the same in C++, I get bad arguments error (for the grabcut function). 但是,当我尝试在C ++中执行完全相同的操作时,我得到了错误的参数错误(对于grabcut函数)。 How to put the mask image in the right format? 如何以正确的格式放置蒙版图像?
I am a newbie at this, so I'd be very thankful if someone could help me understand better. 我是新手,如果有人可以帮助我更好地理解我,我将非常感激。 Thank you! 谢谢! Here's what I have so far: 这是我到目前为止的内容:

    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;

} }

It looks like you have misunderstood the guide, repeated here from the linked guide in the question: 您似乎误解了该指南,以下是链接的指南中有关问题的重复说明:

   # 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()

this is not what you have done i'm afraid. 恐怕这不是您所做的。 For a start you seem to have set the mask to the rgb image: 首先,您似乎已将遮罩设置为rgb图像:

   mask = imread("messi5.png");  

whereas is should be set to the mask image: 而应将其设置为蒙版图像:

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

EDIT from comments: 编辑评论:

from a pure red mask painted over the image (an actual mask would be better). 画在图像上的纯红色蒙版(实际蒙版会更好)。

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

now threshold on the red channel to get your binary mask. 现在在红色通道上设置阈值以获取二进制掩码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM