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