Spaces:
Runtime error
Runtime error
| import numpy as np | |
| import pytest | |
| def test_extract_frame_returns_bgr_array(tmp_path): | |
| """extract_frame should return an HxWx3 BGR numpy array.""" | |
| from inspection.frames import extract_frame | |
| # Create a tiny test video (10 frames, 64x48) | |
| import cv2 | |
| video_path = str(tmp_path / "test.mp4") | |
| writer = cv2.VideoWriter( | |
| video_path, cv2.VideoWriter_fourcc(*"mp4v"), 30, (64, 48) | |
| ) | |
| for i in range(10): | |
| frame = np.full((48, 64, 3), i * 25, dtype=np.uint8) | |
| writer.write(frame) | |
| writer.release() | |
| frame = extract_frame(video_path, 0) | |
| assert isinstance(frame, np.ndarray) | |
| assert frame.shape == (48, 64, 3) | |
| assert frame.dtype == np.uint8 | |
| def test_extract_frame_different_indices(tmp_path): | |
| """Different frame indices should return different pixel data.""" | |
| from inspection.frames import extract_frame | |
| import cv2 | |
| video_path = str(tmp_path / "test.mp4") | |
| writer = cv2.VideoWriter( | |
| video_path, cv2.VideoWriter_fourcc(*"mp4v"), 30, (64, 48) | |
| ) | |
| for i in range(10): | |
| frame = np.full((48, 64, 3), i * 25, dtype=np.uint8) | |
| writer.write(frame) | |
| writer.release() | |
| f0 = extract_frame(video_path, 0) | |
| f5 = extract_frame(video_path, 5) | |
| assert not np.array_equal(f0, f5) | |
| def test_extract_frame_out_of_range(tmp_path): | |
| """Out-of-range frame index should raise ValueError.""" | |
| from inspection.frames import extract_frame | |
| import cv2 | |
| video_path = str(tmp_path / "test.mp4") | |
| writer = cv2.VideoWriter( | |
| video_path, cv2.VideoWriter_fourcc(*"mp4v"), 30, (64, 48) | |
| ) | |
| for i in range(10): | |
| writer.write(np.zeros((48, 64, 3), dtype=np.uint8)) | |
| writer.release() | |
| with pytest.raises(ValueError, match="out of range"): | |
| extract_frame(video_path, 999) | |
| def test_crop_frame_to_bbox(): | |
| """crop_frame should extract the bbox region with padding.""" | |
| from inspection.frames import crop_frame | |
| frame = np.zeros((200, 300, 3), dtype=np.uint8) | |
| # Fill a known region with white | |
| frame[50:100, 80:180] = 255 | |
| bbox = [80, 50, 180, 100] # x1, y1, x2, y2 | |
| crop = crop_frame(frame, bbox, padding=0.0) | |
| assert crop.shape == (50, 100, 3) | |
| assert np.all(crop == 255) | |
| def test_crop_frame_with_padding(): | |
| """Padding should expand the crop region, clamped to frame bounds.""" | |
| from inspection.frames import crop_frame | |
| frame = np.zeros((200, 300, 3), dtype=np.uint8) | |
| bbox = [100, 50, 200, 150] # 100x100 box | |
| crop = crop_frame(frame, bbox, padding=0.5) | |
| # 50% padding on a 100x100 box = 50px each side | |
| # Expected: x=[50,250], y=[0,200] (clamped) | |
| assert crop.shape[0] > 100 | |
| assert crop.shape[1] > 100 | |
| def test_crop_frame_clamped_to_bounds(): | |
| """Padding that exceeds frame bounds should be clamped.""" | |
| from inspection.frames import crop_frame | |
| frame = np.zeros((100, 100, 3), dtype=np.uint8) | |
| bbox = [0, 0, 100, 100] | |
| crop = crop_frame(frame, bbox, padding=1.0) | |
| # Should not exceed original frame dimensions | |
| assert crop.shape[0] <= 100 | |
| assert crop.shape[1] <= 100 | |