pythonnumpyopencvbounding-boximage-preprocessing

Is there any way to create multiple bounding boxes around non zero numpy array values?


I have a numpy array of an image. I have set non zero values for my region of interest and for rest I have set value as 0. Now if I were to create a single bounding box, I could check for 1st occurance and last occurance of non zero value and get the coordinates. But what if the non zero values are on different places?

How can I create 2 bounding boxes instead of one?

I tried -

A = array([[0, 0, 0, 0, 0, 0, 0],
           [1, 1, 0, 0, 0, 0, 0],
           [1, 1, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 1, 1, 1],
           [0, 0, 0, 0, 1, 1, 1],
           [0, 0, 0, 0, 1, 1, 1],
           [0, 0, 0, 0, 0, 0, 0]])

and I was expecting 2 bounding boxes around the Ones.


Solution

  • I tested similar code in my own project, but I didn't test this particular snippet. Comment if you encounter any bugs.

    import cv2
    import numpy as np
    
    A = np.array([[0, 0, 0, 0, 0, 0, 0],
               [1, 1, 0, 0, 0, 0, 0],
               [1, 1, 0, 0, 0, 0, 0],
               [0, 0, 0, 0, 1, 1, 1],
               [0, 0, 0, 0, 1, 1, 1],
               [0, 0, 0, 0, 1, 1, 1],
               [0, 0, 0, 0, 0, 0, 0]])
    
    _, markers = cv2.connectedComponents(np.expand_dims(A.astype(np.uint8),axis=2),connectivity=4)
    
    markers = np.squeeze(markers)
    
    bounding_boxes = []
    
    for label in range(1,int(np.max(markers))+1):
    
        locations = np.transpose(np.nonzero(markers==label))
    
        min_x, max_x, min_y, max_y = np.min(locations[:,1]), np.max(locations[:,1]), np.min(locations[:,0]), np.max(locations[:,0])
    
        bounding_boxes.append((min_x, max_x, min_y, max_y))
    
    print(bounding_boxes)