Spaces:
Sleeping
Sleeping
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()
|