title: Python OpenCV pure white background
body: <p>I have a DIY home photo studio to take photos. I want them to be on pure white background (#FFFFFF) with minimum user interaction</p>
  
  <p>This is original picture i have (no any processing, just raw JPG from camera)
  <a href="https://i.stack.imgur.com/16nH2.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/16nH2.jpg" alt="original image"></a></p>
  
  <p>I implement simple python program with opencv and Tkinter for UI</p>
  
  <p><strong>1) Get rect with object (ROI)</strong></p>
  
  <p>I decide to select ROI with UI, maybe later i will write code to automatically recognize object on the photo.</p>
  
  <p><a href="https://i.stack.imgur.com/vXi70.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/vXi70.jpg" alt="select ROI"></a></p>
  
  <p><strong>2) With cv2.grabCut function i try to cut background from this rect</strong></p>
  
  <p><a href="https://i.stack.imgur.com/33DxM.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/33DxM.jpg" alt="grab cut with rect"></a></p>
  
  <pre><code>cv2.grabCut(image, self.mask, rect, bgdmodel, fgdmodel, 5, cv2.GC_INIT_WITH_RECT)
  </code></pre>
  
  <p><strong>3) If necessary i create custom mask for grabcut which can provide more accuracy object extraction</strong></p>
  
  <p><a href="https://i.stack.imgur.com/Fud0w.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/Fud0w.jpg" alt="grab cut with mask"></a></p>
  
  <pre><code>cv2.grabCut(image, self.mask, rect, bgdmodel, fgdmodel, 5, cv2.GC_INIT_WITH_MASK)
  </code></pre>
  
  <p><strong>4) After this step i can create mask where my object is located. I also resize mask by 30px</strong></p>
  
  <pre><code>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]]
  </code></pre>
  
  <p>so this mask have more width and height</p>
  
  <p><a href="https://i.stack.imgur.com/q8acu.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/q8acu.jpg" alt="object mask"></a></p>
  
  <p><strong>5) I use this mask for seamlessClone method</strong></p>
  
  <pre><code>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)
  </code></pre>
  
  <p>And get such result:
  <a href="https://i.stack.imgur.com/AxLVq.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/AxLVq.jpg" alt="output"></a></p>
  
  <p>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:</p>
  
  <p><a href="https://i.stack.imgur.com/Kq19c.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/Kq19c.jpg" alt="levels"></a></p>
  
  <p>Some strange gradients and background isn't really white on bottom right corner. I try with many images and there is often such things.</p>
  
  <p>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</p>