File size: 2,410 Bytes
ecbaf10
 
 
 
 
 
 
 
 
 
 
 
 
719b8f7
ecbaf10
 
 
 
 
 
 
719b8f7
ecbaf10
 
 
 
 
 
 
 
 
 
 
 
719b8f7
ecbaf10
 
 
719b8f7
 
 
ecbaf10
 
 
1f3bac1
ecbaf10
 
 
 
 
 
 
719b8f7
ecbaf10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
"""
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)