Friday, August 02, 2013

Try GrabCut using OpenCV

I was considering using GrabCut to cut out the target in one of my working project. After testing it using Python, I thought it's necessary to try it in C++ code. Therefore I started to find some example code and picked one for my test [1].

Here is my test code, the sample photo, and the result:

#include "opencv2/opencv.hpp"
#include <iostream>

using namespace cv;
using namespace std;

int main( )
{
    // Open another image
    Mat image;
    image = cv::imread("sunflower02.jpg");

    if(! image.data ) // Check for invalid input
    {
        cout <<  "Could not open or find the image" << std::endl ;
        return -1;
    }

    // define bounding rectangle
    int border = 20;
    int border2 = border + border;
    cv::Rect rectangle(border,border,image.cols-border2,image.rows-border2);

    cv::Mat result; // segmentation result (4 possible values)
    cv::Mat bgModel,fgModel; // the models (internally used)

    // GrabCut segmentation
    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
    // Get the pixels marked as likely foreground
    cv::compare(result,cv::GC_PR_FGD,result,cv::CMP_EQ);
    // Generate output image
    cv::Mat foreground(image.size(),CV_8UC3,cv::Scalar(255,255,255));
    image.copyTo(foreground,result); // bg pixels not copied

    // draw rectangle on original image
    cv::rectangle(image, rectangle, cv::Scalar(255,255,255),1);
    cv::namedWindow("Image");
    cv::imshow("Image",image);

    // display result
    cv::namedWindow("Segmented Image");
    cv::imshow("Segmented Image",foreground);


    waitKey();
    return 0;

}

The sample photo used in the test



The result of applying GrabCut

During the test, I encountered an old problem to me, which had been some odd runtime bugs for the debug mode when using OpenCV. The solution might be NOT to mix up the debug and release libraries [2].

Oh, by the way, the processing time of the GrabCut was too long (about 2 seconds in the test case), and I thought it's not feasible for realtime applications. Orz

---
[1] http://stackoverflow.com/questions/15536222/opencv-grabcut-algorithm-example-not-working
[2] http://stackoverflow.com/a/2590795/1024813

1 comment:

  1. Hi , I am using opencv 2.4.10 along with javacv. In the mentioned version compare() expects three Mat objects and a Integer :
    Mat src1 – the first source array.
    Mat src2 – the second source array; must have the same size and same type as src1.
    Mat dst – the destination array; will have the same size as src1 and type CV_8UC1.
    Int cmpop – the flag specifying the relation between the elements to be checked.

    Where as your compare() expects two Mat objects as parameters. Can you please explain what appropriate Mat objects I have to pass to continue.

    Thanks

    ReplyDelete