pythonimageopencvimage-processingopenexr

How to correctly read .exr files in python?


like the title says I want to read .exr image files which encode depth.

Sample image - displayed using openexr-viewer (Source: Synscapes datatset)

I tried:

os.environ["OPENCV_IO_ENABLE_OPENEXR"]="1"

import cv2
import numpy as np

exr_file_path = 'path/to/file'

image = cv2.imread(exr_file_path,  cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH)

The dimensions of image are correct, but the image is completely filled with zeros.

Debugger shows this:

->image.shape
      (720, 1440)
->np.unique(image)
      array([0.], dtype=float32)

What am I missing ?

My goal would be to create a function which accepts a path to an .exr file and returns the image as a pillow image.

Currently this is what I have:

def exr_to_pil(exr_file_path): 
    exr_file_path = str(exr_file_path)
    image = cv2.imread(exr_file_path,  cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH)
    
    # Debugger stops here to check output of imread
    img = Image.fromarray(image.astype('uint8'))
    
    return img

Solution

  • Solved the problem using the OpenEXR an Imath libs

    At first had some problems installing OpenEXR but could fix is thanks to this answer in this post.

    On MacOS with the same python version I hit similar errors and everything worked when installing with this command: pip install git+https://github.com/jamesbowman/openexrpython.git

    Code for depth map loading is:

    import OpenEXR as exr
    import Imath
    
    def exr_to_array(filepath: Path):
        exrfile = exr.InputFile(filepath.as_posix())
        raw_bytes = exrfile.channel('Z', Imath.PixelType(Imath.PixelType.FLOAT))
        depth_vector = numpy.frombuffer(raw_bytes, dtype=numpy.float32)
        height = exrfile.header()['displayWindow'].max.y + 1 - exrfile.header()['displayWindow'].min.y
        width = exrfile.header()['displayWindow'].max.x + 1 - exrfile.header()['displayWindow'].min.x
        depth_map = numpy.reshape(depth_vector, (height, width))
        return depth_map