我正在编写游戏的线性化深度缓冲区,使用openEXR使用FFmpeg。不幸的是,FFmpeg没有完全遵守openEXR文件规范(就像允许一个通道使用无符号整数),所以我正在为openEXR编写一个浮动通道,该通道使用这个命令-f rawvideo -pix_fmt grayf32be -s %WIDTH%x%HEIGHT% -r %FPS% -i - -vf %DEFVF% -preset ultrafast -tune zerolatency -qp 6 -compression zip1 -pix_fmt gbrpf32le %NAME%_depth_%d.exr放入绿色通道。
浮子范围从0F到1F,是线性的。通过在搅拌机上测试16位整数(每像素分量) PNG,可以确定计算和线性化是正确的。16位整数数据与此short s = (short) (linearzieDepth(depth) * (Math.pow(2,16) - 1))类似,而对于浮点数,线性化的值直接写入OpenEXR,而不与值相乘。
但是,当查看openEXR文件时,它不具有与16位png相同的“梯度”.当并排查看它们时,在0附近的值似乎不是线性的,而且它们也不像16位png中应该的那样暗。(是的,我将图像节点设置为线性),并将其与游戏中的3d跟踪数据进行比较,我无法再现深度,也无法像使用png那样使用深度缓冲区来掩盖内容。
线性浮动范围怎么可能与图像中的线性整数范围如此不同?
更新:
现在我用下面的代码向ffmpeg写了3个通道
float f2 = this.linearizeDepth(depth);
buffer.putFloat(f2);
buffer.putFloat(0);
buffer.putFloat(0);字节缓冲区的大小为width * height * 3 * 4 -> 3通道,每4个字节。命令现在是-f rawvideo -pix_fmt gbrpf32be -s %WIDTH%x%HEIGHT% -r %FPS% -i - -vf %DEFVF% -preset ultrafast -tune zerolatency -qp 6 -compression zip1 -pix_fmt gbrpf32le %NAME%_depth_%d.exr,这意味着输入(字节缓冲区)期望32位浮动有3个通道。

FFmpeg以某种方式分裂了频道或者什么的..。可能是窃听器,可能是我的错?
发布于 2022-04-03 22:11:46
问题是从grayf32be到gbrpf32le的颜色转换。
假设源像素范围为0,1我们可以在将像素格式转换为gbrpf32le之前添加格式转换过滤器:gbrpf32le。
看起来FFmpeg也忽略了range参数,修复是添加刻度过滤器:scale=in_range=full:out_range=full。
更新命令:
ffmpeg -y -f rawvideo -pix_fmt grayf32be -src_range 1 -s 192x108 -i in.raw -vf "scale=in_range=full:out_range=full,format=rgb48le" -vcodec exr -compression zip1 -pix_fmt gbrpf32le -dst_range 1 out.exr可复制的例子:
-y -f lavfi -i testsrc=size=192x108:rate=1:duration=1 -pix_fmt gray16le in.tif
-y -src_range 1 -i in.tif -pix_fmt grayf32be -dst_range 1 -f rawvideo in.raw
-y -f rawvideo -pix_fmt grayf32be -src_range 1 -s 192x108 -i in.raw -vf "scale=in_range=full:out_range=full,format=rgb48le“-vcodec exr -compression zip1 -pix_fmt gbrpf32le 1 -dst_range
用于比较不同之处的Python代码:
img1 = cv2.imread('in.tif', cv2.IMREAD_UNCHANGED)
img2 = cv2.imread('out.exr', cv2.IMREAD_UNCHANGED)
green_ch = img2[:, :, 1] # Green channel
max_abs_diff = np.max(np.abs(green_ch*65535 - img1.astype(float)))最大的差异是3 (在65535级中)。
我们可能得考虑一下过滤器的论点.
由于FFmpeg颜色转换和范围转换存在问题(看起来是这样),在解决问题之前,您将无法获得所需的结果。
更新:
看起来,当输入的像素格式是grayf32be (三色通道平面格式)时,它就可以工作了。
测试:
-y -f lavfi -i testsrc=size=192x108:rate=1:duration=1 -pix_fmt gray16le in.tif
-y -src_range 1 -i in.tif -pix_fmt grayf32be -dst_range 1 -f rawvideo in.raw
-y -f rawvideo -pix_fmt grayf32be -s 192x108 -i "concat:in.raw|in.raw|in.raw“-f rawvideo 3.原始
-y -f rawvideo -pix_fmt gbrpf32be -s 192x108 -i -y 3.原始-vcodec exr -compression zip1 -pix_fmt gbrpf32le out.exr
用于比较差异的Python代码(比较3个颜色通道):
img1 = cv2.imread('in.tif', cv2.IMREAD_UNCHANGED)
img2 = cv2.imread('out.exr', cv2.IMREAD_UNCHANGED)
blue_ch = img2[:, :, 0] # Blue channel
green_ch = img2[:, :, 1] # Green channel
red_ch = img2[:, :, 2] # Red channel
max_red_abs_diff = np.max(np.abs(red_ch*65535 - img1.astype(float)))
max_green_abs_diff = np.max(np.abs(green_ch*65535 - img1.astype(float)))
max_blue_abs_diff = np.max(np.abs(blue_ch*65535 - img1.astype(float)))最大差异是0.001953125 (可忽略不计)。
https://stackoverflow.com/questions/71725213
复制相似问题