Spaces:
Sleeping
Sleeping
| """ | |
| Color detection and normalization utilities for play clock digit processing. | |
| This module provides utilities for detecting red digits (shown when play clock <= 5) | |
| and normalizing play clock regions to grayscale for consistent template matching. | |
| These utilities are shared across: | |
| - readers/playclock.py (template matching) | |
| - setup/template_builder.py (template building) | |
| - setup/playclock_region.py (OCR preprocessing) | |
| """ | |
| import logging | |
| from typing import Any | |
| import cv2 | |
| import numpy as np | |
| logger = logging.getLogger(__name__) | |
| def detect_red_digits(region: np.ndarray[Any, Any]) -> bool: | |
| """ | |
| Detect if the play clock digits are red. | |
| Red digits appear when the play clock has 5 seconds or less remaining. | |
| Red digits have high red channel values with very low green and blue. | |
| Args: | |
| region: Play clock region (BGR format) | |
| Returns: | |
| True if red digits detected, False otherwise | |
| """ | |
| # Split into BGR channels (np.asarray normalizes cv2.Mat type for numpy) | |
| b, g, r = cv2.split(region) | |
| # Calculate mean values for each channel | |
| r_mean = np.mean(np.asarray(r)) | |
| g_mean = np.mean(np.asarray(g)) | |
| b_mean = np.mean(np.asarray(b)) | |
| # Red digits: high red channel, very low green/blue, red > 2x green | |
| max_gb = max(g_mean, b_mean) | |
| is_red = bool(r_mean > 15 > max_gb and r_mean > g_mean * 2) | |
| if is_red: | |
| logger.debug("Red digits detected: R=%.1f, G=%.1f, B=%.1f", r_mean, g_mean, b_mean) | |
| return is_red | |
| def normalize_to_grayscale(region: np.ndarray[Any, Any]) -> np.ndarray[Any, Any]: | |
| """ | |
| Normalize a play clock region to grayscale, handling both red and white digits. | |
| Red digits (displayed when clock <= 5) are converted to white-like grayscale | |
| by extracting the red channel. White digits use standard grayscale conversion. | |
| This allows a single set of templates to match both color variants. | |
| Args: | |
| region: Play clock region (BGR format) | |
| Returns: | |
| Grayscale image where digits appear as bright pixels on dark background | |
| """ | |
| is_red = detect_red_digits(region) | |
| if is_red: | |
| # For red digits, use the red channel directly as grayscale | |
| # This converts red digits to white-like appearance | |
| _, _, r = cv2.split(region) | |
| return r | |
| # Standard grayscale conversion for white digits | |
| return cv2.cvtColor(region, cv2.COLOR_BGR2GRAY) | |