Search code examples
pythonopencvbounding-box

Python: Showing every Object of an image in its own window


I've written some code, to crop an object (in this case the Data Matrix Code) from an image:

import numpy as np
import cv2

image = cv2.imread("datamatrixc.png")
img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

img_height, img_width = image.shape[:2]

WHITE = [255, 255, 255]

# Threshold filter
ret, thresh = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV)

# Get Contours
_, contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# Get Last element of the contours object
max = len(contours) - 1

cnt = contours[max]

# Get coordinates for the bounding box  
x, y, w, h = cv2.boundingRect(cnt)

image_region = image[ int(((img_height / 2) - h) / 2) : int(((img_height / 2) - h) / 2 + h), int(x): int(x + w) ]
dmc = cv2.copyMakeBorder(image_region, 10, 10, 10, 10, cv2.BORDER_CONSTANT, value = WHITE)

cv2.imshow("Test", dmc)
cv2.waitKey(0)
cv2.destroyAllWindows()

First Image Data Matrix

The code works fine and I received as result:

Result Of My Python Code

However, the next image is a little more complicated. I receive the same result as in the previous image, but I have no idea how to detect the two other objects.

Second Image With Three Objects

Is there an easier way every object showing in its window?


Solution

  • How about this?

    import numpy as np
    import cv2
    
    image = cv2.imread("datamatrixc.png")
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    ret, bin_img = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
    
    kernel = np.ones((3,3),np.uint8)
    closing = cv2.morphologyEx(bin_img, cv2.MORPH_CLOSE, kernel, iterations=4)
    
    n_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(bin_img)
    
    size_thresh = 5000
    
    for i in range(1, n_labels):
        if stats[i, cv2.CC_STAT_AREA] >= size_thresh:
            print(stats[i, cv2.CC_STAT_AREA])
            x = stats[i, cv2.CC_STAT_LEFT]
            y = stats[i, cv2.CC_STAT_TOP]
            w = stats[i, cv2.CC_STAT_WIDTH]
            h = stats[i, cv2.CC_STAT_HEIGHT]
    
            cv2.imshow('img', image[y:y+h, x:x+w])
            cv2.waitKey(0)