Paul Mark
Paul Mark

Reputation: 199

Identify and count objects different from background

I try to use python, NumPy, and OpenCV to analyze the image below and just draw a circle on each object found. The idea here is not to identify the bug only identify any object that is different from the background.

Original Image: enter image description here

Here is the code that I'm using.

import cv2
import numpy as np
img = cv2.imread('per.jpeg', cv2.IMREAD_GRAYSCALE)
if cv2.__version__.startswith('2.'):
    detector = cv2.SimpleBlobDetector()
else:
    detector = cv2.SimpleBlobDetector_create()
keypoints = detector.detect(img)
print(len(keypoints))
imgKeyPoints = cv2.drawKeypoints(img, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
status = cv2.imwrite('teste.jpeg',imgKeyPoints)
print("Image written to file-system : ",status)

But the problem is that I'm getting only a greyscale image as result without any counting or red circle, as shown below: enter image description here

Since I'm new to OpenCV and object recognition world I'm not able to identify what is wrong, and any help will be very appreciated.

Upvotes: 0

Views: 444

Answers (1)

fmw42
fmw42

Reputation: 53174

Here is one way in Python/OpenCV.

Threshold on the bugs color in HSV colorspace. Then use morphology to clean up the threshold. Then get contours. Then find the minimum enclosing circle around each contour. Then bias the radius to make a bit larger and draw the circle around each bug.

Input:

enter image description here

import cv2
import numpy as np

# read image
img = cv2.imread('bugs.jpg')

# convert image to hsv colorspace
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# threshold on bugs color
lower=(0,90,10)
upper=(100,250,170)
thresh = cv2.inRange(hsv, lower, upper)

# apply morphology to clean up
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
morph = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (6,6))
morph = cv2.morphologyEx(morph, cv2.MORPH_CLOSE, kernel)

# get external contours
contours = cv2.findContours(morph, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]

result = img.copy()
bias = 10
for cntr in contours:
    center, radius = cv2.minEnclosingCircle(cntr)
    cx = int(round(center[0]))
    cy = int(round(center[1]))
    rr = int(round(radius)) + bias
    cv2.circle(result, (cx,cy), rr, (0, 0, 255), 2)

# save results
cv2.imwrite('bugs_threshold.jpg', thresh)
cv2.imwrite('bugs_cleaned.jpg', morph)
cv2.imwrite('bugs_circled.jpg', result)

# display results
cv2.imshow('thresh', thresh)
cv2.imshow('morph', morph)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

Threshold Image:

enter image description here

Morphology Cleaned Image:

enter image description here

Resulting Circles:

enter image description here

Upvotes: 1

Related Questions