Ask Your Question
2

How to remove black background from grabcut output image in OpenCV android ?

asked 2013-11-24 12:09:27 -0600

Dexter gravatar image

updated 2015-10-02 10:31:36 -0600

image description

Hi, I am using OpenCV android library grabcut() method to extract an image from background, but the problem is that the output bitmap contains black background which I do not want please note that original image does not have any black background it is actually white and I am able to successfully extract the fish image from that but the output contains this kind of black background. I am attaching the code for your reference, I am new to opencv and don't have much understanding about it and grabcut algorithm also so kindly help me out.

public class Grabcut extends Activity {
    ImageView iv;
    Bitmap bitmap;
    Canvas canvas;
    Scalar color = new Scalar(255, 0, 0, 255);
    Point tl, br;
    int counter;
    Bitmap bitmapResult, bitmapBackground;
    Mat dst = new Mat();
    final String pathToImage  = Environment.getExternalStorageDirectory()+"/gcut.png";
    public static final String TAG = "Grabcut demo";
    static {
          if (!OpenCVLoader.initDebug()) {
            // Handle initialization error
          }
        }
    @Override
    public void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);
        setContentView(R.layout.grabcut_main);
        iv = (ImageView) this.findViewById(R.id.imageView);


        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.grabcut);
        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/5, r/5);
        Point p2 = new Point(c-c/5, r-r/8);

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

        Mat mask = new Mat();
        debugger(""+mask.type());
        mask.setTo(new Scalar(125));
        Mat fgdModel = new Mat();
        fgdModel.setTo(new Scalar(255, 255, 255));
        Mat bgdModel = new Mat();
        bgdModel.setTo(new Scalar(255, 255, 255));

        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, 5, Imgproc.GC_INIT_WITH_RECT);

        Mat source = new Mat(1, 1, CvType.CV_8U, new Scalar(3.0));


        Core.compare(mask, source, mask, Core.CMP_EQ);
        Mat foreground = new Mat(img.size(), CvType.CV_8UC3, new Scalar(255, 255, 255));
        img.copyTo(foreground, mask);
        Core.rectangle(img, p1, p2, color);

        Mat background = new Mat();
        try {
            background = Utils.loadResource(getApplicationContext(),
                    R.drawable.wall2 );
        } catch (IOException e) {

            e.printStackTrace();
        }
        Mat tmp = new Mat();
        Imgproc.resize(background, tmp, img.size());

        background = tmp;

        Mat tempMask = new Mat(foreground.size(), CvType.CV_8UC1, new Scalar(255, 255, 255));
        Imgproc.cvtColor(foreground, tempMask, 6/* COLOR_BGR2GRAY */);
        //Imgproc.threshold(tempMask, tempMask, 254, 255, 1 /* THRESH_BINARY_INV */);

        Mat vals = new Mat(1, 1, CvType.CV_8UC3, new Scalar(0.0));
        dst = new Mat();
        background.setTo(vals, tempMask);
        Imgproc.resize(foreground, tmp, mask.size());
        foreground = tmp;
        Core.add(background, foreground, dst, tempMask);

        //convert to Bitmap
        Log.d(TAG, "Convert to Bitmap");
        Utils.matToBitmap(dst, bitmap);

        iv.setBackgroundResource(R.drawable.wall2);
        iv.setImageBitmap(bitmap);
        //release MAT part
        img.release();
        imgC3.release();
        mask.release();
        fgdModel.release();
        bgdModel.release();

    }

    public void debugger(String s){
        Log.v("","########### "+s);
    }
}

I have ... (more)

edit retag flag offensive close merge delete

5 answers

Sort by ยป oldest newest most voted
4

answered 2013-11-25 05:01:46 -0600

Haris gravatar image

updated 2013-11-25 05:03:08 -0600

You can easily solve this by reconstruct your image with alpha channel using the following step

  • Convert your source image to Gray scale.
  • Threshold the image to create alpha channel with complete transparency in black background region and zero transparency in foreground object region .
  • Split the original image in to three single channel.
  • Create the final result by merging three single channel and alpha(BGRA order).
  • Use the newly created image above your wall image.

And here is the C++ code for the above steps, re-write in Java as your need.

Mat src=imread("0.jpg",1);
Mat dst;//(src.rows,src.cols,CV_8UC4);
Mat tmp,alpha;

cvtColor(src,tmp,CV_BGR2GRAY);
threshold(tmp,alpha,100,255,THRESH_BINARY);

Mat rgb[3];
split(src,rgb);

Mat rgba[4]={rgb[0],rgb[1],rgb[2],alpha};
merge(rgba,4,dst);
imwrite("dst.png",dst);

Source Image without alpha.

image description

Result with alpha

image description

edit flag offensive delete link more

Comments

1

Nice answer. You really put some effort into it.

StevenPuttemans gravatar imageStevenPuttemans ( 2013-11-25 06:15:41 -0600 )edit
1

Thank you...

Haris gravatar imageHaris ( 2013-11-25 07:07:59 -0600 )edit
2

Thanks a lot Haris, I am really grateful to you.

Dexter gravatar imageDexter ( 2013-11-30 09:36:54 -0600 )edit
2

You are welcome.

Haris gravatar imageHaris ( 2013-11-30 23:58:32 -0600 )edit
1

Can you give me your java code to remove the block background.Very Thanks

Opencv_lover gravatar imageOpencv_lover ( 2014-04-28 22:18:23 -0600 )edit

Can you give me your java code to remove the block background.Very Thanks

Farrakh Javed gravatar imageFarrakh Javed ( 2014-05-20 06:37:52 -0600 )edit

The code is right there?

StevenPuttemans gravatar imageStevenPuttemans ( 2014-05-20 06:40:28 -0600 )edit

I'm not able to convert to java code for alpha and tmp. Kindly tell me how aplha is populated?

Farrakh Javed gravatar imageFarrakh Javed ( 2014-05-20 07:01:19 -0600 )edit

Please reply as soon as possible. Thanks in advance.

Farrakh Javed gravatar imageFarrakh Javed ( 2014-05-20 07:02:00 -0600 )edit

I think you should start reading on grabcut first ... it seems you do not understand the principles of the algorithm!

StevenPuttemans gravatar imageStevenPuttemans ( 2014-05-20 07:06:11 -0600 )edit

You are right. I'm using opencv4Adnroid library. so i think i am not able to do that.

Farrakh Javed gravatar imageFarrakh Javed ( 2014-05-20 07:31:15 -0600 )edit
3

answered 2014-10-01 18:26:30 -0600

crazymichel1 gravatar image

updated 2014-10-01 22:46:11 -0600

Haris gravatar image

Here is my working java code for Haris answer:

`

 /**

 * Make the black background of a PNG-Bitmap-Image transparent.
 * code based on example at http://j.mp/1uCxOV5
 * @Param image png bitmap image
 * @return output image
 */

private static Bitmap makeBlackTransparent(Bitmap image) {
    // convert image to matrix
    Mat src = new Mat(image.getWidth(), image.getHeight(), CvType.CV_8UC4);
    Utils.bitmapToMat(image, src);

    // init new matrices
    Mat dst = new Mat(image.getWidth(), image.getHeight(), CvType.CV_8UC4);
    Mat tmp = new Mat(image.getWidth(), image.getHeight(), CvType.CV_8UC4);
    Mat alpha = new Mat(image.getWidth(), image.getHeight(), CvType.CV_8UC4);

    // convert image to grayscale
    Imgproc.cvtColor(src, tmp, Imgproc.COLOR_BGR2GRAY);

    // threshold the image to create alpha channel with complete transparency in black background region and zero transparency in foreground object region.
    Imgproc.threshold(tmp, alpha, 100, 255, Imgproc.THRESH_BINARY);

    // split the original image into three single channel.
    List<Mat> rgb = new ArrayList<Mat>(3);
    Core.split(src, rgb);

    // Create the final result by merging three single channel and alpha(BGRA order)
    List<Mat> rgba = new ArrayList<Mat>(4);
    rgba.add(rgb.get(0));
    rgba.add(rgb.get(1));
    rgba.add(rgb.get(2));
    rgba.add(alpha);
    Core.merge(rgba, dst);

    // convert matrix to output bitmap
    Bitmap output = Bitmap.createBitmap(image.getWidth(), image.getHeight(), Bitmap.Config.ARGB_8888);
    Utils.matToBitmap(dst, output);
    return output;
}`
edit flag offensive delete link more
0

answered 2018-04-28 07:39:21 -0600

14051598-023 gravatar image

Why colors in output image are changed. I have used image of orange(fruit) and after applying this code of grabcut that orange(fruit)'s color has been changed into intense yellowImage I used is this .And output that I get is thisimage description

edit flag offensive delete link more
0

answered 2018-01-26 01:41:26 -0600

Use it. After using grabcut, the result background is transparent.

public Bitmap removeBackground(Bitmap bitmap) {
    //GrabCut part
    Mat img = new Mat();
    Utils.bitmapToMat(bitmap, img);

    int r = img.rows();
    int c = img.cols();
    Point p1 = new Point(c / 100, r / 100);
    Point p2 = new Point(c - c / 100, r - r / 100);
    Rect rect = new Rect(p1, p2);

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

    Mat imgC3 = new Mat();
    Imgproc.cvtColor(img, imgC3, Imgproc.COLOR_RGBA2RGB);

    Imgproc.grabCut(imgC3, mask, rect, bgdModel, fgdModel, 5, Imgproc.
            GC_INIT_WITH_RECT);

    Mat source = new Mat(1, 1, CvType.CV_8U, new Scalar(3.0));
    Core.compare(mask, source/* GC_PR_FGD */, mask, Core.CMP_EQ);

    //This is important. You must use Scalar(255,255, 255,255), not Scalar(255,255,255)
    Mat foreground = new Mat(img.size(), CvType.CV_8UC3, new Scalar(255,
            255, 255,255));
    img.copyTo(foreground, mask);

    // convert matrix to output bitmap
    bitmap = Bitmap.createBitmap((int) foreground.size().width,
            (int) foreground.size().height,
            Bitmap.Config.ARGB_8888);
    Utils.matToBitmap(foreground, bitmap);
    return bitmap;
}
edit flag offensive delete link more
-1

answered 2013-12-09 00:20:22 -0600

Joystna gravatar image

updated 2013-12-09 00:21:53 -0600

Hello Mr Haris,

can i get your help for my grabcut project.

please email me on [email protected]

Thank you

edit flag offensive delete link more

Comments

2

Better to post your problem here then every one can help you.

Haris gravatar imageHaris ( 2013-12-09 03:45:52 -0600 )edit

what would be the reason if this code still dont work ?

NomiYaqoob gravatar imageNomiYaqoob ( 2017-02-21 12:12:32 -0600 )edit

I am using an image over javacameraview

NomiYaqoob gravatar imageNomiYaqoob ( 2017-02-21 12:13:22 -0600 )edit

Question Tools

Stats

Asked: 2013-11-24 12:09:27 -0600

Seen: 33,630 times

Last updated: Oct 01 '14