cfb40 / scripts /test_frame_alignment.py
andytaylor-smg's picture
some decent progress generalizing
137c6cf
#!/usr/bin/env python3
"""Test frame alignment between different FFmpeg extraction methods."""
import sys
import logging
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent))
import json
import numpy as np
from src.video.ffmpeg_reader import FFmpegFrameReader
from src.readers.flags import FlagReader
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)
def test_frame_at_timestamp(video_path: str, target_time: float, flag_reader: FlagReader, scorebug_x: int, scorebug_y: int):
"""Extract and test a specific frame."""
# Calculate absolute flag region
x = scorebug_x + flag_reader.flag_x_offset
y = scorebug_y + flag_reader.flag_y_offset
w = flag_reader.flag_width
h = flag_reader.flag_height
with FFmpegFrameReader(video_path, target_time, target_time + 0.5, 0.5) as reader:
for timestamp, frame in reader:
result = flag_reader.read_from_fixed_location(frame, (x, y, w, h))
yellow_pct = result.yellow_ratio * 100
logger.info(f" t={timestamp:.1f}s: yellow={yellow_pct:.1f}%, hue={result.mean_hue:.1f}, detected={result.detected}")
return timestamp, yellow_pct, result.mean_hue
return None, 0, 0
def main():
video_path = "/Users/andytaylor/Documents/Personal/cfb40/full_videos/OSU vs Tenn 12.21.24.mkv"
# Load session config
with open("output/OSU_vs_Tenn_12_21_24_config.json", "r") as f:
config = json.load(f)
# Create flag reader
flag_reader = FlagReader(
flag_x_offset=config["flag_x_offset"],
flag_y_offset=config["flag_y_offset"],
flag_width=config["flag_width"],
flag_height=config["flag_height"],
)
scorebug_x = config["scorebug_x"]
scorebug_y = config["scorebug_y"]
logger.info("=" * 80)
logger.info("FRAME ALIGNMENT TEST")
logger.info(f"Flag region: offset=({flag_reader.flag_x_offset}, {flag_reader.flag_y_offset})")
logger.info("=" * 80)
# Test 1: Extract frame at 340.5s directly (like diagnostic)
logger.info("\nTest 1: Extract frame at 340.5s directly (start_time=340.5)")
test_frame_at_timestamp(video_path, 340.5, flag_reader, scorebug_x, scorebug_y)
# Test 2: Extract frame 681 from start (like pipeline chunk 0)
logger.info("\nTest 2: Extract from start and iterate to frame 681 (340.5s)")
frame_count = 0
target_frame = 681 # 340.5 / 0.5 = 681
# Only extract 5 frames around the target to save time
start_time = (target_frame - 2) * 0.5 # 339.5s
end_time = (target_frame + 3) * 0.5 # 342.0s
x = scorebug_x + flag_reader.flag_x_offset
y = scorebug_y + flag_reader.flag_y_offset
w = flag_reader.flag_width
h = flag_reader.flag_height
with FFmpegFrameReader(video_path, start_time, end_time, 0.5) as reader:
for timestamp, frame in reader:
result = flag_reader.read_from_fixed_location(frame, (x, y, w, h))
yellow_pct = result.yellow_ratio * 100
logger.info(f" t={timestamp:.1f}s: yellow={yellow_pct:.1f}%, hue={result.mean_hue:.1f}, detected={result.detected}")
# Test 3: Extract from time 0 and iterate to 340.5s (exactly like pipeline)
# This would take too long, so let's just test the first few frames to see if there's a pattern
logger.info("\nTest 3: Extract first 10 frames from time 0 (like pipeline chunk 0)")
with FFmpegFrameReader(video_path, 0.0, 5.0, 0.5) as reader:
for timestamp, frame in reader:
# Just print frame info, no flag detection (not expected at start of video)
logger.info(f" t={timestamp:.1f}s: frame shape={frame.shape}")
logger.info("\n" + "=" * 80)
logger.info("CONCLUSION: If Test 1 and Test 2 show same results, frame alignment is correct")
logger.info("=" * 80)
if __name__ == "__main__":
main()