lbw_detection_in_cricket / ball_detect.py
dschandra's picture
Upload 5 files
2649d00 verified
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()