{"record":{"id":"ee72bf16d4750c83","repo":"lllyasviel/ControlNet","slug":"image-dtype-must-be-float32","errorCode":null,"errorMessage":"Image dtype must be float32.","messagePattern":"Image dtype must be float32\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"annotator/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/annotator/midas/utils.py#L53-L89","documentation":"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.","triggerScenarios":"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.","commonSituations":"Depth predictions in float64 after arithmetic; normalizing with astype('float16') to save memory; feeding model outputs without an explicit dtype cast.","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"],"exampleFix":"# before\nwrite_pfm('/tmp/d.pfm', depth)  # depth is float64\n# after\nwrite_pfm('/tmp/d.pfm', depth.astype(np.float32))","handlingStrategy":"validation","validationCode":"assert image.dtype == np.float32, f'need float32, got {image.dtype}'\nimage = image.astype(np.float32, copy=False)","typeGuard":"def is_float32(img) -> bool:\n    return getattr(img, 'dtype', None) == np.float32","tryCatchPattern":"try:\n    write_pfm(path, image)\nexcept Exception as e:\n    if 'dtype must be float32' in str(e):\n        write_pfm(path, image.astype(np.float32))\n    else:\n        raise","preventionTips":["Standardize on float32 immediately after model inference","Centralize dtype conversion in one save utility"],"tags":["pfm","numpy","dtype","midas"],"backgroundTag":"wrong-dtype","analyzedSha":"ed85cd1e25a5ed592f7d8178495b4483de0331bf","analyzedAt":"2026-08-27T12:58:54.167Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}