Grabcut outputs only what was marked as GC_FGD

asked 2019-11-06 03:13:01 -0600

updated 2020-10-05 23:21:20 -0600

I am using JavaCV version 3.4.2 along with Android SDK 27.

Here is my input image (please forget the cursor): image description

Here is the mask (only the "lines" remain, the shirt itself is just used as a guide).
image description

Here is the result :(

image description

The code that runs grabcut:

Mat mask = imageView.mask;

// Create ROI
Rect bounding_box = new Rect(0, 0, mask.cols(), mask.rows());

// extracted features for foreground & bg
Mat bgdModel = new Mat();
Mat fgdModel = new Mat();

// Get original image and convert from RGBA to RGB
Mat original_image = new Mat();
Utils.bitmapToMat(imageView.original_bitmap, original_image);
Imgproc.cvtColor(original_image, original_image, Imgproc.COLOR_RGBA2RGB);

// Do extraction
Imgproc.grabCut(original_image, mask, bounding_box, bgdModel, fgdModel,
        /*iterCount:*/1, Imgproc.GC_INIT_WITH_MASK);

Mat foreground = new Mat(original_image.size(), CvType.CV_8UC1,
        new Scalar(0, 0, 0));
Bitmap output_image = Bitmap.createBitmap(mask.cols(), mask.rows(),
        Bitmap.Config.ARGB_8888);
Mat source = new Mat(1, 1, CvType.CV_8U, new Scalar(0));

original_image.copyTo(foreground, mask);
Utils.matToBitmap(foreground, output_image);

Here is the code that crates the mask:

mask = new Mat (bmp.getHeight(), bmp.getWidth(), CvType.CV_8U, new Scalar(0)); // I am thinking that the issue
                                                                                                                              // lies here. It is assuming all black
                                                                                                                              // is DEF bg. Idk how to circumvent
                                                                                                                              // this.
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        int action = event.getAction();
        byte[] buffer = new byte[3];
        switch (action)
        {
            case MotionEvent.ACTION_DOWN:
                downx = getPointerCoords(event)[0];//event.getX();
                downy = getPointerCoords(event)[1];//event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                upx = getPointerCoords(event)[0];//event.getX();
                upy = getPointerCoords(event)[1];//event.getY();
                canvas.drawLine(downx, downy, upx, upy, paint);
                Imgproc.line(mask, new Point(downx, downy), new Point(upx, upy),
                        new Scalar(
                                paint.getColor() == Color.parseColor("#1de9b6") ?
                                        (byte)Imgproc.GC_FGD : (byte)Imgproc.GC_BGD
                        ), 10);
                invalidate();
                downx = upx;
                downy = upy;
                break;
            case MotionEvent.ACTION_UP:
                upx = getPointerCoords(event)[0];//event.getX();
                upy = getPointerCoords(event)[1];//event.getY();
                canvas.drawLine(downx, downy, upx, upy, paint);
                Imgproc.line(mask, new Point(downx, downy), new Point(upx, upy),
                        new Scalar(
                                paint.getColor() == Color.parseColor("#1de9b6") ?
                                (byte)Imgproc.GC_FGD : (byte)Imgproc.GC_BGD
                        ), 10);
                invalidate();
                break;
            case MotionEvent.ACTION_CANCEL:
                break;
            default:
                break;
        }
edit retag flag offensive close merge delete