I am working on a project and I need to determine the location of circles in a live feed from a camera.
I have already managed to get this kinda running, but I get a weird jitter with the recognition of the circles, and sometimes a circle is not recognized at all.
Here is a Example of this:
The function I Use for editing the Image is:
def preprocess_image(self):
self.image = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
# apply GuassianBlur to reduce noise. medianBlur is also added for smoothening, reducing noise.
self.image = cv2.GaussianBlur(self.image,(5,5),0);
self.image = cv2.medianBlur(self.image,5)
# Adaptive Guassian Threshold is to detect sharp edges in the Image. For more information Google it.
self.image = cv2.adaptiveThreshold(self.image,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
cv2.THRESH_BINARY,11,3.5)
kernel = np.ones((2,2),np.uint8)
self.image = cv2.erode(self.image,kernel,iterations = 1) # gray = erosion
self.image = cv2.dilate(self.image,kernel,iterations = 1) # gray = dilation
And the Method for detecting the circles is:
def get_circles(self):
rows = self.image.shape[0] # width of the image (1280)
# detect circles in the image
self.circles = cv2.HoughCircles(
self.image,
cv2.HOUGH_GRADIENT,
1,
rows / 8,
param1=self.parameters["param1"],
param2=self.parameters["param2"],
minRadius=self.parameters["minRadius"],
maxRadius=self.parameters["maxRadius"]
)
if self.circles is None: return None
self.circles = np.round(self.circles[0, :]).astype("int")
How do I get rid of this jitter and the sometimes missing recognition of the circles?
I solved the issue by ditching hough transforms and instead using connectedComponentsWithStats to transform the circles into black blobs as suggested by Christoph Rackwitz.
Then I used the SimpleBlobDetector to detect the wanted circles.
This works way better then before!
Here is the Code I used:
import cv2
import numpy as np
def detect_circles(image):
_, labels, _, _ = cv2.connectedComponentsWithStats(image)
# Extract the pixels associated with the current label
label_mask = np.zeros(image.shape, dtype=np.uint8)
label_mask[labels == 1] = 255
params = cv2.SimpleBlobDetector_Params()
# Set Area filtering parameters
params.filterByArea = True
params.minArea = 1000
params.maxArea = 10000
params.filterByCircularity = True
params.minCircularity = .7
# Create a detector with the parameters
detector = cv2.SimpleBlobDetector_create(params)
# Detect blobs
keypoints = detector.detect(label_mask)
circles = []
for kp in keypoints:
circles.append(np.array([int(kp.pt[0]), int(kp.pt[1]), int(kp.size / 2)]))
return circles
cap = cv2.VideoCapture("<your sample video>")
while True:
ret, frame = cap.read()
if np.sum(frame) == 0:[![enter image description here][1]][1]
break
detect_circles(frame)
# draw the circles on image here
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
cap.release()