roboflow/supervision · error · TypeError
`image` must be a numpy.ndarray or PIL.Image.Image. Received
Error message
`image` must be a numpy.ndarray or PIL.Image.Image. Received {type(image)} What it means
Raised by `sv.crop_image` when the `image` argument is neither a `numpy.ndarray` nor a `PIL.Image.Image`. The function dispatches on these two types (each has a different crop path) and has no behavior for anything else, so it fails fast with a TypeError naming the received type.
Source
Thrown at src/supervision/utils/image.py:223
x_min, y_min, x_max, y_max = xyxy_arr.flatten()
if isinstance(image, np.ndarray):
height, width = image.shape[:2]
x_min = int(np.clip(x_min, 0, width))
y_min = int(np.clip(y_min, 0, height))
x_max = int(np.clip(x_max, 0, width))
y_max = int(np.clip(y_max, 0, height))
return image[y_min:y_max, x_min:x_max]
if isinstance(image, Image.Image):
width, height = image.size
x_min = int(np.clip(x_min, 0, width))
y_min = int(np.clip(y_min, 0, height))
x_max = int(np.clip(x_max, 0, width))
y_max = int(np.clip(y_max, 0, height))
return image.crop((float(x_min), float(y_min), float(x_max), float(y_max)))
raise TypeError(
f"`image` must be a numpy.ndarray or PIL.Image.Image. Received {type(image)}"
)
@ensure_cv2_image_for_standalone_function
def scale_image(image: ImageType, scale_factor: float) -> ImageType:
"""
Scale image by given factor. Scale factor > 1.0 zooms in, < 1.0 zooms out.
Args:
image: The image to scale.
scale_factor: Factor by which to scale the image.
Returns:
Scaled image matching input
type.
Raises:View on GitHub (pinned to 7f254d9784)
Solutions
- Convert tensors: `image.detach().cpu().numpy()` before cropping.
- Load paths first: `cv2.imread(path)` or `PIL.Image.open(path)`.
- Decode bytes with `cv2.imdecode(np.frombuffer(data, np.uint8), cv2.IMREAD_COLOR)`.
Example fix
# before
crop = sv.crop_image(image='/data/frame.jpg', xyxy=box)
# after
import cv2
crop = sv.crop_image(image=cv2.imread('/data/frame.jpg'), xyxy=box) Defensive patterns
Strategy: type-guard
Validate before calling
assert isinstance(image, (np.ndarray, Image.Image)), type(image)
Type guard
from PIL import Image
import numpy as np
def is_image(x: Any) -> bool:
return isinstance(x, (np.ndarray, Image.Image)) Try / catch
try:
crop = sv.crop_image(image, xyxy)
except TypeError as e:
raise TypeError(f'load the image first: {e}') from e Prevention
- Keep one canonical loaded representation (ndarray BGR) through the pipeline.
- Convert tensors with .detach().cpu().numpy() at model boundaries.
- Never pass paths or raw bytes to image utilities.
When it happens
Trigger: Passing a file path string, a `torch.Tensor`, a `cv2.VideoCapture` frame proxy, or bytes to `sv.crop_image(image=..., xyxy=...)`.
Common situations: Loading with PIL/opencv elsewhere but passing the path by mistake; deep-learning pipelines handing raw tensors to a utility that expects numpy; reading bytes from an HTTP response without decoding first via `sv.load_image_from_url`/`cv2.imdecode`.
Related errors
- `image` must be a numpy.ndarray or PIL.Image.Image. Received
- NumPy image must have at least 2 dimensions (H, W, ...). Rec
- Expected shape (H,W), (H,W,3), or (H,W,4), got {image.shape}
- Unsupported image type: {type(scene)}
- Unsupported image type: {type(image)}
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/58e2ec755546ff60.
Report an issue: GitHub.