Home > other >  How to count the color detected objects using python opencv
How to count the color detected objects using python opencv

Time:03-19

I am trying to detect objects using color. Below is the code and the image

import cv2
import numpy as np

img = cv2.imread('image2.jpeg')
img1 = img[157:498, 212:705]

hsv = cv2.cvtColor(img1, cv2.COLOR_BGR2HSV)
lower_bound = np.array([0, 20, 20])
upper_bound = np.array([20, 255, 255])
origMask = cv2.inRange(hsv, lower_bound, upper_bound)
kernel = np.ones((7, 7), np.uint8)
mask = cv2.morphologyEx(origMask, cv2.MORPH_CLOSE, kernel)
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)

cv2.imshow("Mask", mask)
cv2.imshow("Crop Image", img1)
cv2.imshow("Orig Image", img)
    
cv2.waitKey(0)
cv2.destroyAllWindows()

So in the above code, I am loading the image first. Then cropping it to a desired area and then performing the HSV to find orange color objects. Below is the original image

enter image description here

Below is the cropped image

enter image description here

Below is the mask image after hsv

enter image description here

I want to know how can I count the number of objects in the mask image. For ex, in this case it is 3. And after counting it, how can I draw bounding box over these color objects on the original image. Please help. Thanks

CodePudding user response:

You can use your binary mask to get the contours of the image. Then, you can compute the bounding rectangles belonging to each contour. Assume the input is your binary mask, the script should look like this:

# imports:
import cv2

# image path
path = "D://opencvImages//"
fileName = "objectsMask.png" # This is your binary mask

# Reading an image in default mode:
inputImage = cv2.imread(path   fileName)

# Deep copy for results:
inputImageCopy = inputImage.copy()

# Convert RGB to grayscale:
grayscaleImage = cv2.cvtColor(inputImage, cv2.COLOR_BGR2GRAY)

# Find the contours on the binary image:
contours, hierarchy = cv2.findContours(grayscaleImage, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# Store bounding rectangles and object id here:
objectData = []

# ObjectCounter:
objectCounter = 1

# Look for the outer bounding boxes (no children):
for _, c in enumerate(contours):
    # Get the contour's bounding rectangle:
    boundRect = cv2.boundingRect(c)

    # Store in list:
    objectData.append((objectCounter, boundRect))

    # Get the dimensions of the bounding rect:
    rectX = boundRect[0]
    rectY = boundRect[1]
    rectWidth = boundRect[2]
    rectHeight = boundRect[3]

    # Draw bounding rect:
    color = (0, 0, 255)
    cv2.rectangle(inputImageCopy, (int(rectX), int(rectY)),
                  (int(rectX   rectWidth), int(rectY   rectHeight)), color, 2)

    # Draw object counter:
    font = cv2.FONT_HERSHEY_SIMPLEX
    fontScale = 1
    fontThickness = 2
    color = (0, 255, 0)
    cv2.putText(inputImageCopy, str(objectCounter), (int(rectX), int(rectY)), 
                font, fontScale, color, fontThickness)

    # Increment object counter
    objectCounter  = 1

    cv2.imshow("Rectangles", inputImageCopy)
    cv2.waitKey(0)

I'm creating a list called objectData. Here, I'm storing the object's "id" (just an object counter) and its bounding rectangle. This is the output:

enter image description here

  • Related