Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect circles with specific colors using opencv

I have to detect yellow circles in an image using OpenCV and python, as shown in the first image:

Picture 1 image

Once I detect the yellow circle, I have to highlight it, like so:

Picture 2

I am new to OpenCV, so I was looking for some guidance or help. All help is appreciated

like image 724
Coder Avatar asked Sep 14 '25 08:09

Coder


1 Answers

Here's a potential approach:

  • Convert image to HSV
  • Find upper/lower color boundaries and create a mask
  • Find contours and filter using the number of vertices

We convert image to HSV and then determine lower and upper boundaries to create a mask using cv2.inRange(). This step isolates the yellow objects

image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower = np.array([0, 208, 94], dtype="uint8")
upper = np.array([179, 255, 232], dtype="uint8")
mask = cv2.inRange(image, lower, upper)

Next to determine the shape, we find contours and filter using the number of vertices. We use cv2.arcLength() and cv2.approxPolyDP() to obtain a list of vertices and approximate contours. We can check the number of entries in this list to determine the shape of an object. For instance, if the contour has three vertices, it must be a triangle. Similarly, if it has four vertices, it must be a square. So for this image, we can make the assumption the shape is a circle if it has greater than a certain number of vertices. Here's the result

import numpy as np
import cv2

image = cv2.imread('1.png')
original = image.copy()
image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower = np.array([0, 208, 94], dtype="uint8")
upper = np.array([179, 255, 232], dtype="uint8")
mask = cv2.inRange(image, lower, upper)

# Find contours
cnts = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Extract contours depending on OpenCV version
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

# Iterate through contours and filter by the number of vertices 
for c in cnts:
    perimeter = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.04 * perimeter, True)
    if len(approx) > 5:
        cv2.drawContours(original, [c], -1, (36, 255, 12), -1)

cv2.imshow('mask', mask)
cv2.imshow('original', original)
cv2.imwrite('mask.png', mask)
cv2.imwrite('original.png', original)
cv2.waitKey()
like image 127
nathancy Avatar answered Sep 15 '25 20:09

nathancy