I render RGB images and their depth maps as well for a series of frames (using cycles). Specifically, I need not a B/W depth png/jpg image, rather the actual depth values itself, which I can later read off in python. I found the exr to be the oft suggested format in online forums, as I want to store float values as such.
So, I stored the rgb image as well as the z buffer together in a .exr file. In python, while I could reassemble the rgb image perfectly, I discovered the Z channel info to be a matrix of ones. It should actually contain the float depth values.
What could be going wrong here? I have checked the 'zbuf' option in output properties.
For reference, this is the code I use to separate rgb and z values from the exr file:
import sys import numpy as np import OpenEXR as exr import Imath def readEXR(filename): """Read color + depth data from EXR image file. Parameters ---------- filename : str File path. Returns ------- img : RGB or RGBA image in float32 format. Each color channel lies within the interval [0, 1]. Color conversion from linear RGB to standard RGB is performed internally. See https://en.wikipedia.org/wiki/SRGB#The_forward_transformation_(CIE_XYZ_to_sRGB) for more information. Z : Depth buffer in float32 format or None if the EXR file has no Z channel. """ print(filename) filename = str(filename) exrfile = exr.InputFile(filename) header = exrfile.header() dw = header['dataWindow'] isize = (dw.max.y - dw.min.y + 1, dw.max.x - dw.min.x + 1) channelData = dict() # convert all channels in the image to numpy arrays for c in header['channels']: C = exrfile.channel(c, Imath.PixelType(Imath.PixelType.FLOAT)) C = np.fromstring(C, dtype=np.float32) C = np.reshape(C, isize) channelData[c] = C colorChannels = ['R', 'G', 'B', 'A'] if 'A' in header['channels'] else ['R', 'G', 'B'] img = np.concatenate([channelData[c][...,np.newaxis] for c in colorChannels], axis=2) # linear to standard RGB img[..., :3] = np.where(img[..., :3] <= 0.0031308, 12.92 * img[..., :3], 1.055 * np.power(img[..., :3], 1 / 2.4) - 0.055) # sanitize image to be in range [0, 1] img = np.where(img < 0.0, 0.0, np.where(img > 1.0, 1, img)) Z = None if 'Z' not in header['channels'] else channelData['Z'] return img, Z def main(fpth): img, depth = readEXR(fpth[-1]) print(np.max(depth)) print(np.min(depth)) return if __name__ == '__main__': main(sys.argv[1:])