Search code examples
pythonopencvtrackingobject-detection

OpenCV + python red ball detection and tracking


I am working on an object detection and tracking system, the input is a rgb webcam stream. My code has no problems to detect e.g. yellow, green and blue geometrical objects like balls, but when it comes to red balls, I am challenging a problem.

# converting the input stream into HSV color space
hsv_conv_img = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

# because hue wraps up and to extract as many "red objects" as possible, I define lower and upper boundaries for brighter and for darker red shades
bright_red_lower_bounds = (0, 100, 100)
bright_red_upper_bounds = (10, 255, 255)
bright_red_mask = cv2.inRange(hsv_conv_img, bright_red_lower_bounds, bright_red_upper_bounds)

dark_red_lower_bounds = (160, 100, 100)
dark_red_upper_bounds = (179, 255, 255)
dark_red_mask = cv2.inRange(hsv_conv_img, dark_red_lower_bounds, dark_red_upper_bounds)

# after masking the red shades out, I add the two images 
weighted_mask = cv2.addWeighted(bright_red_mask, 1.0, dark_red_mask, 1.0, 0.0)

# then the result is blurred
blurred_mask = cv2.GaussianBlur(weighted_mask,(9,9),3,3)

# some morphological operations (closing) to remove small blobs 
erode_element = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
dilate_element = cv2.getStructuringElement(cv2.MORPH_RECT, (8, 8))
eroded_mask = cv2.erode(blurred_mask,erode_element)
dilated_mask = cv2.dilate(eroded_mask,dilate_element)

# on the color-masked, blurred and morphed image I apply the cv2.HoughCircles-method to detect circle-shaped objects 
detected_circles = cv2.HoughCircles(dilated_mask, cv2.HOUGH_GRADIENT, 1, 150, param1=100, param2=20, minRadius=20, maxRadius=200)
if detected_circles is not None:
    for circle in detected_circles[0, :]:
        circled_orig = cv2.circle(frame, (circle[0], circle[1]), circle[2], (0,255,0),thickness=3)
    cv2.imshow("original", circled_orig)
else:
    cv2.imshow("original", frame)

Problem: by defining a broad range of "red" to extract from HSV, parts of my hand and my face (when standing in front of the camera, holding the ball) are extracted, too. Later the HoughCircles-method detects little circles in the remaining area of my hand and my face.

I played a bit with the (not so easy to adjusting) parameters for cv2.HoughCircles, e.g. a small value of param2 detects a lot more (false) circles than a bigger value.

Does anybody have an idea how to overcome this problem and eliminate the falsely detected circles? Requirement: The system knows nothing about the size of the balls, it should detect a lot. So I cannot define a minimum or maximum circle radius to eliminate the false positives.

Many thanks in advance. Regards, Chris

p.s.: this piece of code is closely oriented towards this one


Solution

  • Since the reddish areas on your face and hands are - I hope - much less homogeneous than the ball, try blurring before the HSV thresholding. That should soften the red areas where you don't want to detect them and on the ball, the color should stay more or less the same.

    EDIT: If the example you provided in a comment is anything close to the real situation, it proves that blur will resolve your issue. What you want to do basically, is create multiple trackbars and adjust them simultaneously for different types of blur; morphological operations; and the HSV thresholding itself (since the blur might change the best values for the thresholds). Experiment with that with a live view of the resulting detected region and that should help you figure out what helps and what doesn't.

    As my Professor used to say: "if our eyes can see, the computer can see it". And that's clearly the case here - the ball is very different color than Beckham's face.