Ball circle shape tracking in video or live feed with opencv python

Tracking the shape of a ball in a video or live feed can be a challenging task, but with the help of OpenCV library in Python, it becomes much easier. In this article, we will explore three different approaches to solve this problem.

Approach 1: Color-based Tracking

One way to track the ball shape is by using color-based tracking. This approach assumes that the ball has a distinct color that stands out from the background. Here’s how you can implement it:


import cv2
import numpy as np

# Define the lower and upper boundaries of the ball color in HSV color space
lower_color = np.array([H_MIN, S_MIN, V_MIN])
upper_color = np.array([H_MAX, S_MAX, V_MAX])

# Capture video or live feed
cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()
    
    if not ret:
        break
    
    # Convert the frame to HSV color space
    hsv_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    
    # Create a mask using the color boundaries
    mask = cv2.inRange(hsv_frame, lower_color, upper_color)
    
    # Apply morphological operations to remove noise
    mask = cv2.erode(mask, None, iterations=2)
    mask = cv2.dilate(mask, None, iterations=2)
    
    # Find contours of the ball shape
    contours, _ = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
    if len(contours) > 0:
        # Find the largest contour
        largest_contour = max(contours, key=cv2.contourArea)
        
        # Get the center and radius of the enclosing circle
        ((x, y), radius) = cv2.minEnclosingCircle(largest_contour)
        
        # Draw the circle on the frame
        cv2.circle(frame, (int(x), int(y)), int(radius), (0, 255, 0), 2)
    
    # Display the frame
    cv2.imshow("Ball Tracking", frame)
    
    if cv2.waitKey(1) == ord('q'):
        break

# Release the video capture and close all windows
cap.release()
cv2.destroyAllWindows()

This approach works by defining the lower and upper boundaries of the ball color in the HSV color space. It then creates a mask using these boundaries and applies morphological operations to remove noise. Finally, it finds the contours of the ball shape and draws an enclosing circle on the frame.

Approach 2: Template Matching

Another approach to track the ball shape is by using template matching. This method assumes that you have a template image of the ball shape. Here’s how you can implement it:


import cv2
import numpy as np

# Load the template image
template = cv2.imread("ball_template.png", 0)

# Capture video or live feed
cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()
    
    if not ret:
        break
    
    # Convert the frame to grayscale
    gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
    # Perform template matching
    result = cv2.matchTemplate(gray_frame, template, cv2.TM_CCOEFF_NORMED)
    
    # Get the location of the maximum value in the result
    _, max_val, _, max_loc = cv2.minMaxLoc(result)
    
    # Get the center and radius of the enclosing circle
    x, y = max_loc
    radius = template.shape[1] // 2
    
    # Draw the circle on the frame
    cv2.circle(frame, (x + radius, y + radius), radius, (0, 255, 0), 2)
    
    # Display the frame
    cv2.imshow("Ball Tracking", frame)
    
    if cv2.waitKey(1) == ord('q'):
        break

# Release the video capture and close all windows
cap.release()
cv2.destroyAllWindows()

This approach works by loading a template image of the ball shape and performing template matching on each frame of the video or live feed. It then finds the location of the maximum value in the result and draws an enclosing circle on the frame.

Approach 3: Deep Learning-based Tracking

The third approach to track the ball shape is by using deep learning-based object detection models. This method requires training a model to detect the ball shape and then using it for tracking. Here’s a simplified example using the YOLOv3 model:


import cv2
import numpy as np

# Load the pre-trained YOLOv3 model
net = cv2.dnn.readNetFromDarknet("yolov3.cfg", "yolov3.weights")

# Get the output layer names
layer_names = net.getLayerNames()
output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]

# Capture video or live feed
cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()
    
    if not ret:
        break
    
    # Perform object detection
    blob = cv2.dnn.blobFromImage(frame, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
    net.setInput(blob)
    outs = net.forward(output_layers)
    
    # Get the bounding boxes, confidences, and class IDs
    boxes = []
    confidences = []
    class_ids = []
    
    for out in outs:
        for detection in out:
            scores = detection[5:]
            class_id = np.argmax(scores)
            confidence = scores[class_id]
            
            if confidence > 0.5 and class_id == 0:  # Assuming class 0 is the ball
                center_x = int(detection[0] * frame.shape[1])
                center_y = int(detection[1] * frame.shape[0])
                width = int(detection[2] * frame.shape[1])
                height = int(detection[3] * frame.shape[0])
                
                x = int(center_x - width / 2)
                y = int(center_y - height / 2)
                
                boxes.append([x, y, width, height])
                confidences.append(float(confidence))
                class_ids.append(class_id)
    
    # Apply non-maximum suppression to remove overlapping boxes
    indices = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)
    
    for i in indices:
        i = i[0]
        x, y, width, height = boxes[i]
        
        # Get the center and radius of the enclosing circle
        center_x = x + width // 2
        center_y = y + height // 2
        radius = max(width, height) // 2
        
        # Draw the circle on the frame
        cv2.circle(frame, (center_x, center_y), radius, (0, 255, 0), 2)
    
    # Display the frame
    cv2.imshow("Ball Tracking", frame)
    
    if cv2.waitKey(1) == ord('q'):
        break

# Release the video capture and close all windows
cap.release()
cv2.destroyAllWindows()

This approach uses a pre-trained YOLOv3 model for object detection. It performs object detection on each frame of the video or live feed and then finds the bounding boxes of the detected objects. It filters out the ball shape based on the class ID and confidence score, and finally draws an enclosing circle on the frame.

Among the three options, the best approach depends on the specific requirements and constraints of the project. If the ball has a distinct color, color-based tracking can be a simple and effective solution. If a template image of the ball shape is available, template matching can provide accurate results. However, if the ball shape needs to be detected in various environments and conditions, deep learning-based tracking using object detection models like YOLOv3 can offer better robustness and flexibility.

Rate this post

10 Responses

    1. I understand your concern, but deep learning has shown great potential in accurately tracking various objects. With proper training and data, it can certainly be trusted to track ball shape effectively. Lets give it a chance before dismissing its capabilities.

    1. Id say template matching falls short when it comes to handling diverse ball shapes and sizes. Its like trying to fit a square peg into a round hole. Maybe a more robust and adaptable approach, like machine learning, would be a better fit? Just a thought. 🤷‍♀️

Leave a Reply

Your email address will not be published. Required fields are marked *

Table of Contents