I would like to know how to read a HDR image (.hdr) by obtaining pixel values in the RGBE format quickly and efficiently in Python.
These are somethings I tried:
import imageio
img = imageio.imread(hdr_path, format="HDR-FI")
alternatively:
import cv2
img = cv2.imread(hdr_path, flags=cv2.IMREAD_ANYDEPTH)
This read the image, but gave the values in a RGB format.
How do you obtain the 4rth channel, the "E" channel for every pixel, without altered RGB values? I would prefer a solution involving only imageio, as i am restricted to use only that module.
If you prefer the RGBE representation over the float representation you can convert between the two
def float_to_rgbe(image, *, channel_axis=-1):
# ensure channel-last
image = np.moveaxis(image, channel_axis, -1)
max_float = np.max(image, axis=-1)
scale, exponent = np.frexp(max_float)
scale *= 256.0/max_float
image_rgbe = np.empty((*image.shape[:-1], 4)
image_rgbe[..., :3] = image * scale
image_rgbe[..., -1] = exponent + 128
image_rgbe[scale < 1e-32, :] = 0
# restore original axis order
image_rgbe = np.moveaxis(image_rgbe, -1, channel_axis)
return image_rgbe
(Note: this is based on the RGBE reference implementation (found here) and can be further optimized if it actually is the bottleneck.)
In your comment, you mention "If i parse the numpy array manually and split the channels into an E channel, it takes too much time...", but it is hard to tell why that is the case without seeing the code. The above is O(height*width), which seems reasonable for a pixel-level image processing method.