How to merge nearby rectangles
I am working on character segmentation and looking to merge nearby characters into a box. I have successfully found the contours but I am not sure how to find a straight line between the top and bottom points.
def findContours(self, image):
contour_img = image.copy()
vis = image.copy()
vis = cv2.cvtColor(vis, cv2.COLOR_GRAY2BGR)
_, contours, hierarchy = cv2.findContours(contour_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contoursBBS = []
for contour in contours:
[x, y, w, h] = cv2.boundingRect(contour)
if w > 100 or h < 8:
continue
contoursBBS.append([x, y, w, h, w*h])
contoursBBS = np.array(contoursBBS)
# reject outliers based on width, height, and area
rejectH = self.rejectOutliers(contoursBBS, 3, m=4)
rejectW = self.rejectOutliers(rejectH, 2, m=4)
rejectA = self.rejectOutliers(rejectW, 4, m=4)
contourRects = []
for c in rejectA:
[x, y, w, h, a] = c
if w < 9 or h < 15 or a < 300 or a > 6000:
continue
contourRects.append(c)
for i, rect in enumerate(contourRects):
[x, y, w, h, a] = rect
topCenter, bottomCenter = (int((2*x + w)/2), int(y)), (int((2*x + w)/2), int(y+h))
print("X: {:4d} Y: {:4d} W: {:4d} H: {:4d} A: {:4d}".format(x, y, w, h, a))
cv2.rectangle(vis, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.circle(vis, topCenter, 2, (0, 0, 255), 2)
cv2.circle(vis, bottomCenter, 2, (0, 0, 255), 2)
Result
What I am hoping to achieve
Some test images (requested by @supra56)