dschandra's picture
Upload 5 files
2649d00 verified
import cv2
import cvzone
import numpy as np
def batsman_detect(img, rgb_lower, rgb_upper, canny_threshold1=100, canny_threshold2=200):
"""
Detects a batsman in an image frame using color-based filtering and edge detection.
Args:
img: The input image frame (BGR format).
rgb_lower: NumPy array defining the lower bound of the RGB color range for batsman. e.g., np.array([112, 0, 181])
rgb_upper: NumPy array defining the upper bound of the RGB color range for batsman. e.g., np.array([255, 255, 255])
canny_threshold1: Lower threshold for Canny edge detection.
canny_threshold2: Upper threshold for Canny edge detection.
Returns:
contours: A list of contours detected in the color-masked and edge-processed image,
presumed to be the batsman. Returns an empty list if no contours are found.
"""
img_gray_rgb = cv2.cvtColor(
img, cv2.COLOR_BGR2RGB
) # Convert to RGB for color masking
img_blur = cv2.GaussianBlur(
img_gray_rgb, (5, 5), 1
) # Gaussian blur for noise reduction
# Edge Detection (Canny) - you can tune canny_threshold1 and canny_threshold2
img_canny = cv2.Canny(img_blur, canny_threshold1, canny_threshold2)
# Morphological Operations (Opening - Dilation followed by Erosion) - Consider experimenting with Closing (Erosion then Dilation)
kernel = np.ones((5, 5))
img_dilate = cv2.dilate(img_canny, kernel, iterations=2) # Dilate to thicken edges
img_threshold = cv2.erode(
img_dilate, kernel, iterations=2
) # Erode to remove noise and thin edges (Opening)
# Color Masking in RGB color space
mask = cv2.inRange(img_gray_rgb, rgb_lower, rgb_upper)
# Find contours in the color mask
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
return contours
if __name__ == "__main__":
cap = cv2.VideoCapture(r"lbw.mp4") # Adjust path if needed
# Default RGB color range - you should tune these using the trackbars below
default_rgb_lower = np.array([112, 0, 181])
default_rgb_upper = np.array([255, 255, 255])
# Canny thresholds - you can also tune these via trackbars if needed
default_canny_threshold1 = 100
default_canny_threshold2 = 200
def empty(a): # Dummy function for trackbar
pass
# Create a window for trackbars to tune RGB color range and Canny thresholds
cv2.namedWindow("Trackbars")
cv2.resizeWindow(
"Trackbars", 640, 480
) # Increased window height to fit more trackbars
cv2.createTrackbar("R Min", "Trackbars", default_rgb_lower[0], 255, empty)
cv2.createTrackbar("G Min", "Trackbars", default_rgb_lower[1], 255, empty)
cv2.createTrackbar("B Min", "Trackbars", default_rgb_lower[2], 255, empty)
cv2.createTrackbar("R Max", "Trackbars", default_rgb_upper[0], 255, empty)
cv2.createTrackbar("G Max", "Trackbars", default_rgb_upper[1], 255, empty)
cv2.createTrackbar("B Max", "Trackbars", default_rgb_upper[2], 255, empty)
cv2.createTrackbar(
"Canny Thresh 1", "Trackbars", default_canny_threshold1, 255, empty
) # Canny threshold 1
cv2.createTrackbar(
"Canny Thresh 2", "Trackbars", default_canny_threshold2, 255, empty
) # Canny threshold 2
while True:
frame, img = cap.read()
if not frame:
break
# Get trackbar positions for RGB color range
rgb_lower = np.array(
[
cv2.getTrackbarPos("R Min", "Trackbars"),
cv2.getTrackbarPos("G Min", "Trackbars"),
cv2.getTrackbarPos("B Min", "Trackbars"),
]
)
rgb_upper = np.array(
[
cv2.getTrackbarPos("R Max", "Trackbars"),
cv2.getTrackbarPos("G Max", "Trackbars"),
cv2.getTrackbarPos("B Max", "Trackbars"),
]
)
# Get trackbar positions for Canny thresholds
canny_threshold1 = cv2.getTrackbarPos("Canny Thresh 1", "Trackbars")
canny_threshold2 = cv2.getTrackbarPos("Canny Thresh 2", "Trackbars")
# Detect batsman using the function with tunable parameters
batsman_contours = batsman_detect(
img, rgb_lower, rgb_upper, canny_threshold1, canny_threshold2
)
img_contours = img.copy() # Copy image to draw contours on
for cnt in batsman_contours:
if (
cv2.contourArea(cnt) > 5000
): # Area filtering - you can adjust this threshold in main.py if needed
cv2.drawContours(
img_contours, cnt, -1, (0, 255, 0), 2
) # Draw batsman contours in green
img_mask = cv2.inRange(
cv2.cvtColor(img, cv2.COLOR_BGR2RGB), rgb_lower, rgb_upper
) # Show the mask for tuning
img_stack = cvzone.stackImages(
[img, img_mask, img_contours], 3, 0.5
) # Stack original, mask, and contours
cv2.imshow("Batsman Detection Tuning", img_stack) # Combined window for tuning
key = cv2.waitKey(1)
if key == ord("q"):
break
elif key == ord("s"): # Press 's' to save current RGB values to console
print("Saved RGB lower:", rgb_lower)
print("Saved RGB upper:", rgb_upper)
print("Saved Canny Threshold 1:", canny_threshold1)
print("Saved Canny Threshold 2:", canny_threshold2)
print(
"--- Copy these values to your main.py or default_rgb_lower/upper in batsman.py ---"
)
cap.release()
cv2.destroyAllWindows()