roboflow/supervision · error · ValueError
Mean mask must match the image height and width
Error message
Mean mask must match the image height and width
What it means
Thrown by the fallback cv2.mean when a mask is supplied. The implementation selects pixels via boolean indexing (image[mask != 0]), which requires mask to be a 2D array exactly matching the image's (height, width). OpenCV has the same contract, but the fallback checks it explicitly.
Source
Thrown at src/supervision/_cv2/_image.py:116
) -> npt.NDArray[np.uint8]:
"""Scale, offset, take the absolute value, and saturate to uint8."""
values = np.abs(image.astype(np.float64) * alpha + beta)
return _cast_array_like_opencv(values, np.dtype(np.uint8))
def _mean(
image: npt.NDArray[Any], mask: npt.NDArray[Any] | None = None
) -> tuple[float, float, float, float]:
"""Return per-channel means using OpenCV's four-value result contract."""
if mask is None:
selected = (
image.reshape(-1, 1)
if image.ndim == 2
else image.reshape(-1, image.shape[2])
)
else:
if mask.shape != image.shape[:2]:
raise ValueError("Mean mask must match the image height and width")
selected = image[mask != 0]
if image.ndim == 2:
selected = selected.reshape(-1, 1)
if selected.size == 0:
means = np.zeros(4, dtype=np.float64)
else:
means = np.zeros(4, dtype=np.float64)
means[: selected.shape[1]] = np.mean(selected, axis=0)
return cast(
tuple[float, float, float, float],
tuple(float(value) for value in means),
)
def _resize(
src: npt.NDArray[Any],
dsize: tuple[int, int] | None,
fx: float = 0,View on GitHub (pinned to 7f254d9784)
Solutions
- Resize the mask to the image dimensions: mask = cv2.resize(mask, (image.shape[1], image.shape[0])).
- Squeeze extra dimensions: mask = mask.reshape(image.shape[:2]) or mask.squeeze().
- Compute the mask from the same frame you are measuring.
Example fix
# before mean = cv2.mean(frame, mask=seg_mask) # seg_mask from half-res frame # after seg_mask = cv2.resize(seg_mask, (frame.shape[1], frame.shape[0])) mean = cv2.mean(frame, mask=seg_mask)
Defensive patterns
Strategy: validation
Validate before calling
if mask is not None and mask.shape != image.shape[:2]:
mask = mask.reshape(image.shape[:2]) if mask.size == image.size else cv2.resize(mask, (image.shape[1], image.shape[0]))
mean = cv2.mean(image, mask=mask) Prevention
- Compute masks on the same frame being measured
- Keep masks 2D (H, W)
- Squeeze (H, W, 1) masks before use
When it happens
Trigger: Calling cv2.mean(image, mask=mask) where mask.shape != image.shape[:2] — e.g. a 3-channel mask, a mask from a differently-sized image, or a mask with an extra batch dimension.
Common situations: Reusing a mask computed on a resized/downscaled frame (common in segmentation pipelines), passing a (H, W, 1) mask where (H, W) is expected, or passing a full-shape mask for a 3-channel image.
Related errors
- addWeighted inputs must have equal shapes
- Video frame must have shape ({self._height}, {self._width},
- Contours must have shape (N, 2) or (N, 1, 2)
- xyxy must have shape (N, 4), where N matches the number of R
- the sum of the number of pixels in the RLE must be the same
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/e61ea7a1f293c9d3.
Report an issue: GitHub.