Spaces:
Runtime error
Runtime error
Zhen Ye Claude Opus 4.6 (1M context) commited on
Commit ·
a2f4d4e
1
Parent(s): c51e2e9
fix: handle degenerate bbox and unhandled exceptions in inspection frame endpoint
Browse filesCast bbox coordinates to int in crop_frame to prevent numpy float indexing errors.
Add error handling for ValueError/OSError in the /inspect/frame endpoint to return
422 instead of 500 when frame extraction or cropping fails.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- inspection/frames.py +1 -1
- inspection/router.py +16 -2
inspection/frames.py
CHANGED
|
@@ -77,7 +77,7 @@ def crop_frame(
|
|
| 77 |
Returns:
|
| 78 |
Cropped HxWx3 BGR numpy array.
|
| 79 |
"""
|
| 80 |
-
x1, y1, x2, y2 = bbox
|
| 81 |
if x2 <= x1 or y2 <= y1:
|
| 82 |
raise ValueError(
|
| 83 |
f"Invalid bbox: [{x1}, {y1}, {x2}, {y2}] — must have x2 > x1 and y2 > y1"
|
|
|
|
| 77 |
Returns:
|
| 78 |
Cropped HxWx3 BGR numpy array.
|
| 79 |
"""
|
| 80 |
+
x1, y1, x2, y2 = int(bbox[0]), int(bbox[1]), int(bbox[2]), int(bbox[3])
|
| 81 |
if x2 <= x1 or y2 <= y1:
|
| 82 |
raise ValueError(
|
| 83 |
f"Invalid bbox: [{x1}, {y1}, {x2}, {y2}] — must have x2 > x1 and y2 > y1"
|
inspection/router.py
CHANGED
|
@@ -99,7 +99,10 @@ async def get_frame(
|
|
| 99 |
_validate_frame_idx(input_path, frame_idx)
|
| 100 |
|
| 101 |
# Extract frame in thread pool (cv2 seek can block)
|
| 102 |
-
|
|
|
|
|
|
|
|
|
|
| 103 |
|
| 104 |
# Optionally crop to track bbox
|
| 105 |
if track_id is not None:
|
|
@@ -110,7 +113,18 @@ async def get_frame(
|
|
| 110 |
instance_id = _parse_track_id(track_id)
|
| 111 |
target = _find_track(tracks, instance_id, track_id)
|
| 112 |
if target and "bbox" in target:
|
| 113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
else:
|
| 115 |
raise HTTPException(
|
| 116 |
status_code=404,
|
|
|
|
| 99 |
_validate_frame_idx(input_path, frame_idx)
|
| 100 |
|
| 101 |
# Extract frame in thread pool (cv2 seek can block)
|
| 102 |
+
try:
|
| 103 |
+
frame = await asyncio.to_thread(extract_frame, input_path, frame_idx)
|
| 104 |
+
except (ValueError, OSError) as exc:
|
| 105 |
+
raise HTTPException(status_code=422, detail=str(exc))
|
| 106 |
|
| 107 |
# Optionally crop to track bbox
|
| 108 |
if track_id is not None:
|
|
|
|
| 113 |
instance_id = _parse_track_id(track_id)
|
| 114 |
target = _find_track(tracks, instance_id, track_id)
|
| 115 |
if target and "bbox" in target:
|
| 116 |
+
bbox = target["bbox"]
|
| 117 |
+
# Validate bbox is non-degenerate before cropping
|
| 118 |
+
x1, y1, x2, y2 = [int(c) for c in bbox]
|
| 119 |
+
if x2 <= x1 or y2 <= y1:
|
| 120 |
+
raise HTTPException(
|
| 121 |
+
status_code=422,
|
| 122 |
+
detail=f"Track {track_id} has a degenerate bbox [{x1},{y1},{x2},{y2}] at frame {frame_idx}.",
|
| 123 |
+
)
|
| 124 |
+
try:
|
| 125 |
+
frame = crop_frame(frame, [x1, y1, x2, y2], padding=padding)
|
| 126 |
+
except ValueError as exc:
|
| 127 |
+
raise HTTPException(status_code=422, detail=str(exc))
|
| 128 |
else:
|
| 129 |
raise HTTPException(
|
| 130 |
status_code=404,
|