roboflow/supervision · error · ValueError

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

Error message

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

What it means

Raised by `BlurAnnotator.__init__` when an explicit `kernel_size` smaller than 1 is passed. The kernel drives OpenCV average pooling; a zero or negative size is invalid for OpenCV and meaningless for blurring, so it is rejected at construction time rather than crashing later inside cv2.

Source

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

        return _load_icon_from_path(
            icon_path=icon_path, icon_resolution_wh=self.icon_resolution_wh
        )


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

    def __init__(self, kernel_size: int | None = None):
        """
        Args:
            kernel_size: The size of the average pooling kernel used for blurring.
                If not set, a dynamic size is computed as one-third of the shorter
                bounding-box dimension. Must be >= 1 when provided.
        """
        if kernel_size is not None and kernel_size < 1:
            raise ValueError(f"kernel_size must be >= 1, got {kernel_size}.")
        self.kernel_size: int | None = kernel_size

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

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

        Returns:

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Pass `kernel_size=None` to let the annotator compute a dynamic size from each box.
  2. Use `kernel_size=max(1, computed_value)` when deriving the size from measurements.
  3. Fix the config value to a positive odd/positive integer such as 15 or 25.

Example fix

# before
kernel = int(min(w, h) * 0.05)  # tiny box -> 0
annotator = sv.BlurAnnotator(kernel_size=kernel)  # ValueError

# after
kernel = max(1, int(min(w, h) * 0.05))
annotator = sv.BlurAnnotator(kernel_size=kernel if kernel > 0 else None)
Defensive patterns

Strategy: validation

Validate before calling

kernel_size = None if computed_size is None else max(1, int(computed_size))
annotator = sv.BlurAnnotator(kernel_size=kernel_size)

Type guard

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

Prevention

When it happens

Trigger: Calling `sv.BlurAnnotator(kernel_size=0)` or `kernel_size=-3`; computing kernel size from a config or box dimension as `int(smallest_side * ratio)` where rounding or a small ratio yields 0; passing None is fine (dynamic sizing) — only explicit values < 1 raise.

Common situations: Auto-tuned blur strength from image dimensions that floors to 0 for tiny images; config files with a missing/zero blur setting; unit tests sweeping parameter values including 0.

Related errors


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