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

  1. Cast the array before writing: image = image.astype(np.float32)
  2. If using torch, do tensor.float().cpu().numpy() before passing to write_pfm
  3. If the values are uint8 intensities, decide whether PFM is the right format at all (PGM/PNG may suit integer data)
  4. 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

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


AI-assisted analysis of lllyasviel/ControlNet@ed85cd1e25 (2026-08-27). Data as JSON: /api/errors/0647c6f968a86cd1. Report an issue: GitHub.