roboflow/supervision · error · TypeError

image must be uint8, got

Error message

image must be uint8, got {image.dtype}. Convert with image.astype(np.uint8) before calling show().

What it means

Raised by ImageWindow.show() in supervision.utils.image_window when the input array's dtype is not np.uint8. The Tk-based display path converts the array straight to a Pillow image, which requires 8-bit data; float arrays (common after model preprocessing) would render as garbage or fail inside Pillow, so the dtype is checked up front with an actionable message.

Solutions

  1. Scale floats back to range then cast: (img * 255).clip(0, 255).astype(np.uint8).
  2. For arbitrary floats use cv2.normalize(img, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8).
  3. Convert integer types directly: img.astype(np.uint8) only if values already span 0-255.
  4. Keep a uint8 copy of the original frame for display alongside the float working copy.

Example fix

// before
window.show(frame / 255.0)  # float64 -> TypeError

// after
window.show((frame / 255.0 * 255).clip(0, 255).astype(np.uint8))
Defensive patterns

Strategy: type-guard

Validate before calling

def ensure_uint8(img: np.ndarray) -> np.ndarray:
    if img.dtype == np.uint8:
        return img
    if np.issubdtype(img.dtype, np.floating):
        return (img * 255 if img.max() <= 1.0 else img).clip(0, 255).astype(np.uint8)
    return img.astype(np.uint8)

window.show(ensure_uint8(image))

Type guard

def is_uint8_image(image: np.ndarray) -> bool:
    return image.dtype == np.uint8

Prevention

When it happens

Trigger: Calling window.show(image) with a float32/float64 array (e.g. normalized 0-1 images, model outputs, cv2.resize on floats); uint16 medical/scientific imagery; boolean masks.

Common situations: Displaying frames that went through normalization (image / 255.0); annotator outputs assumed to stay uint8 but a preprocessing step cast them; stacking with np.mean producing float; feeding depth maps.

Related errors


AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15). Data as JSON: /api/errors/6b7a24740f19da1e. Report an issue: GitHub.

Appendix: source

Thrown at src/supervision/utils/image_window.py:108

    def show(self, image: npt.NDArray[np.uint8]) -> None:
        """Display a BGR, grayscale, or BGRA frame in the window.

        The image is scaled to fit the current window dimensions. Aspect ratio is
        preserved unless `keep_aspect_ratio=False`. Resizing the window rescales live.
        Args:
            image: uint8 numpy array. Accepted shapes:
                - ``(H, W)`` — grayscale
                - ``(H, W, 3)`` — BGR (OpenCV convention; channels are swapped
                  to RGB before display)
                - ``(H, W, 4)`` — BGRA (channels reordered to RGBA)

        Raises:
            TypeError: If `image.dtype` is not `uint8`.
            ValueError: If `image` is not 2-D or 3-D with 3 or 4 channels.
        """
        if image.dtype != np.uint8:
            raise TypeError(
                f"image must be uint8, got {image.dtype}. "
                "Convert with image.astype(np.uint8) before calling show()."
            )
        self._pil_image = _bgr_to_pil(image)
        self._ensure_window()
        self._update_display()
        self._root.update_idletasks()
        self._root.update()

    def wait_key(self, delay_ms: int = 0) -> str | None:
        """Wait for a keypress and return its name.

        Args:
            delay_ms: How long to wait in milliseconds. ``0`` blocks until a
                key is pressed. Positive values poll for up to `delay_ms` ms
                and return ``None`` if no key arrives in time.

        Returns:

View on GitHub (pinned to 7f254d9784)