{"record":{"id":"20717bef49b84051","repo":"roboflow/supervision","slug":"expected-shape-h-w-h-w-3-or-h-w-4-got-im","errorCode":null,"errorMessage":"Expected shape (H,W), (H,W,3), or (H,W,4), got {image.shape}.","messagePattern":"Expected shape \\(H,W\\), \\(H,W,3\\), or \\(H,W,4\\), got (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/utils/conversion.py","lineNumber":235,"sourceCode":"        >>> from supervision.utils.conversion import cv2_to_pillow\n        >>> scene = np.zeros((10, 10, 3), dtype=np.uint8)\n        >>> scene[:, :, 2] = 255\n        >>> image = cv2_to_pillow(scene)\n        >>> image.size\n        (10, 10)\n        >>> image.getpixel((0, 0))\n        (255, 0, 0)\n\n        ```\n    \"\"\"\n    if image.ndim == 2:\n        return Image.fromarray(np.ascontiguousarray(image))\n    if image.ndim == 3 and image.shape[2] == 3:\n        rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        return Image.fromarray(rgb_image)\n    if image.ndim == 3 and image.shape[2] == 4:\n        return Image.fromarray(np.ascontiguousarray(image[..., [2, 1, 0, 3]]))\n    raise ValueError(f\"Expected shape (H,W), (H,W,3), or (H,W,4), got {image.shape}.\")\n","sourceCodeStart":217,"sourceCodeEnd":236,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/utils/conversion.py#L217-L236","documentation":"Raised by cv2_to_pillow() in supervision.utils.conversion when the input NumPy array is not a 2-D grayscale image, a 3-D 3-channel BGR image, or a 3-D 4-channel BGRA image. The function converts OpenCV-convention arrays to Pillow images, so any other rank or channel count has no defined conversion. The message echoes the offending shape so you can see exactly which dimension is wrong.","triggerScenarios":"Calling cv2_to_pillow(image) (or an annotator decorated with ensure_pil_image_for_* that routes through it) with an array of shape (H,W,2), (H,W,N) where N>4, (H,W,3,1) (extra batch axis), a 1-D flattened array, or a 0-D scalar. Also happens when you pass a stacked batch of frames (N,H,W,3) instead of a single frame.","commonSituations":"Feeding a batched model-output tensor converted to NumPy directly into a Pillow-based annotator; images loaded with unusual loaders that keep an extra dimension; grayscale images manually expanded to (H,W,1); sliced arrays like frame[None] passed by mistake.","solutions":["Squeeze spurious dimensions first: np.squeeze(image) or image[0] if you accidentally passed a batch.","If the image is (H,W,1) grayscale, reshape with image.reshape(image.shape[0], image.shape[1]).","If channels > 4 (e.g. multispectral data), slice to the first 3 or 4 channels: image[..., :3].","Print image.shape right before the call and verify it is exactly (H,W), (H,W,3), or (H,W,4)."],"exampleFix":"// before\nimg = model_output  # shape (1, 480, 640, 3)\npil = cv2_to_pillow(img)  # ValueError\n\n// after\nimg = np.squeeze(model_output)  # shape (480, 640, 3)\npil = cv2_to_pillow(img)","handlingStrategy":"validation","validationCode":"def is_valid_image_shape(image: np.ndarray) -> bool:\n    return image.ndim == 2 or (image.ndim == 3 and image.shape[2] in (3, 4))\n\nif not is_valid_image_shape(image):\n    image = np.squeeze(image)\n    if image.ndim == 3 and image.shape[2] == 1:\n        image = image[..., 0]\nassert is_valid_image_shape(image), image.shape","typeGuard":"from typing import TypeGuard\n\ndef is_convertible_image(image: object) -> TypeGuard[np.ndarray]:\n    return isinstance(image, np.ndarray) and (\n        image.ndim == 2 or (image.ndim == 3 and image.shape[2] in (3, 4))\n    )","tryCatchPattern":"try:\n    pil = cv2_to_pillow(image)\nexcept ValueError as e:\n    raise ValueError(f'Bad image for annotation: {image.shape}') from e","preventionTips":["Always print/check image.shape before image-format conversions in new pipelines.","Standardize on (H, W, 3) uint8 BGR frames at system boundaries.","Squeeze batch dimensions immediately after model inference."],"tags":["numpy","image-processing","shape-mismatch","pillow"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}