I am trying to use ffmpeg to write an EXR image containing a single channel of float32 values. Here is the code:
def test_ffmpeg_float_gray_to_exr():
import numpy as np
import subprocess
array1 = np.array([[0.1, 0.2], [0.4, 0.7]], np.float32) # Single-channel 2x2 image.
array1.tofile('temp1.raw')
ffmpeg_command_write = [
'ffmpeg', '-hide_banner',
'-f', 'rawvideo',
'-pix_fmt', 'grayf32le',
'-s', '2x2',
'-i', 'temp1.raw',
'-pix_fmt', 'grayf32le',
'-compression', 'zip1', # ['none', 'rle', 'zip1', zip16']
'-format', 'float', # ['half', 'float']
'-vcodec', 'exr',
'-y', 'output.exr',
]
subprocess.run(ffmpeg_command_write, check=True)
ffmpeg_command_read = [
'ffmpeg', '-hide_banner',
'-i', 'output.exr',
'-f', 'image2pipe',
'-pix_fmt', 'grayf32le',
'-y', 'temp2.raw',
]
subprocess.run(ffmpeg_command_read, check=True)
array2 = np.fromfile('temp2.raw', dtype=np.float32).reshape(2, 2)
print(array2)
test_ffmpeg_float_gray_to_exr()
When writing, ffmpeg gives the message Incompatible pixel format 'grayf32le' for codec 'exr', auto-selecting format 'gbrpf32le'
and then reading back the values gives incorrect results.
If I create a single-channel exr image (using OpenCV), it does read correctly using the ffmpeg_command_read
command in the above code, so only the writing part is broken.
And, I am able to create 3-channel (gbrpf32le
) and 4-channel (gbrapf32le
) exr images using ffmpeg and variants of the above code. Just not 1-channel.
The source code https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/exrenc.c suggests that it should be possible to encode grayf32le
(but I'm no expert).
Am I missing some command-line option to enable this?
grayf32le
support in exr encode is available since v5.1