title: How do I remove the background on this type of images when object color is very similar to the background?
body: <p>I am working on removing the background of <a href="http://i.stack.imgur.com/oYxzi.jpg" rel="nofollow">this image</a> where the object is the top the model is wearing. I have to do this on a range of images, some of them have very distinct background colors, some have very noisy/colorful backgrounds, and some are like this one where the background color and object color are very similar.</p>
  
  <p>Right now, the process I'm taking is from image -> grayscale -> use otsu threshold to get black and white image -> canny edge detection -> opening and closing -> find contour -> overlay on original image</p>
  
  <p>This works well with some of the images and doesn't work at all for others, like the one above. I don't know where to go from here and also have the one process automatically remove backgrounds for all the different images.</p>
  
  <p>I'm using the opencv2-python, PIL, and scikit-image packages.</p>
  
  <hr>
  
  <p>So I tried out grabcut and it works reasonably well. I ended up using the tutorial codes <a href="http://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_grabcut/py_grabcut.html" rel="nofollow">here</a> and modified it slightly.</p>
  
  <pre><code>import numpy as np
  import cv2
  from matplotlib import pyplot as plt
  
  img = cv2.imread(filename)
  img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) #convert to RGB color
  img = cv2.copyMakeBorder(img,1,1,1,1,cv2.BORDER_CONSTANT,value= (0,255,255) #add thin border so images where foreground bleeds off page are not cut out
  img = np.array(Image.fromarray(img).resize((200,200))) #make it run faster and standardize size of the img
  mask = np.zeros(img.shape[:2],np.uint8)
  
  bgdModel = np.zeros((1,65),np.float64)
  fgdModel = np.zeros((1,65),np.float64)
  
  rect = (1,1,200,200)
  cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)
  
  mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
  new_img = img.copy()
  new_img[np.where((mask2==0))] = np.array([0,255,255]).astype('uint8') #this allows you to change the background color after grabcut
  </code></pre>