lllyasviel/ControlNet · error · Exception
Image dtype must be float32.
Error message
Image dtype must be float32.
What it means
write_pfm serializes a numpy array to PFM, which only supports float32 pixel data. Any other dtype (float64, uint8, float16) is rejected before writing, because the PFM endianness/byte layout assumes 4-byte floats.
Source
Thrown at annotator/midas/utils.py:71
data = np.flipud(data)
return data, scale
def write_pfm(path, image, scale=1):
"""Write pfm file.
Args:
path (str): pathto file
image (array): data
scale (int, optional): Scale. Defaults to 1.
"""
with open(path, "wb") as file:
color = None
if image.dtype.name != "float32":
raise Exception("Image dtype must be float32.")
image = np.flipud(image)
if len(image.shape) == 3 and image.shape[2] == 3: # color image
color = True
elif (
len(image.shape) == 2 or len(image.shape) == 3 and image.shape[2] == 1
): # greyscale
color = False
else:
raise Exception("Image must have H x W x 3, H x W x 1 or H x W dimensions.")
file.write("PF\n" if color else "Pf\n".encode())
file.write("%d %d\n".encode() % (image.shape[1], image.shape[0]))
endian = image.dtype.byteorder
if endian == "<" or endian == "=" and sys.byteorder == "little":View on GitHub (pinned to ed85cd1e25)
Solutions
- Cast before writing: image = image.astype(np.float32)
- If using write_depth, ensure the depth array you pass is float32
- Add an assertion in your pipeline right after depth inference to catch dtype drift early
Example fix
# before
write_pfm('/tmp/d.pfm', depth) # depth is float64
# after
write_pfm('/tmp/d.pfm', depth.astype(np.float32)) Defensive patterns
Strategy: validation
Validate before calling
assert image.dtype == np.float32, f'need float32, got {image.dtype}'
image = image.astype(np.float32, copy=False) Type guard
def is_float32(img) -> bool:
return getattr(img, 'dtype', None) == np.float32 Try / catch
try:
write_pfm(path, image)
except Exception as e:
if 'dtype must be float32' in str(e):
write_pfm(path, image.astype(np.float32))
else:
raise Prevention
- Standardize on float32 immediately after model inference
- Centralize dtype conversion in one save utility
When it happens
Trigger: Calling write_pfm (directly or via write_depth) with a numpy image whose dtype is not np.float32, e.g. a float64 depth array from computation or a uint8 image.
Common situations: Depth predictions in float64 after arithmetic; normalizing with astype('float16') to save memory; feeding model outputs without an explicit dtype cast.
Related errors
- Image dtype must be float32.
- Image must have H x W x 3, H x W x 1 or H x W dimensions.
- Not a PFM file:
- Malformed PFM header.
- Image must have H x W x 3, H x W x 1 or H x W dimensions.
AI-assisted analysis of lllyasviel/ControlNet@ed85cd1e25 (2026-08-27).
Data as JSON: /api/errors/ee72bf16d4750c83.
Report an issue: GitHub.