roboflow/supervision · error · ValueError

Only CHAIN_APPROX_SIMPLE is supported by the fallback

Error message

Only CHAIN_APPROX_SIMPLE is supported by the fallback

What it means

The fallback `findContours` in src/supervision/_cv2/_contours.py:147 only implements `CHAIN_APPROX_SIMPLE` (which compresses straight runs into endpoints); it rejects `CHAIN_APPROX_NONE` and other approximation methods because the fallback's `_compress_contour` stage always produces SIMPLE-style output and emulating the others would diverge silently.

Source

Thrown at src/supervision/_cv2/_contours.py:147

        following = contour[(index + 1) % len(contour)] - point
        if (
            np.any(previous)
            and np.any(following)
            and np.array_equal(np.sign(previous), np.sign(following))
        ):
            continue
        keep.append(point)
    return np.asarray(keep, dtype=np.int32)


def _find_contours(
    image: npt.NDArray[Any], mode: int, method: int
) -> tuple[list[npt.NDArray[np.int32]], npt.NDArray[np.int32] | None]:
    """Find contours for the supported tree and SIMPLE modes."""
    if mode != _RETR_TREE:
        raise ValueError("Only RETR_TREE is supported by the fallback")
    if method != _CHAIN_APPROX_SIMPLE:
        raise ValueError("Only CHAIN_APPROX_SIMPLE is supported by the fallback")
    values = np.asarray(image)
    if values.ndim != 2:
        raise ValueError("Contour input must be a two-dimensional image")
    traced = [_compress_contour(contour) for contour in _trace_borders(values != 0)]
    if not traced:
        return [], None
    return [contour.reshape(-1, 1, 2) for contour in traced], None

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Use `method=cv2.CHAIN_APPROX_SIMPLE` and accept compressed contours (they define the same polygons)
  2. If you truly need all boundary points, densify SIMPLE contours afterwards (e.g. interpolate along segments) or install `opencv-python`
  3. Check `supervision._cv2.BACKEND_NAME` at startup and route to a real cv2 install when the fallback lacks features you use

Example fix

// before
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

// after
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
Defensive patterns

Strategy: fallback

Validate before calling

from supervision._cv2 import BACKEND_NAME

SUPPORTED_METHOD = {"CHAIN_APPROX_SIMPLE"}

def assert_method_supported(method_name: str) -> None:
    """Fail fast when a chain approximation method is unavailable on the fallback."""
    if BACKEND_NAME != "opencv" and method_name not in SUPPORTED_METHOD:
        raise ValueError(f"contour method {method_name} needs opencv-python installed")

Prevention

When it happens

Trigger: Calling `cv2.findContours` with `method=cv2.CHAIN_APPROX_NONE` (all boundary points) on the fallback backend; passing any approximation flag other than CHAIN_APPROX_SIMPLE.

Common situations: Code that needs every boundary pixel (e.g. precise perimeter sampling) written against real OpenCV, then executed where opencv-python is absent.

Related errors


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