roboflow/supervision · error · ValueError
OBB data for each detection must have shape (4, 2), got {cor
Error message
OBB data for each detection must have shape (4, 2), got {corners.shape}. Ensure `detections.data['{ORIENTED_BOX_COORDINATES}']` has shape (N, 4, 2) before exporting. What it means
Raised during OBB YOLO export when the per-detection oriented corner array in data[ORIENTED_BOX_COORDINATES] does not have shape (4, 2). Each oriented box is defined by exactly 4 corner points with x,y coordinates; a wrong shape means the stored geometry is not a valid single OBB (e.g. a flattened array, wrong corner count, or the whole (N, 4, 2) batch stored per detection).
Source
Thrown at src/supervision/dataset/formats/yolo.py:398
UserWarning,
stacklevel=2,
)
annotation: list[str] = []
for xyxy, mask, _, class_id, _, data in detections:
if class_id is None:
raise ValueError("Class ID is required for YOLO annotations.")
if not isinstance(class_id, (int, np.integer)):
raise ValueError(
f"Detections class_id must be an integer for YOLO export, "
f"got {type(class_id)!r}."
)
class_id_int = int(class_id)
if is_obb:
corners = np.asarray(data[ORIENTED_BOX_COORDINATES], dtype=np.float32)
if corners.shape != (4, 2):
raise ValueError(
f"OBB data for each detection must have shape (4, 2), "
f"got {corners.shape}. Ensure "
f"`detections.data['{ORIENTED_BOX_COORDINATES}']` has "
"shape (N, 4, 2) before exporting."
)
next_object = object_to_yolo(
xyxy=xyxy,
class_id=class_id_int,
image_shape=image_shape,
polygon=corners,
)
annotation.append(next_object)
continue
if mask is not None:
polygons = approximate_mask_with_polygons(
mask=mask,
min_image_area_percentage=min_image_area_percentage,View on GitHub (pinned to 7f254d9784)
Solutions
- Reshape each detection's corners to exactly 4 rows of (x, y): corners.reshape(4, 2).
- If starting from rotated-rect parameters, convert with cv2.boxPoints(((cx,cy),(w,h),angle)) which returns (4, 2).
- Store the batch as one (N, 4, 2) array in detections.data; the loader indexes rows per detection.
- Print corners.shape in a small repro to confirm the fix.
Example fix
# before dets.data[sv.ORIENTED_BOX_COORDINATES] = flat_corners # shape (N, 8) # after import numpy as np N = len(dets) dets.data[sv.ORIENTED_BOX_COORDINATES] = flat_corners.reshape(N, 4, 2)
Defensive patterns
Strategy: validation
Validate before calling
import numpy as np
import supervision as sv
def obb_shapes_valid(detections) -> bool:
"""Check ORIENTED_BOX_COORDINATES is (N, 4, 2) with N matching detections."""
c = detections.data.get(sv.ORIENTED_BOX_COORDINATES)
return c is not None and c.shape == (len(detections), 4, 2) Try / catch
try:
lines = sv.detections_to_yolo_annotations(dets, image_shape=shape, is_obb=True)
except ValueError as e:
if 'must have shape (4, 2)' in str(e):
c = dets.data[sv.ORIENTED_BOX_COORDINATES]
dets.data[sv.ORIENTED_BOX_COORDINATES] = np.asarray(c).reshape(len(dets), 4, 2)
lines = sv.detections_to_yolo_annotations(dets, image_shape=shape, is_obb=True)
else:
raise Prevention
- Always store corners via cv2.boxPoints output reshaped to (N, 4, 2).
- Unit-test data shapes when building OBB Detections by hand.
- Keep the batch array intact in data; do not store per-detection slices.
When it happens
Trigger: sv.detections_to_yolo_annotations(..., is_obb=True) where detections.data[ORIENTED_BOX_COORDINATES] was set manually to e.g. an (8,) flat array, an (N, 4, 2) array incorrectly indexed, or an (4, 3) array.
Common situations: Hand-building OBB data from model output that returns flat 8-value OBB params (x,y,w,h,angle) instead of corners — forgetting cv2.boxPoints; reshaping errors; passing per-detection rows of a batch array without indexing.
Related errors
- `is_obb=True` requires `'{ORIENTED_BOX_COORDINATES}'` in `de
- Class ID is required for YOLO annotations.
- Detections class_id must be an integer for YOLO export, got
- Cannot export dataset: image paths {first_path} and {image_p
- Expected 'names' to be a list or dict in data.yaml at '{file
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/b68e6553b31aa5ed.
Report an issue: GitHub.