title: Techniques to merge overlapping bounding boxes not working
body: <p>I am trying to detect text regions in an image with OpenCV (3.0)  and Python. So far, I am able to detect individual text characters and draw a bounding box or rectangle around them. My ultimate goal is merging individual text characters into words/text lines and eventually into text blocks or paragraphs.</p>
  
  <p>My approach is to finding neighbouring text regions, and then form a bounding box around these regions. So, in my code, I have expanded the bounding boxes or rectangles around each text characters a bit, so that they overlap each other, forming a chain of overlapping bounding boxes. (please refer to the image). Now, I would like to merge these overlapping rectangles to form a single bounding box based on overlap ratio between all bounding box pairs.</p>
  
  <p>I am having very hard time figuring out how to merge overlapping rectangles into a single one. For the last 24 hours, I have tried different techniques without any luck. Among them is cv2.groupRectangles. I think we need an array of rectangles (i.e. rectList) returned by cv2.cascade.detectMultiScale(); we also need haar cascades to detect objects in an image (i.e. in our case rectangles), and there are a number of haar cascades in the "data folder" and I am confused which one to use in my case (detecting rectangles).  </p>
  
  <p>If cv2.groupRectangles is not applicable in my case, then what might be other options I would like to know. If you have encountered similar problems, please share.   </p>
  
  <p><a href="https://i.stack.imgur.com/TQlUL.png" rel="noreferrer"><img src="https://i.stack.imgur.com/TQlUL.png" alt="enter image description here"></a></p>
  
  <p>Here is my working Python code </p>
  
  <pre><code>import numpy as np
  import cv2
  im = cv2.imread('headintext.png')
  grayImage = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
  # grayImage = cv2.imread('gates.jpg', cv2.IMREAD_GRAYSCALE)
  # cv2.imwrite('gates.png', grayImage)
  # cv2.imshow('image', grayImage)
  # cv2.waitKey(0)
  # cv2.destroyAllWindows()
  _,thresh = cv2.threshold(grayImage, 150, 255, cv2.THRESH_BINARY_INV)
  kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))
  dilated = cv2.dilate(thresh, kernel, iterations = 1) # dilate
  _,contours0,_ = cv2.findContours(dilated,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) # get contours
  contours = [cv2.approxPolyDP(cnt, 3, True) for cnt in contours0]
  # contours, hierarchy = cv2.findContours(thresh, 1, 2)
  # for each contour found, draw a rectangle around it on original image
  for contour in contours:
      # get rectangle bounding contour
      [x,y,w,h] = cv2.boundingRect(contour)
  
      # discard areas that are too large
      if h&gt;50 and w&gt;50:
          continue
  
      # discard areas that are too small
      if h&lt;5 or w&lt;5:
          continue
  
      # draw rectangle around contour on original image
      # slightly expand the rectangles to form a chain of overlapping bounding boxes
      pad_w, pad_h = int(0.05*w), int(0.15*h)
      cv2.rectangle(im,(x-pad_w,y-pad_h),(x+w+pad_w,y+h+pad_h),(255,0,255),1,shift=0)
  
  
  # write original image with added contours to disk
  cv2.imwrite("rectangle.png", im)
  cv2.imshow('image', im)
  cv2.waitKey(0)
  cv2.destroyAllWindows()
  </code></pre>
  
  <p>I have tried the following cv2.groupRectangles code, but it is not producing any effects at all. I have noticed cascade.detectMultiScale do not find any rectangles.</p>
  
  <pre><code>import numpy as np
  import cv2
  
  cascade = cv2.CascadeClassifier('data/haarcascades/haarcascade_frontalface_alt.xml')
  
  img = cv2.imread('rectangle.png')
  gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
  
  rawrects = cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=1, minSize=(5, 5), flags = cv2.CASCADE_SCALE_IMAGE)
  # rects, weights = cv2.groupRectangles(np.array(rawrects).tolist(), 1, 0.2)
  print "nrects %d" % len(rawrects)
  
  for i, r in enumerate(rawrects):
      weight = weights[i]
      rectline = "%f %f %f %f %d\n" % (r[0], r[1], r[2], r[3], weight)
      print rectline
  
      p1 = (r[0], r[1])
      p2 = (r[0]+r[2], r[1]+r[3])
      cv2.rectangle(img, p1, p2, (0,0,255))
  
      cv2.imshow('image', img)
      cv2.waitKey(0)
      cv2.destroyAllWindows()    
  </code></pre>