lllyasviel/ControlNet · error · Exception
Image dtype must be float32.
Error message
Image dtype must be float32.
What it means
Raised by write_pfm when the numpy array passed as image does not have dtype float32. The PFM format stores 32-bit floats, so the writer only accepts np.float32 arrays and refuses anything else (float64, uint8, float16, etc.).
Source
Thrown at ldm/modules/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 the array before writing: image = image.astype(np.float32)
- If using torch, do tensor.float().cpu().numpy() before passing to write_pfm
- If the values are uint8 intensities, decide whether PFM is the right format at all (PGM/PNG may suit integer data)
- Wrap the save in a helper that always normalizes dtype to float32
Example fix
# before write_depth(path, depth) # depth is float64 # after write_depth(path, depth.astype(np.float32))
Defensive patterns
Strategy: type-guard
Validate before calling
def as_pfm_image(img):
import numpy as np
return np.ascontiguousarray(img, dtype=np.float32) Type guard
def is_pfm_writable(img) -> bool:
import numpy as np
return isinstance(img, np.ndarray) and img.dtype == np.float32 Prevention
- Convert with .astype(np.float32) at the boundary right after model inference
- If using torch, do tensor.float().cpu().numpy() before saving
- Centralize saving in one helper that enforces float32
When it happens
Trigger: Calling write_pfm(path, image) (usually via write_depth) with an array whose image.dtype.name != 'float32' — e.g. a float64 depth map from arithmetic, a uint8 image from cv2.imread, or a torch tensor converted with .numpy() while still in half precision.
Common situations: Saving MiDaS/depth-model outputs that went through operations promoting to float64, feeding a normalized image read as uint8, or converting fp16 tensors on GPU to numpy without casting.
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.
- Malformed PFM header.
- Not a PFM file:
- Malformed PFM header.
AI-assisted analysis of lllyasviel/ControlNet@ed85cd1e25 (2026-08-27).
Data as JSON: /api/errors/0647c6f968a86cd1.
Report an issue: GitHub.