pythonpython-3.xopencvcontour

How to group contours and draw a single bounding rectangle


I need to group contours and draw a single bounding rectangle that encloses all the contours, something like this

enter image description here

from matplotlib import pyplot as plt
import cv2 as cv

img = cv.imread('shapes1.png', 0)
imgRGB = cv.cvtColor(img.copy(), cv.COLOR_GRAY2RGB)

_, ctrs, _ = cv.findContours(img, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)

boxes = []
for ctr in ctrs:
    x, y, w, h = cv.boundingRect(ctr)
    boxes.append([x, y, w, h])

for box in boxes:
    top_left     = (box[0], box[1])
    bottom_right = (box[0] + box[2], box[1] + box[3])
    cv.rectangle(imgRGB, top_left, bottom_right, (0,255,0), 2)
    
fig = plt.figure(figsize = (10, 10))
ax  = fig.add_subplot(111)
ax.imshow(imgRGB, cmap='gray')

enter image description here

Is there any straight forward way to do it rather than merging all bounding rectangles programmatically


Solution

  • If you don't mind using numpy, you can simply use the concatenate function from there, see the following code. Attention: I use OpenCV 4.0.0 where the order of the return values of findContours is different.

    import cv2
    import numpy as np
    
    # Input image
    input = cv2.imread('images/kchZb.png', cv2.IMREAD_GRAYSCALE)
    
    # Modify input image to extract "original" image
    _, input = cv2.threshold(input[10:400, 40:580], 224, 255, cv2.THRESH_BINARY)
    
    # Find contours
    cnts, _ = cv2.findContours(input, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
    # Concatenate all contours
    cnts = np.concatenate(cnts)
    
    # Determine and draw bounding rectangle
    x, y, w, h = cv2.boundingRect(cnts)
    cv2.rectangle(input, (x, y), (x + w - 1, y + h - 1), 255, 2)
    
    # Output image
    cv2.imwrite('images/output.png', input)
    cv2.imshow('Input', input)
    cv2.waitKey(0)
    

    Output

    Disclaimer: I'm new to Python in general, and specially to the Python API of OpenCV (C++ for the win). Comments, improvements, highlighting Python no-gos are highly welcome!