Spaces:
Sleeping
Sleeping
import cv2 | |
from cvzone.ColorModule import ColorFinder | |
def ball_detect(img, color_finder, hsv_values): | |
""" | |
Detects a ball in an image frame based on color. | |
Adapted to handle OpenCV-style contours (NumPy arrays of points). | |
Args: | |
img: The input image frame (BGR format). | |
color_finder: An instance of cvzone.ColorFinder for color detection. | |
hsv_values: A dictionary containing HSV range for ball color. | |
Returns: | |
tuple: (img_with_contours, ball_x, ball_y) | |
- img_with_contours: Image with contours drawn around the detected ball (or None if no ball detected). | |
- ball_x, ball_y: Center coordinates (x, y) of the detected ball (or 0, 0 if no ball detected). | |
""" | |
ball_x = 0 | |
ball_y = 0 | |
img_with_contours = None | |
if img is None: | |
return None, ball_x, ball_y | |
imggray_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) | |
_, mask = color_finder.update(imggray_hsv, hsv_values) | |
contours, _ = cv2.findContours( | |
mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE | |
) # Use standard cv2.findContours | |
# print(f"Type of contours: {type(contours)}") # Keep for debugging - should be NumPy array | |
if len(contours) > 0: | |
# Find the contour with the largest area using cv2.contourArea | |
largest_contour_index = 0 | |
max_area = 0 | |
for i, contour in enumerate(contours): | |
area = cv2.contourArea(contour) | |
if area > max_area: | |
max_area = area | |
largest_contour_index = i | |
largest_contour = contours[largest_contour_index] | |
# Calculate centroid using moments (OpenCV method for center of contour) | |
M = cv2.moments(largest_contour) | |
if M["m00"] != 0: # avoid division by zero | |
ball_x = int(M["m10"] / M["m00"]) | |
ball_y = int(M["m01"] / M["m00"]) | |
else: | |
ball_x = 0 | |
ball_y = 0 | |
img_with_contours = img.copy() | |
cv2.drawContours( | |
img_with_contours, [largest_contour], -1, (255, 0, 0), 2 | |
) # Draw largest contour | |
cv2.circle( | |
img_with_contours, (ball_x, ball_y), 5, (255, 0, 0), -1 | |
) # Draw center point | |
return img_with_contours, ball_x, ball_y | |
if __name__ == "__main__": | |
cap = cv2.VideoCapture(r"lbw.mp4") | |
color_finder = ColorFinder(False) | |
hsv_vals = { | |
"hmin": 10, | |
"smin": 44, | |
"vmin": 192, | |
"hmax": 125, | |
"smax": 114, | |
"vmax": 255, | |
} | |
while True: | |
frame, img = cap.read() | |
if not frame: | |
break | |
img_contours, x, y = ball_detect(img, color_finder, hsv_vals) | |
if img_contours is not None: | |
cv2.imshow("Ball Detection", img_contours) | |
else: | |
cv2.imshow("Ball Detection", img) | |
if cv2.waitKey(1) & 0xFF == ord("q"): | |
break | |
cap.release() | |
cv2.destroyAllWindows() | |