Grabcut outputs only what was marked as GC_FGD
I am using JavaCV version 3.4.2 along with Android SDK 27.
Here is my input image (please forget the cursor):
Here is the mask (only the "lines" remain, the shirt itself is just used as a guide).
Here is the result :(
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;
}