roboflow/supervision · error · ValueError

pixel_size must be >= 1, got {pixel_size}.

Error message

pixel_size must be >= 1, got {pixel_size}.

What it means

Raised by `PixelateAnnotator.__init__` when an explicit `pixel_size` smaller than 1 is passed. The pixelation grid must have at least one cell per axis; smaller values are rejected up front because OpenCV resize cannot form a valid grid. When unset, the size is derived dynamically from each box.

Source

Thrown at src/supervision/annotators/core.py:2462

        return scene


class PixelateAnnotator(BaseAnnotator):
    """
    A class for pixelating regions in an image using provided detections.
    """

    def __init__(self, pixel_size: int | None = None):
        """
        Args:
            pixel_size: The size of the pixelation. If not set, a dynamic size is
                computed as one-half of the shorter bounding-box dimension. When set
                and the detection area is smaller than `pixel_size`, the region is
                filled with its average colour instead to avoid an OpenCV crash.
                Must be >= 1 when provided.
        """
        if pixel_size is not None and pixel_size < 1:
            raise ValueError(f"pixel_size must be >= 1, got {pixel_size}.")
        self.pixel_size: int | None = pixel_size

    @ensure_cv2_image_for_class_method
    def annotate(
        self,
        scene: ImageType,
        detections: Detections,
    ) -> ImageType:
        """
        Annotates the given scene by pixelating regions based on the provided
            detections.

        Args:
            scene: The image where pixelating will be applied.
                `ImageType` is a flexible type, accepting either `numpy.ndarray`
                or `PIL.Image.Image`.
            detections: Object detections to annotate.

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Pass `pixel_size=None` for automatic per-box sizing.
  2. Clamp derived values: `pixel_size=max(1, int(value))`.
  3. If 0 is meant to disable pixelation, skip annotating that region entirely in your own code instead of passing 0.

Example fix

# before
annotator = sv.PixelateAnnotator(pixel_size=int(200 * 0.005))  # -> 1... for 100px -> 0
annotator = sv.PixelateAnnotator(pixel_size=0)  # ValueError

# after
size = max(1, int(smallest_side * 0.05))
annotator = sv.PixelateAnnotator(pixel_size=size)
Defensive patterns

Strategy: validation

Validate before calling

pixel_size = None if computed_size is None else max(1, int(computed_size))
annotator = sv.PixelateAnnotator(pixel_size=pixel_size)

Type guard

def is_valid_pixel_size(v) -> bool:
    return v is None or (isinstance(v, int) and v >= 1)

Prevention

When it happens

Trigger: Calling `sv.PixelateAnnotator(pixel_size=0)` or a negative value; deriving pixel size from box dimensions or a config scale where rounding yields 0 (e.g. `int(box_w * 0.01)` on a 50px box); None is accepted (dynamic sizing), so only explicit bad values raise.

Common situations: Auto-computed pixel sizes on small or distant detections flooring to zero; config-driven privacy-blur strength of 0 intended as 'off' but interpreted as a literal size; parameter sweeps in tests hitting 0.

Related errors


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