roboflow/supervision · error · ValueError

Only 4- and 8-connectivity are supported

Error message

Only 4- and 8-connectivity are supported

What it means

OpenCV's connectedComponents supports only 4-connectivity (edge adjacency) and 8-connectivity (edge + corner adjacency). The fallback maps these to scipy binary structures of rank 1 and 2; any other value (0, 2, 16, etc.) has no defined structure and raises ValueError.

Source

Thrown at src/supervision/_cv2/_components.py:24

import numpy as np
import numpy.typing as npt


def _validate_binary_image(image: npt.NDArray[Any]) -> npt.NDArray[np.bool_]:
    """Validate and normalize a two-dimensional component image."""
    values = np.asarray(image)
    if values.ndim != 2:
        raise ValueError("Connected-component input must be a two-dimensional image")
    return cast(npt.NDArray[np.bool_], values != 0)


def _label(
    image: npt.NDArray[Any], connectivity: int
) -> tuple[int, npt.NDArray[np.int32]]:
    """Label foreground pixels with the requested four- or eight-way topology."""
    if connectivity not in (4, 8):
        raise ValueError("Only 4- and 8-connectivity are supported")

    from scipy import ndimage

    structure = ndimage.generate_binary_structure(2, 1 if connectivity == 4 else 2)
    labels, count = ndimage.label(_validate_binary_image(image), structure=structure)
    return int(count), np.ascontiguousarray(labels, dtype=np.int32)


def _connected_components(
    image: npt.NDArray[Any],
    labels: npt.NDArray[Any] | None = None,
    connectivity: int = 8,
    ltype: int = 4,
) -> tuple[int, npt.NDArray[np.int32]]:
    """Return OpenCV-shaped connected-component labels and their count."""
    del ltype
    count, result = _label(image, connectivity)
    if labels is not None and labels.shape == result.shape and labels.dtype == np.int32:

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Pass connectivity=4 or connectivity=8 explicitly.
  2. Validate config-supplied connectivity against (4, 8) at load time with a clear error.
  3. Default to 8 when the parameter is optional in your own API.

Example fix

# before
count, labels = cv2.connectedComponents(mask, connectivity=cfg.connectivity)  # may be 0

# after
if cfg.connectivity not in (4, 8):
    raise ValueError(f'connectivity must be 4 or 8, got {cfg.connectivity}')
count, labels = cv2.connectedComponents(mask, connectivity=cfg.connectivity)
Defensive patterns

Strategy: validation

Validate before calling

if connectivity not in (4, 8):
    connectivity = 8
count, labels = cv2.connectedComponents(mask, connectivity=connectivity)

Prevention

When it happens

Trigger: Calling cv2.connectedComponents(mask, connectivity=x) with x not in {4, 8} — e.g. 0 from an unset variable, or mistaken values like 2.

Common situations: Config parameters defaulting to 0/None and passed through unvalidated; developers guessing connectivity values; constants copied from a different library's API.

Related errors


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