title: Using Python OpenCV, How would you extract an image area inside a particular color bounding box?
body: <p>Given a photo that I have manually drawn a colored bounding box,
  I want to copy / crop the image content, to keep the content inside the bounding box.</p>
  
  <p>The goal is to detect that color bounding box, and then use that to tell the script where to copy/crop.</p>
  
  <p>I have experimented with contours, but it appears I need extra steps.</p>
  
  <p>Perhaps a way to:</p>
  
  <ul>
  <li>detect the bounded area</li>
  <li>find the smallest area (the box lines could be of variable thickness, so I need the inside bounding area - the bounding eventually will be a colored poster board cutout box in the physical world) </li>
  <li>the script creates a mask for that area</li>
  <li>grab the image</li>
  </ul>
  
  <p>There could be a better way;
  What is the best way to go about this?
  And what Python OpenCV methods would I use?</p>
  
  <p>Based on my current experimental code (I was exploring getting the area by contour size, but I think I need better contour code):</p>
  
  <pre><code>import numpy as np
  import cv2
  
  image_dir = "/Users/admin/Documents/dir/dir2/"
  
  im = cv2.imread(image_dir+'test_image_bounded.png')
  imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
  ret,thresh = cv2.threshold(imgray,176,190,43)
  #ret,thresh = cv2.threshold(imgray,127,255,0)
  contours, hierarchy =         cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
  
  areaArray = []
  count = 1
  
  for i, c in enumerate(contours):
      area = cv2.contourArea(c)
      areaArray.append(area)
  
  #first sort the array by area
  sorteddata = sorted(zip(areaArray, contours), key=lambda x: x[0], reverse=True)
  
  #find the nth largest contour [n-1][1], in this case 2
  largestcontour = sorteddata[0][2]
  
  #draw it
  x, y, w, h = cv2.boundingRect(largestcontour)
  cv2.drawContours(im, largestcontour, -1, (255, 0, 0), 2)
  cv2.rectangle(im, (x, y), (x+w, y+h), (0,255,0), 2)
  cv2.imwrite(image_dir+'output.jpg', im)
  </code></pre>
  
  <p><img src="https://i.stack.imgur.com/PsaMg.jpg" alt="Manually bounded image"></p>
  
  <p>edit --------------------------------</p>
  
  <p>I've managed to get some pretty good results by color detection, morphology, and grabbing the second largest threshold</p>
  
  <p>Here is some relevant code:</p>
  
  <pre><code>green_MIN = np.array([45, 25, 25],np.uint8)
  green_MAX = np.array([55, 255, 255],np.uint8)
  
  hsv_img = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
  
  frame_threshed = cv2.inRange(hsv_img, green_MIN, green_MAX)
  
  #image = cv2.imread('...') # Load your image in here
  # Your code to threshold
  #image = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 45, 0)    
  
  # Perform morphology
  se = np.ones((20,20), dtype='uint8')
  image_close = cv2.morphologyEx(frame_threshed, cv2.MORPH_CLOSE, se)
  </code></pre>
  
  <p>The HSV values are a pain; I'd like to automate that part.
  This was helpful to get value:
  <a href="https://achuwilson.wordpress.com/2012/02/14/hsv-pixel-values-in-opencv/" rel="nofollow noreferrer">https://achuwilson.wordpress.com/2012/02/14/hsv-pixel-values-in-opencv/</a></p>