|
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
|
|
)
|
|
|
|
|
|
if len(contours) > 0:
|
|
|
|
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]
|
|
|
|
|
|
M = cv2.moments(largest_contour)
|
|
if M["m00"] != 0:
|
|
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
|
|
)
|
|
cv2.circle(
|
|
img_with_contours, (ball_x, ball_y), 5, (255, 0, 0), -1
|
|
)
|
|
|
|
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()
|
|
|