John M.
John M.

Reputation: 2712

Removing trivial background using GrabCut

I'm trying to remove relatively trivial background from several images where the background tends to be white. However, the mask generated overlaps the foreground even when it doesn't contain much white. For instance, given the following input:

enter image description here

GrabCut gives:

enter image description here

And here's my code:

img = cv2.imread('test.jpg')

mask = np.zeros(img.shape[:2], np.uint8)

bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,65),np.float64)

height, width, _ = img.shape

rect = (int(width * 0.05), 0, height, int(width * 0.9))

cv2.grabCut(img, mask, rect, bgdModel, fgdModel, 5, cv2.GC_INIT_WITH_RECT)

mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
img = img*mask2[:,:,np.newaxis]

plt.imshow(img),plt.colorbar(),plt.show()

I'm actually trying to imitate Photoshop's Magic Wand, which would easily pick out the white background. Anyone know of a good way using opencv? Is there a way to tweak GrabCut to do similar?

UPDATE: After fixing the rectangle, I'm now getting a mask that leaves a gap:

enter image description here

Upvotes: 1

Views: 299

Answers (1)

Christoph Rackwitz
Christoph Rackwitz

Reputation: 15365

rect = (int(width * 0.05), 0, height, int(width * 0.9))

look closely. you have something proportional to width in 1st and 4th position. that's probably wrong. the elements are (x,y,w,h).

additionally, you base your observation on matplotlib's false color drawing. maybe have it draw true colors.

Upvotes: 1

Related Questions