I have a DIY home photo studio to take photos. I want them to be on pure white background (#FFFFFF) with minimum user interaction
This is original picture i have (no any processing, just raw JPG from camera)
I implement simple python program with opencv and Tkinter for UI
1) Get rect with object (ROI)
I decide to select ROI with UI, maybe later i will write code to automatically recognize object on the photo.
2) With cv2.grabCut function i try to cut background from this rect
cv2.grabCut(image, self.mask, rect, bgdmodel, fgdmodel, 5, cv2.GC_INIT_WITH_RECT)
3) If necessary i create custom mask for grabcut which can provide more accuracy object extraction
cv2.grabCut(image, self.mask, rect, bgdmodel, fgdmodel, 5, cv2.GC_INIT_WITH_MASK)
4) After this step i can create mask where my object is located. I also resize mask by 30px
mask = cv2.resize(mask, ( crop_img.shape[1] + 30, crop_img.shape[0] + 30))
mask = mask[30 : crop_img.shape[0], 30 : crop_img.shape[1]]
so this mask have more width and height
5) I use this mask for seamlessClone method
src_bg = 255 * np.ones(self.src.shape, self.src.dtype)
width, height, channels = src_bg.shape
center = (int(height / 2), int((width / 2)))
output = cv2.seamlessClone(crop_img, src_bg, mask, center, cv2.MIXED_CLONE)
Looks good except some artifacts on the right side of object. It seems like my mask isnt fit good. This is not a real problem. Real problem is: seamlessClone give me not really white background. Take a look at levels:
Some strange gradients and background isn't really white on bottom right corner. I try with many images and there is often such things.
My question is: what is a proper way to do what i want? Is my approach can used for this task and how to make really white (#FFFFFF) background without such gradients. Thanks