roboflow/supervision · error · TypeError
Unsupported image type: {type(scene)}
Error message
Unsupported image type: {type(scene)} What it means
Raised by the ensure_cv2_image_for_class_method decorator's wrapper in supervision.utils.conversion when the `scene` argument passed to an annotator's annotate() method is neither a np.ndarray nor a PIL.Image.Image. The decorator transparently converts PIL scenes to BGR NumPy arrays, runs the annotator, and pastes the result back; any other type cannot be handled.
Source
Thrown at src/supervision/utils/conversion.py:41
Assumes the annotators modify the scene in-place.
Raises:
TypeError: If `scene` is not a `numpy.ndarray` or `PIL.Image.Image`.
"""
@functools.wraps(annotate_func)
def wrapper(self: Any, scene: ImageType, *args: Any, **kwargs: Any) -> Any:
if isinstance(scene, np.ndarray):
return annotate_func(self, scene, *args, **kwargs)
if isinstance(scene, Image.Image):
scene_np = pillow_to_cv2(scene)
annotated_np = annotate_func(self, scene_np, *args, **kwargs)
scene.paste(cv2_to_pillow(annotated_np))
return scene
raise TypeError(f"Unsupported image type: {type(scene)}")
return cast(F, wrapper)
@deprecated( # type: ignore[untyped-decorator]
target=ensure_cv2_image_for_class_method,
deprecated_in="0.27.0",
remove_in="0.31.0",
)
def ensure_cv2_image_for_annotation(
annotate_func: F,
) -> F:
return cast(F, void(annotate_func))
def ensure_cv2_image_for_standalone_function(
image_processing_fun: F,
) -> F:View on GitHub (pinned to 7f254d9784)
Solutions
- Convert tensors to NumPy: scene = tensor.cpu().numpy() before annotate().
- If you have a path, load it first: scene = cv2.imread(path).
- Convert other image objects to a PIL Image or np.ndarray (e.g. np.asarray(qimage)).
- Check for None — a failed upstream load (cv2.imread returning None) flows into annotate().
Example fix
// before frame = model.predict_source(...) # torch.Tensor annotated = annotator.annotate(frame, detections) # TypeError // after frame = frame.cpu().numpy() annotated = annotator.annotate(frame, detections)
Defensive patterns
Strategy: type-guard
Validate before calling
if not isinstance(scene, (np.ndarray, Image.Image)):
if hasattr(scene, 'cpu') and hasattr(scene, 'numpy'):
scene = scene.cpu().numpy()
else:
scene = np.asarray(scene)
assert isinstance(scene, (np.ndarray, Image.Image)) Type guard
ImageType = Union[np.ndarray, Image.Image]
def is_annotatable(scene: object) -> TypeGuard[ImageType]:
return isinstance(scene, (np.ndarray, Image.Image)) Try / catch
try:
annotator.annotate(scene, detections)
except TypeError as e:
if 'Unsupported image type' in str(e):
raise TypeError(f'Convert {type(scene)} to np.ndarray first') from e
raise Prevention
- Convert model tensors to NumPy at the pipeline boundary, once.
- Load images with cv2.imread/PIL.open and check for None before annotating.
- Type-annotate your own pipeline functions as np.ndarray so mypy catches bad flows.
When it happens
Trigger: Calling an annotator method like box_annotator.annotate(scene, detections) with scene as a torch.Tensor, a cv2.VideoCapture frame object, a file path string, a matplotlib figure, or None.
Common situations: Passing a PyTorch tensor straight from a model without calling .cpu().numpy(); passing an image path instead of a loaded array; passing a QImage or other GUI-framework image type; reusing old code where scene was previously accepted in another format.
Related errors
- Unsupported image type: {type(image)}
- `image` must be a numpy.ndarray or PIL.Image.Image. Received
- `image` must be a numpy.ndarray or PIL.Image.Image. Received
- Expected shape (H,W), (H,W,3), or (H,W,4), got {image.shape}
- custom_values must be either a numpy array or a list of floa
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/262735bd4e184a42.
Report an issue: GitHub.