roboflow/supervision · error · TypeError
box coordinates must be real-valued
Error message
box coordinates must be real-valued
What it means
Raised by sv.box_iou when either bounding box contains complex-valued coordinates (np.iscomplexobj true). IoU is defined over real geometry, so complex inputs indicate an upstream data error and are rejected explicitly instead of producing nonsense values or a subtle NumPy cast.
Source
Thrown at src/supervision/detection/utils/iou_and_nms.py:150
ValueError: If `overlap_metric` is not IOU or IOS.
Examples:
```pycon
>>> import supervision as sv
>>> box_true = [100, 100, 200, 200]
>>> box_detection = [150, 150, 250, 250]
>>> sv.box_iou(box_true, box_detection, overlap_metric=sv.OverlapMetric.IOU)
0.142857...
>>> sv.box_iou(box_true, box_detection, overlap_metric=sv.OverlapMetric.IOS)
0.25
```
"""
overlap_metric = OverlapMetric.from_value(overlap_metric)
box_true_array = np.asarray(box_true)
box_detection_array = np.asarray(box_detection)
if np.iscomplexobj(box_true_array) or np.iscomplexobj(box_detection_array):
raise TypeError("box coordinates must be real-valued")
x_min_true, y_min_true, x_max_true, y_max_true = box_true_array
x_min_det, y_min_det, x_max_det, y_max_det = box_detection_array
x_min_inter = max(x_min_true, x_min_det)
y_min_inter = max(y_min_true, y_min_det)
x_max_inter = min(x_max_true, x_max_det)
y_max_inter = min(y_max_true, y_max_det)
inter_w = max(0.0, _coordinate_difference(x_max_inter, x_min_inter))
inter_h = max(0.0, _coordinate_difference(y_max_inter, y_min_inter))
area_inter = inter_w * inter_h
area_true = _coordinate_difference(x_max_true, x_min_true) * _coordinate_difference(
y_max_true, y_min_true
)
area_det = _coordinate_difference(x_max_det, x_min_det) * _coordinate_difference(View on GitHub (pinned to 7f254d9784)
Solutions
- Take the real part before calling: boxes = np.real(np.asarray(boxes))
- Fix the upstream step that produced complex coordinates if complex values are unexpected
- If complex tensors come from PyTorch, convert with .real before turning into numpy
Example fix
# before iou = sv.box_iou(np.array([0,0,10,10], dtype=complex), [5,5,15,15]) # after iou = sv.box_iou(np.real(np.array([0,0,10,10])), [5,5,15,15])
Defensive patterns
Strategy: type-guard
Validate before calling
import numpy as np
def as_real_boxes(boxes):
arr = np.asarray(boxes)
if np.iscomplexobj(arr):
arr = np.real(arr)
return arr Type guard
def is_real_valued_boxes(boxes) -> bool:
import numpy as np
return not np.iscomplexobj(np.asarray(boxes)) Prevention
- Call np.real on arrays coming from FFT/frequency-domain code before geometry ops
- Avoid dtype=complex defaults when allocating coordinate arrays
- Add a dtype assertion (arr.dtype.kind == 'f' or 'i') in data-loading code
When it happens
Trigger: sv.box_iou(box_true, box_detection) where either argument is a complex dtype array, e.g. boxes produced by an FFT-based pipeline, complex-valued model outputs, or accidental dtype propagation (np.zeros(4, dtype=complex) defaults).
Common situations: Signal-processing or frequency-domain preprocessing leaking complex dtype into downstream box code; loading boxes from a complex-typed tensor (torch.complex) without conversion; a bug that mixes complex intermediates into coordinate arrays.
Related errors
- Detection annotation for image {image_path} contains non-int
- `is_crowd` length ({len(is_crowd)}) must match `boxes_true`
- masks_true and masks_detection must be 3D (N, H, W); got ndi
- `{name}` has shape {arr.shape}; expected (N, 4, 2) — each bo
- `{name}` has shape {arr.shape}; expected (N, 8) for flat YOL
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/31f88fcd06b0afd0.
Report an issue: GitHub.