OpenCV  4.5.1
Open Source Computer Vision
Foreground Extraction using GrabCut Algorithm

Goal

Theory

GrabCut algorithm was designed by Carsten Rother, Vladimir Kolmogorov & Andrew Blake from Microsoft Research Cambridge, UK. in their paper, "GrabCut": interactive foreground extraction using iterated graph cuts . An algorithm was needed for foreground extraction with minimal user interaction, and the result was GrabCut.

How it works from user point of view ? Initially user draws a rectangle around the foreground region (foreground region should be completely inside the rectangle). Then algorithm segments it iteratively to get the best result. Done. But in some cases, the segmentation won't be fine, like, it may have marked some foreground region as background and vice versa. In that case, user need to do fine touch-ups. Just give some strokes on the images where some faulty results are there. Strokes basically says *"Hey, this region should be foreground, you marked it background, correct it in next iteration"* or its opposite for background. Then in the next iteration, you get better results.

What happens in background ?

It is illustrated in below image (Image Courtesy: http://www.cs.ru.ac.za/research/g02m1682/)

grabcut_scheme.jpg
image

Demo

We use the function: cv.grabCut (image, mask, rect, bgdModel, fgdModel, iterCount, mode = cv.GC_EVAL)

Parameters
imageinput 8-bit 3-channel image.
maskinput/output 8-bit single-channel mask. The mask is initialized by the function when mode is set to GC_INIT_WITH_RECT. Its elements may have one of the cv.grabCutClasses.
rectROI containing a segmented object. The pixels outside of the ROI are marked as "obvious background". The parameter is only used when mode==GC_INIT_WITH_RECT.
bgdModeltemporary array for the background model. Do not modify it while you are processing the same image.
fgdModeltemporary arrays for the foreground model. Do not modify it while you are processing the same image.
iterCountnumber of iterations the algorithm should make before returning the result. Note that the result can be refined with further calls with mode==GC_INIT_WITH_MASK or mode==GC_EVAL .
modeoperation mode that could be one of the cv::GrabCutModes

Try it