lllyasviel/Fooocus · error · ValueError
Input size must have a shape of (*, 3, H, W). Got {image.sha
Error message
Input size must have a shape of (*, 3, H, W). Got {image.shape} What it means
Kornia's rgb_to_grayscale (vendored into external_canny.py) validates that the last-but-two dimension is exactly 3 (RGB channels) and that the tensor is at least 3-D. Any other layout — channel-first grayscale, channel-last HWC, or 4-channel RGBA — fails this shape contract. This mirrors Kornia's strict (*,3,H,W) convention.
Source
Thrown at ldm_patched/contrib/external_canny.py:132
Args:
image: RGB image to be converted to grayscale with shape :math:`(*,3,H,W)`.
rgb_weights: Weights that will be applied on each channel (RGB).
The sum of the weights should add up to one.
Returns:
grayscale version of the image with shape :math:`(*,1,H,W)`.
.. note::
See a working example `here <https://kornia.readthedocs.io/en/latest/
color_conversions.html>`__.
Example:
>>> input = torch.rand(2, 3, 4, 5)
>>> gray = rgb_to_grayscale(input) # 2x1x4x5
"""
if len(image.shape) < 3 or image.shape[-3] != 3:
raise ValueError(f"Input size must have a shape of (*, 3, H, W). Got {image.shape}")
if rgb_weights is None:
# 8 bit images
if image.dtype == torch.uint8:
rgb_weights = torch.tensor([76, 150, 29], device=image.device, dtype=torch.uint8)
# floating point images
elif image.dtype in (torch.float16, torch.float32, torch.float64):
rgb_weights = torch.tensor([0.299, 0.587, 0.114], device=image.device, dtype=image.dtype)
else:
raise TypeError(f"Unknown data type: {image.dtype}")
else:
# is tensor that we make sure is in the same device/dtype
rgb_weights = rgb_weights.to(image)
# unpack the color image channels with RGB order
r: Tensor = image[..., 0:1, :, :]
g: Tensor = image[..., 1:2, :, :]
b: Tensor = image[..., 2:3, :, :]View on GitHub (pinned to ae05379cc9)
Solutions
- Permute HWC to CHW: img = torch.from_numpy(img).permute(2, 0, 1) and add a batch dim: img[None].
- If image is RGBA, drop alpha first: img = img[..., :3].
- If image is already grayscale, replicate to 3 channels: img = gray.repeat(1, 3, 1, 1).
- Let the node's own loader handle conversion where available (it expects IMAGE in (B,H,W,3) and converts internally); avoid double-converting.
Example fix
# before img = torch.from_numpy(cv2.imread(p)) # HxWx3 grey = rgb_to_grayscale(img) # ValueError # after img = torch.from_numpy(cv2.imread(p)).permute(2, 0, 1).unsqueeze(0).float() / 255. # 1x3xHxW grey = rgb_to_grayscale(img)
Defensive patterns
Strategy: type-guard
Validate before calling
def to_chw(img: torch.Tensor) -> torch.Tensor:
if img.shape[-1] in (1, 3) and (img.ndim < 3 or img.shape[-3] not in (1, 3)):
img = img.permute(*range(img.ndim - 3), img.ndim - 1, img.ndim - 3, img.ndim - 2) # HWC->CHW
if img.shape[-3] == 1:
img = img.repeat_interleave(3, dim=-3)
if img.shape[-3] == 4:
img = img[..., :3, :, :]
assert img.shape[-3] == 3, f'expected (*,3,H,W), got {tuple(img.shape)}'
return img Type guard
def is_rgb_chw(t: torch.Tensor) -> bool:
return t.ndim >= 3 and t.shape[-3] == 3 Try / catch
try:
gray = rgb_to_grayscale(img)
except ValueError as e:
if 'shape of (*, 3, H, W)' in str(e):
gray = rgb_to_grayscale(to_chw(img))
else:
raise Prevention
- Standardize on CHW float tensors at your pipeline entry; convert once after cv2/PIL load.
- Add shape assertions before Kornia-style color ops.
- Drop alpha channels and expand grayscale at load time, not downstream.
When it happens
Trigger: Feeding the Canny node an image tensor of shape (1,1,H,W), (H,W,3), (B,H,W,3), or (B,4,H,W); i.e. forgetting to permute HWC->CHW after decoding, or passing an already-grayscale/alpha image.
Common situations: Loading with PIL/opencv (HWC uint8) and converting to torch without permute(2,0,1); VAE-decoded latents or masks (1-channel) routed into the Canny preprocessor; RGBA exports from image editors.
Related errors
AI-assisted analysis of lllyasviel/Fooocus@ae05379cc9 (2026-08-15).
Data as JSON: /api/errors/a03fa7443f444611.
Report an issue: GitHub.