I rendered and exported a scene with cycles as MultiChannel OpenEXR, then read it back in with OpenEXR binding for Python. The header looks like below. As it indicates, most of the field are floats (32 bits as I've saved with FULL option). I expect them to be in the range of [0, 1] which I can reconstruct to RGB value by multiplying with 255. However, it turns out that the values don't belong to any specific range which is confusing me. For example, the min and max values of each channels of the Composite.Combined are:
[(0.0, 270.6739501953125), (0.0, 221.4493865966797), (0.0, 106.66129302978516)]
So what do these values mean? And is there a way to reconstruct the RGB image that Blender renders? My intention is to simulate the way Blender render with all the passes.
PS: simply normalize these values to the range [0, 255] does not work. Somehow most of the pixels are around 1. or 2., but some get very large.
My code to extract image data is as follows:
exrFile = OpenEXR.InputFile('fallroad_0001.exr')
header = exrFile.header()
dw = header['dataWindow']
pt = Imath.PixelType(Imath.PixelType.FLOAT)
size = (dw.max.x - dw.min.x + 1, dw.max.y - dw.min.y + 1)
cc_r = np.fromstring(exrFile.channel('RenderLayer.Combined.R', pt), dtype=np.float32)
cc_g = np.fromstring(exrFile.channel('RenderLayer.Combined.G', pt), dtype=np.float32)
cc_b = np.fromstring(exrFile.channel('RenderLayer.Combined.B', pt), dtype=np.float32)
cc_r.shape = cc_g.shape = cc_b.shape = (size[1], size[0])
cc = np.dstack((cc_r, cc_g, cc_b))
The header information is as follows
{'BlenderMultiChannel': 'Blender V2.55.1 and newer',
'Camera': 'Camera',
'Date': '2016/10/17 10:23:17',
'File': '/home/FallRoad/FallRoad_render1.blend',
'Frame': '015',
'RenderTime': '11:30.66',
'Scene': 'Scene',
'Time': '00:00:00:15',
'channels': {'Composite.Combined.A': FLOAT (1, 1),
'Composite.Combined.B': FLOAT (1, 1),
'Composite.Combined.G': FLOAT (1, 1),
'Composite.Combined.R': FLOAT (1, 1),
'RenderLayer.Combined.A': FLOAT (1, 1),
'RenderLayer.Combined.B': FLOAT (1, 1),
'RenderLayer.Combined.G': FLOAT (1, 1),
'RenderLayer.Combined.R': FLOAT (1, 1),
'RenderLayer.Depth.Z': FLOAT (1, 1),
'RenderLayer.DiffCol.B': FLOAT (1, 1),
'RenderLayer.DiffCol.G': FLOAT (1, 1),
'RenderLayer.DiffCol.R': FLOAT (1, 1),
'RenderLayer.DiffDir.B': FLOAT (1, 1),
'RenderLayer.DiffDir.G': FLOAT (1, 1),
'RenderLayer.DiffDir.R': FLOAT (1, 1),
'RenderLayer.DiffInd.B': FLOAT (1, 1),
'RenderLayer.DiffInd.G': FLOAT (1, 1),
'RenderLayer.DiffInd.R': FLOAT (1, 1),
'RenderLayer.Emit.B': FLOAT (1, 1),
'RenderLayer.Emit.G': FLOAT (1, 1),
'RenderLayer.Emit.R': FLOAT (1, 1),
'RenderLayer.GlossCol.B': FLOAT (1, 1),
'RenderLayer.GlossCol.G': FLOAT (1, 1),
'RenderLayer.GlossCol.R': FLOAT (1, 1),
'RenderLayer.GlossDir.B': FLOAT (1, 1),
'RenderLayer.GlossDir.G': FLOAT (1, 1),
'RenderLayer.GlossDir.R': FLOAT (1, 1),
'RenderLayer.GlossInd.B': FLOAT (1, 1),
'RenderLayer.GlossInd.G': FLOAT (1, 1),
'RenderLayer.GlossInd.R': FLOAT (1, 1),
'RenderLayer.IndexMA.X': FLOAT (1, 1),
'RenderLayer.IndexOB.X': FLOAT (1, 1),
'RenderLayer.Shadow.B': FLOAT (1, 1),
'RenderLayer.Shadow.G': FLOAT (1, 1),
'RenderLayer.Shadow.R': FLOAT (1, 1),
'RenderLayer.SubsurfaceCol.B': FLOAT (1, 1),
'RenderLayer.SubsurfaceCol.G': FLOAT (1, 1),
'RenderLayer.SubsurfaceCol.R': FLOAT (1, 1),
'RenderLayer.SubsurfaceDir.B': FLOAT (1, 1),
'RenderLayer.SubsurfaceDir.G': FLOAT (1, 1),
'RenderLayer.SubsurfaceDir.R': FLOAT (1, 1),
'RenderLayer.SubsurfaceInd.B': FLOAT (1, 1),
'RenderLayer.SubsurfaceInd.G': FLOAT (1, 1),
'RenderLayer.SubsurfaceInd.R': FLOAT (1, 1),
'RenderLayer.TransCol.B': FLOAT (1, 1),
'RenderLayer.TransCol.G': FLOAT (1, 1),
'RenderLayer.TransCol.R': FLOAT (1, 1),
'RenderLayer.TransDir.B': FLOAT (1, 1),
'RenderLayer.TransDir.G': FLOAT (1, 1),
'RenderLayer.TransDir.R': FLOAT (1, 1),
'RenderLayer.TransInd.B': FLOAT (1, 1),
'RenderLayer.TransInd.G': FLOAT (1, 1),
'RenderLayer.TransInd.R': FLOAT (1, 1),
'RenderLayer.Vector.W': FLOAT (1, 1),
'RenderLayer.Vector.X': FLOAT (1, 1),
'RenderLayer.Vector.Y': FLOAT (1, 1),
'RenderLayer.Vector.Z': FLOAT (1, 1)},
'compression': NO_COMPRESSION,
'dataWindow': (0, 0) - (1919, 1079),
'displayWindow': (0, 0) - (1919, 1079),
'lineOrder': INCREASING_Y,
'pixelAspectRatio': 1.0,
'screenWindowCenter': (0.0, 0.0),
'screenWindowWidth': 1.0}
Edited: I include here the images that I have hand-on. From left to right: the image display with original float value, the image with float cut-off at 1 (all > 1 become 1) and image rendered by Blender