{"record":{"id":"0647c6f968a86cd1","repo":"lllyasviel/ControlNet","slug":"image-dtype-must-be-float32-0647c6","errorCode":null,"errorMessage":"Image dtype must be float32.","messagePattern":"Image dtype must be float32\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"ldm/modules/midas/utils.py","lineNumber":71,"sourceCode":"        data = np.flipud(data)\n\n        return data, scale\n\n\ndef write_pfm(path, image, scale=1):\n    \"\"\"Write pfm file.\n\n    Args:\n        path (str): pathto file\n        image (array): data\n        scale (int, optional): Scale. Defaults to 1.\n    \"\"\"\n\n    with open(path, \"wb\") as file:\n        color = None\n\n        if image.dtype.name != \"float32\":\n            raise Exception(\"Image dtype must be float32.\")\n\n        image = np.flipud(image)\n\n        if len(image.shape) == 3 and image.shape[2] == 3:  # color image\n            color = True\n        elif (\n            len(image.shape) == 2 or len(image.shape) == 3 and image.shape[2] == 1\n        ):  # greyscale\n            color = False\n        else:\n            raise Exception(\"Image must have H x W x 3, H x W x 1 or H x W dimensions.\")\n\n        file.write(\"PF\\n\" if color else \"Pf\\n\".encode())\n        file.write(\"%d %d\\n\".encode() % (image.shape[1], image.shape[0]))\n\n        endian = image.dtype.byteorder\n\n        if endian == \"<\" or endian == \"=\" and sys.byteorder == \"little\":","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/lllyasviel/ControlNet/blob/ed85cd1e25a5ed592f7d8178495b4483de0331bf/ldm/modules/midas/utils.py#L53-L89","documentation":"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.).","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\nwrite_depth(path, depth)  # depth is float64\n# after\nwrite_depth(path, depth.astype(np.float32))","handlingStrategy":"type-guard","validationCode":"def as_pfm_image(img):\n    import numpy as np\n    return np.ascontiguousarray(img, dtype=np.float32)","typeGuard":"def is_pfm_writable(img) -> bool:\n    import numpy as np\n    return isinstance(img, np.ndarray) and img.dtype == np.float32","tryCatchPattern":null,"preventionTips":["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"],"tags":["midas","pfm","numpy","dtype","depth-estimation"],"backgroundTag":"numpy-dtype-mismatch","analyzedSha":"ed85cd1e25a5ed592f7d8178495b4483de0331bf","analyzedAt":"2026-08-27T12:58:54.167Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}