Retrieving a Background Image Using GrabCut

I have an image (.jpg image) and I want to extract the background from the original image. I googled a lot, but only found tutorials on extracting foreground images.

I took the code from another question https://stackoverflow.com/a/318618/ The code works fine for me, and I have successfully extracted the foreground (according to my requirements). Now I want to completely remove this foreground from the original image. I want it to be something like this: -

Background = Original Image - Foreground

White space can be filled in black or white. How can i achieve this?

I tried using this technique: -

Mat background = image2 - foreground; 

but he gives a complete black image.

The code: -

 #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main( ) { // Open another image Mat image; image= cv::imread("images/abc.jpg"); Mat image2 = image.clone(); // define bounding rectangle cv::Rect rectangle(40,90,image.cols-80,image.rows-170); 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 cout << "oks pa dito" <<endl; // 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)); //cv::Mat background(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); imwrite("img_1.jpg",image); imwrite("Foreground.jpg",foreground); Mat background = image2 - foreground; imwrite("Background.jpg",background); return 0; } 

Note. I am a beginner novice and do not know about it now. I will be very grateful if you can publish the full code (as I need) or simply place the lines of code and tell me where these lines of code will be placed. Thanks.

PS This is my second question at StackOverflow.com. apologies ... if you do not follow any agreement.

+7
c ++ opencv
source share
4 answers

Instead of copying all the pixels in the foreground, it copies all the pixels that are not foreground. You can do this using ~ , which negates the mask:

 image.copyTo(background,~result); 
+12
source share

What if you //Get the pixels marked as likely background :

 // Get the pixels marked as likely background cv::compare(result,cv::GC_PR_BGD,result,cv::CMP_EQ); 

Change There are no GC_BGD pixels in the above code. Despite a more effective answer, let me know where we started:

 // Get the pixels marked as background cv::compare(result,cv::GC_BGD,result_a,cv::CMP_EQ); // Get the pixels marked as likely background cv::compare(result,cv::GC_PR_BGD,result_b,cv::CMP_EQ); // Final results result=result_a+result_b; 
+3
source share

Just a small sentence @William answer can be written more succinctly:

 result = result & 1; 

to get the binary mask.

0
source share

Maybe another example helps, in which I suggested that the middle part of the image definitely stands in the foreground. So try this link. enter the link here

0
source share

All Articles