Ask Your Question

How To use OpenCv(2.4.5) GrabCut

asked 2013-07-03 00:20:08 -0500

Opencv_lover gravatar image

updated 2013-07-03 02:46:57 -0500

Hello Everyone,

Here is my code using the OpenCv method GrabCut, but there is a problem. The input image is a color image, but through Grabcut, the result image is a grey level image.

The code as follows:

    Long startTime = System.currentTimeMillis();

    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.p4);
    Log.d(TAG, "bitmap: " + bitmap.getWidth() + "x" + bitmap.getHeight());

    bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
    Log.d(TAG, "bitmap 8888: " + bitmap.getWidth() + "x" + bitmap.getHeight());

    //GrabCut part
    Mat img = new Mat();
    Utils.bitmapToMat(bitmap, img);
    Log.d(TAG, "img: " + img);

    int r = img.rows();
    int c = img.cols();

    Point p1 = new Point(c/10, r/10);
    Point p2 = new Point(c-c/10, r-r/10);
    Rect rect = new Rect(p1,p2);
    //Rect rect = new Rect(50,30, 100,200);
    Log.d(TAG, "rect: " + rect);

    Mat mask = new Mat();
    Mat fgdModel = new Mat();
    Mat bgdModel = new Mat();

    Mat imgC3 = new Mat();  
    Imgproc.cvtColor(img, imgC3, Imgproc.COLOR_RGBA2RGB);
    Log.d(TAG, "imgC3: " + imgC3);

    Log.d(TAG, "Grabcut begins");
    Imgproc.grabCut(imgC3, mask, rect, bgdModel, fgdModel, 2, Imgproc.GC_INIT_WITH_RECT);

    Core.convertScaleAbs(mask, mask, 100, 0);
    Imgproc.cvtColor(mask, mask, Imgproc.COLOR_GRAY2RGBA,4);
    Log.d(TAG, "maskC4: " + mask);

    //convert to Bitmap
    Log.d(TAG, "Convert to Bitmap");

    Utils.matToBitmap(mask, bitmap);

    Long endTime = System.currentTimeMillis();
    Long time=endTime-startTime;
    System.out.println("Time Is:"+time);
    //release MAT part
edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted

answered 2013-07-03 09:13:37 -0500

elmiguelao gravatar image

Grabcut output is the mask, not a complete segmented multichannel image.

What you need to do is convert the output mask into the alpha channel of your image; for this, best use "Split" on the input RGBA to separate the channels, discard the input A channel, and "Merge" back into the output RGBA the RGB channels from the input with the mask from Grabcut.

Or, if you want the mask applied to your input image, "Split" the channels like before, then Multiply each input RGB channel with the mask, and "Merge" then back like before.

As a side note, openCV GrabCut implementation for square foreground seeds works best if the rectangle is larger than the object to segment. Otherwise you might see an empty output mask...

edit flag offensive delete link more

answered 2013-07-03 02:54:27 -0500

Excuse me for giving examples in C++ code, but Java is by far a harder programming language for me. However, same functionality is available there.

Some suggestions you can try out:

  • Try initiating your Mat element with the correct structure by initializing the correct rows, colums and type. This will make sure you actually create the corresponding 3 color layers before copying data. This would result in something like this:

    Mat img = new Mat(bmp.rows, bmp.cols, CV_8UC3);

  • Do the same for every Mat element you are creating.

  • Are you sure that the Mat has the RGBA structure after BMP conversion? If so, you will even need 4 layers.

edit flag offensive delete link more

Question Tools


Asked: 2013-07-03 00:20:08 -0500

Seen: 3,998 times

Last updated: Jul 03 '13