File size: 5,112 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
#!/usr/bin/env python3
"""
Compare playclock regions between working and non-working timestamps.

This will help us understand why clock readings work at some timestamps
but not others.
"""

import json
import logging
import sys
from pathlib import Path

import cv2
import numpy as np

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

from readers import ReadPlayClock
from setup import DigitTemplateLibrary
from video import iter_frames_ffmpeg
from utils.regions import preprocess_playclock_region

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

# Video path
VIDEO_PATH = Path("/Users/andytaylor/Documents/Personal/cfb40/full_videos/OSU vs Oregon 01.01.25.mkv")

# Working timestamps (from detected plays in the output JSON)
# - Play #94 at 4104.5s works
# - Play #148 at 6645.4s works
WORKING_TIMESTAMPS = [4104.5, 6645.5]

# Non-working timestamps (from ground truth)
FAILING_TIMESTAMPS = [4136, 6684]


def load_session_config(config_path: str) -> dict:
    """Load session config."""
    with open(config_path, "r", encoding="utf-8") as f:
        return json.load(f)


def main():
    if not VIDEO_PATH.exists():
        print(f"ERROR: Video not found at {VIDEO_PATH}")
        return

    # Load config
    video_basename = VIDEO_PATH.stem.replace(" ", "_").replace(".", "_")
    config_path = Path("output") / f"{video_basename}_config.json"
    config = load_session_config(str(config_path))

    # Calculate absolute play clock coordinates
    playclock_coords = (
        config["scorebug_x"] + config["playclock_x_offset"],
        config["scorebug_y"] + config["playclock_y_offset"],
        config["playclock_width"],
        config["playclock_height"],
    )

    print(f"Playclock coords: {playclock_coords}")

    # Load digit templates
    template_dir = Path("output/debug/digit_templates")
    library = DigitTemplateLibrary()
    if not library.load(str(template_dir)):
        print(f"ERROR: Could not load digit templates from {template_dir}")
        return

    # Create clock reader
    reader = ReadPlayClock(library, region_width=config["playclock_width"], region_height=config["playclock_height"])

    # Create output directory
    output_dir = Path("output/debug/clock_comparison")
    output_dir.mkdir(parents=True, exist_ok=True)

    print("\n" + "=" * 70)
    print("WORKING TIMESTAMPS (plays were detected here)")
    print("=" * 70)

    for ts in WORKING_TIMESTAMPS:
        frames = list(iter_frames_ffmpeg(str(VIDEO_PATH), start_time=ts, end_time=ts + 5, frame_interval=0.5))
        print(f"\nTimestamp {ts}s:")

        for frame_time, frame in frames[:5]:
            pc_x, pc_y, pc_w, pc_h = playclock_coords
            playclock_region = frame[pc_y : pc_y + pc_h, pc_x : pc_x + pc_w].copy()
            preprocessed = preprocess_playclock_region(playclock_region, reader.scale_factor)
            result = reader.read_from_fixed_location(frame, playclock_coords, padding=10)

            status = f"value={result.value}, conf={result.confidence:.2f}" if result.detected else f"NOT DETECTED (conf={result.confidence:.2f})"
            print(f"  t={frame_time:.1f}s: {status}")

            # Save comparison
            pc_scaled = cv2.resize(playclock_region, (pc_w * 10, pc_h * 10), interpolation=cv2.INTER_NEAREST)
            prep_bgr = cv2.cvtColor(preprocessed, cv2.COLOR_GRAY2BGR)
            prep_scaled = cv2.resize(prep_bgr, (pc_w * 10, pc_h * 10), interpolation=cv2.INTER_NEAREST)
            composite = np.vstack([pc_scaled, prep_scaled])
            cv2.imwrite(str(output_dir / f"working_{int(ts)}_{int(frame_time)}.png"), composite)

    print("\n" + "=" * 70)
    print("FAILING TIMESTAMPS (plays were NOT detected here)")
    print("=" * 70)

    for ts in FAILING_TIMESTAMPS:
        frames = list(iter_frames_ffmpeg(str(VIDEO_PATH), start_time=ts, end_time=ts + 5, frame_interval=0.5))
        print(f"\nTimestamp {ts}s:")

        for frame_time, frame in frames[:5]:
            pc_x, pc_y, pc_w, pc_h = playclock_coords
            playclock_region = frame[pc_y : pc_y + pc_h, pc_x : pc_x + pc_w].copy()
            preprocessed = preprocess_playclock_region(playclock_region, reader.scale_factor)
            result = reader.read_from_fixed_location(frame, playclock_coords, padding=10)

            status = f"value={result.value}, conf={result.confidence:.2f}" if result.detected else f"NOT DETECTED (conf={result.confidence:.2f})"
            print(f"  t={frame_time:.1f}s: {status}")

            # Save comparison
            pc_scaled = cv2.resize(playclock_region, (pc_w * 10, pc_h * 10), interpolation=cv2.INTER_NEAREST)
            prep_bgr = cv2.cvtColor(preprocessed, cv2.COLOR_GRAY2BGR)
            prep_scaled = cv2.resize(prep_bgr, (pc_w * 10, pc_h * 10), interpolation=cv2.INTER_NEAREST)
            composite = np.vstack([pc_scaled, prep_scaled])
            cv2.imwrite(str(output_dir / f"failing_{int(ts)}_{int(frame_time)}.png"), composite)

    print(f"\nSaved comparison images to: {output_dir}")


if __name__ == "__main__":
    main()