File size: 5,474 Bytes
5d257ae
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/usr/bin/env python3
"""
Diagnose why the punt at 6107s (1:41:47) wasn't detected.

The freeze→25 detection fires at 6117.9s, but no play was started between
6065.4s (previous play end) and 6117.9s. Why?
"""

import json
import logging
import sys
from pathlib import Path

import cv2

# Add src to path
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))

from detection.scorebug import DetectScoreBug
from readers import ReadPlayClock
from setup import DigitTemplateLibrary, PlayClockRegionConfig, PlayClockRegionExtractor

logging.basicConfig(level=logging.INFO, format="%(message)s")
logger = logging.getLogger(__name__)

# Video and config paths
VIDEO_PATH = Path("/Users/andytaylor/Documents/Personal/cfb40/full_videos/OSU vs Oregon 01.01.25.mkv")
CONFIG_PATH = Path("/Users/andytaylor/Documents/Personal/cfb40/output/OSU_vs_Oregon_01_01_25_config.json")
TEMPLATE_DIR = Path("/Users/andytaylor/Documents/Personal/cfb40/output/debug/digit_templates")

# Time window to analyze: 6060s to 6125s
START_TIME = 6060
END_TIME = 6125


def main():
    # Load config
    with open(CONFIG_PATH, "r") as f:
        config = json.load(f)

    # Set up fixed coordinates
    scorebug_bbox = (
        config["scorebug_x"],
        config["scorebug_y"],
        config["scorebug_width"],
        config["scorebug_height"],
    )
    playclock_coords = (
        config["scorebug_x"] + config["playclock_x_offset"],
        config["scorebug_y"] + config["playclock_y_offset"],
        config["playclock_width"],
        config["playclock_height"],
    )
    template_path = config["template_path"]

    print(f"Video: {VIDEO_PATH}")
    print(f"Scorebug bbox: {scorebug_bbox}")
    print(f"Playclock coords: {playclock_coords}")
    print()

    # Initialize components
    scorebug_detector = DetectScoreBug(template_path=template_path, fixed_region=scorebug_bbox, use_split_detection=True)

    # Load digit templates
    template_library = DigitTemplateLibrary()
    if not template_library.load(str(TEMPLATE_DIR)):
        print(f"ERROR: Could not load digit templates from {TEMPLATE_DIR}")
        return

    clock_reader = ReadPlayClock(template_library, config["playclock_width"], config["playclock_height"])

    # Open video
    cap = cv2.VideoCapture(str(VIDEO_PATH))
    fps = cap.get(cv2.CAP_PROP_FPS)
    frame_interval = 0.5  # Same as main pipeline

    print(f"FPS: {fps:.2f}, Frame interval: {frame_interval}s")
    print()
    print(f"{'Time':>10} | {'Clock':>6} | {'SB Det':>7} | {'SB Match':>8} | {'Notes'}")
    print("-" * 60)

    # Track state
    last_clock = None
    freeze_start = None
    freeze_value = None

    current_time = START_TIME
    while current_time <= END_TIME:
        frame_num = int(current_time * fps)
        cap.set(cv2.CAP_PROP_POS_FRAMES, frame_num)
        ret, frame = cap.read()

        if not ret or frame is None:
            print(f"{current_time:>10.1f} | {'???':>6} | {'NO FRAME':>7} |")
            current_time += frame_interval
            continue

        # Detect scorebug
        scorebug = scorebug_detector.detect(frame)

        # Read clock
        clock_value = None
        sb_det = "No"
        sb_match = "N/A"
        notes = []

        if scorebug.detected:
            sb_det = "Yes"
            sb_match = "Yes" if scorebug.template_matched else "No"

            clock_result = clock_reader.read_from_fixed_location(frame, playclock_coords, padding=4)
            if clock_result and clock_result.detected and clock_result.value is not None:
                clock_value = clock_result.value

                # Track freeze
                if last_clock == clock_value:
                    if freeze_start is None:
                        freeze_start = current_time - frame_interval
                        freeze_value = clock_value
                    freeze_duration = current_time - freeze_start
                    if freeze_duration > 0.5:
                        notes.append(f"frozen {freeze_duration:.1f}s")
                else:
                    # Clock changed
                    if freeze_start is not None and clock_value == 25 and freeze_value is not None and freeze_value <= 24:
                        freeze_duration = current_time - freeze_start
                        notes.append(f"*** FREEZE→25 from {freeze_value} (frozen {freeze_duration:.1f}s) ***")
                    freeze_start = None
                    freeze_value = None

                    # Check for play start indicators
                    if clock_value == 40:
                        notes.append("*** CLOCK AT 40 - should trigger play start ***")
                    if clock_value == 25 and last_clock is not None and last_clock != 25:
                        notes.append(f"jump to 25 from {last_clock}")

                last_clock = clock_value
        else:
            sb_det = "No"
            sb_match = "N/A"
            notes.append("scorebug not detected")
            # Reset tracking when scorebug lost
            freeze_start = None
            freeze_value = None

        time_str = f"{current_time:.1f}s"
        clock_str = str(clock_value) if clock_value is not None else "???"
        note_str = " | ".join(notes) if notes else ""

        print(f"{time_str:>10} | {clock_str:>6} | {sb_det:>7} | {sb_match:>8} | {note_str}")

        current_time += frame_interval

    cap.release()
    print()
    print("Analysis complete.")


if __name__ == "__main__":
    main()