将[0,1]范围内的RGB值转换为高动态范围(EXR格式)

时间:2014-08-05 18:21:59

标签: image image-processing graphics rgb openexr

我只需要澄清如何正确地将[0,1]范围内的rgb像素值转换为适合像openEXR这样的HDR格式的范围。

所以我知道,例如,当使用像PNG或JPG这样每个通道只有8位的低动态范围格式时,你只需要将每个rgb值乘以2 ^ 8-1 = 255并将其钳制以便所有你的值在[0,255]范围内。

OpenEXR和其他HDR格式使用半精度格式,每个通道16位。所以我只是做与以前相同的事情,并将每个通道乘以2 ^ 16-1 = 65535,以便我的新范围变为[0,65535]?

修改

所以我尝试了上面写的内容但是当我尝试在photoshop中显示openEXR文件时,它完全是白色的。似乎大于10左右的任何值都太亮了,以至于Photoshop无法正常显示,我觉得很奇怪。所以这似乎不是正确的方法,除非photoshops显示有问题。

3 个答案:

答案 0 :(得分:2)

我们同时处理三个相关但不同的问题。

第一个问题是 range 的问题:通道存储为[0,1]或[0,255]或[0,65535]范围内的值。 缩放(乘法和可能的钳位)是您从一个范围转换为另一个范围的方法。

第二个问题是原始样本大小的问题:您使用多少位来存储该值。这不一定必须是范围大小的二进制对数。例如,如果您的范围是[0,255],则可以将值存储为8位,其中最低有效位表示增量1,或者存储为6位,其中最低有效位表示增量4或10位最低有效位表示0.25的增量。事实上,正如我们将在下一期中看到的那样,增量不必修复。

第三个也是最后一个问题是 encoding :固定点或浮点。当我们说以8位存储[0,255]的值或以16位存储[0,65535]的值时,我们通常表示整数编码(固定点的特殊情况,其中最低有效位表示固定增量为1 )。当值存储在[0,1]范围内时,无论原始样本大小如何,通常这意味着浮点存储(其中大多数位用于存储有效位数,而保留一些位用于存储大小的与最低有效位相关联的增量)。当我们谈到"半精度","单精度","双精度","扩展精度"等等我们也总是指浮点编码。

所以这里有一个问题:OpenEXR使用浮点编码,格式不是大多数编程语言的内置。大多数现代语言只有64位浮点数,如果它们提供其他任何东西,它通常是32位浮点数(在C系列中分别为doublefloat),但是16位浮点数几乎从来没有开箱即用。

Half precision可以表示[-65505,65504]范围内的值,具有11位(略好于3位小数位数)的精度,同时还能够表示小到2 ^ -14的值。但是,考虑到OpenEXR是HDR格式,您可能不会真正期望使用整个范围,因为选择数字编码以适应(极端)过度曝光或曝光不足。也就是说,除非您的相机实际上产生如此巨大的动态范围值。

因此,您可能实际上不需要扩展频道值。但是,假设您已经从[0,1]中的值开始,您可能会以单精度或双精度存储浮点数,并且您必须将它们转码为半精度。根据您使用的编程语言,库甚至硬件平台,可能有一个现成的解决方案,或者您可能需要对自己的方法进行一些改进。作为起点,我只能为您提供this DuckDuckGo search

答案 1 :(得分:0)

我太累了,不能直接思考,但这可能会帮助你全力以赴。我用ImageMagick创建了三个OpenEXR图像,一个是白色,一个是黑色,一个是红色,都是1像素x 1像素。

convert -size 1x1! xc:white white.exr
convert -size 1x1! xc:black black.exr
convert -size 1x1! xc:red red.exr

然后我把它们全部重写:

xxd white.exr > white.txt
xxd black.exr > black.txt
xxd red.exr > red.txt

以下是文件:

White.txt

0000000: 762f 3101 0200 0000 6368 616e 6e65 6c73  v/1.....channels
0000010: 0063 686c 6973 7400 4900 0000 4100 0100  .chlist.I...A...
0000020: 0000 0000 0000 0100 0000 0100 0000 4200  ..............B.
0000030: 0100 0000 0000 0000 0100 0000 0100 0000  ................
0000040: 4700 0100 0000 0000 0000 0100 0000 0100  G...............
0000050: 0000 5200 0100 0000 0000 0000 0100 0000  ..R.............
0000060: 0100 0000 0063 6f6d 7072 6573 7369 6f6e  .....compression
0000070: 0063 6f6d 7072 6573 7369 6f6e 0001 0000  .compression....
0000080: 0000 6461 7461 5769 6e64 6f77 0062 6f78  ..dataWindow.box
0000090: 3269 0010 0000 0000 0000 0000 0000 0000  2i..............
00000a0: 0000 0000 0000 0064 6973 706c 6179 5769  .......displayWi
00000b0: 6e64 6f77 0062 6f78 3269 0010 0000 0000  ndow.box2i......
00000c0: 0000 0000 0000 0000 0000 0000 0000 006c  ...............l
00000d0: 696e 654f 7264 6572 006c 696e 654f 7264  ineOrder.lineOrd
00000e0: 6572 0001 0000 0000 7069 7865 6c41 7370  er......pixelAsp
00000f0: 6563 7452 6174 696f 0066 6c6f 6174 0004  ectRatio.float..
0000100: 0000 0000 0080 3f73 6372 6565 6e57 696e  ......?screenWin
0000110: 646f 7743 656e 7465 7200 7632 6600 0800  dowCenter.v2f...
0000120: 0000 0000 0000 0000 0000 7363 7265 656e  ..........screen
0000130: 5769 6e64 6f77 5769 6474 6800 666c 6f61  WindowWidth.floa
0000140: 7400 0400 0000 0000 803f 0053 0100 0000  t........?.S....
0000150: 0000 0000 0000 0008 0000 0000 3c00 3c00  ............<.<.
0000160: 3c00 3c                                  <.<

Black.txt

0000000: 762f 3101 0200 0000 6368 616e 6e65 6c73  v/1.....channels
0000010: 0063 686c 6973 7400 4900 0000 4100 0100  .chlist.I...A...
0000020: 0000 0000 0000 0100 0000 0100 0000 4200  ..............B.
0000030: 0100 0000 0000 0000 0100 0000 0100 0000  ................
0000040: 4700 0100 0000 0000 0000 0100 0000 0100  G...............
0000050: 0000 5200 0100 0000 0000 0000 0100 0000  ..R.............
0000060: 0100 0000 0063 6f6d 7072 6573 7369 6f6e  .....compression
0000070: 0063 6f6d 7072 6573 7369 6f6e 0001 0000  .compression....
0000080: 0000 6461 7461 5769 6e64 6f77 0062 6f78  ..dataWindow.box
0000090: 3269 0010 0000 0000 0000 0000 0000 0000  2i..............
00000a0: 0000 0000 0000 0064 6973 706c 6179 5769  .......displayWi
00000b0: 6e64 6f77 0062 6f78 3269 0010 0000 0000  ndow.box2i......
00000c0: 0000 0000 0000 0000 0000 0000 0000 006c  ...............l
00000d0: 696e 654f 7264 6572 006c 696e 654f 7264  ineOrder.lineOrd
00000e0: 6572 0001 0000 0000 7069 7865 6c41 7370  er......pixelAsp
00000f0: 6563 7452 6174 696f 0066 6c6f 6174 0004  ectRatio.float..
0000100: 0000 0000 0080 3f73 6372 6565 6e57 696e  ......?screenWin
0000110: 646f 7743 656e 7465 7200 7632 6600 0800  dowCenter.v2f...
0000120: 0000 0000 0000 0000 0000 7363 7265 656e  ..........screen
0000130: 5769 6e64 6f77 5769 6474 6800 666c 6f61  WindowWidth.floa
0000140: 7400 0400 0000 0000 803f 0053 0100 0000  t........?.S....
0000150: 0000 0000 0000 0008 0000 0000 3c00 0000  ............<...
0000160: 0000 00                                  ...

Red.txt

0000000: 762f 3101 0200 0000 6368 616e 6e65 6c73  v/1.....channels
0000010: 0063 686c 6973 7400 4900 0000 4100 0100  .chlist.I...A...
0000020: 0000 0000 0000 0100 0000 0100 0000 4200  ..............B.
0000030: 0100 0000 0000 0000 0100 0000 0100 0000  ................
0000040: 4700 0100 0000 0000 0000 0100 0000 0100  G...............
0000050: 0000 5200 0100 0000 0000 0000 0100 0000  ..R.............
0000060: 0100 0000 0063 6f6d 7072 6573 7369 6f6e  .....compression
0000070: 0063 6f6d 7072 6573 7369 6f6e 0001 0000  .compression....
0000080: 0000 6461 7461 5769 6e64 6f77 0062 6f78  ..dataWindow.box
0000090: 3269 0010 0000 0000 0000 0000 0000 0000  2i..............
00000a0: 0000 0000 0000 0064 6973 706c 6179 5769  .......displayWi
00000b0: 6e64 6f77 0062 6f78 3269 0010 0000 0000  ndow.box2i......
00000c0: 0000 0000 0000 0000 0000 0000 0000 006c  ...............l
00000d0: 696e 654f 7264 6572 006c 696e 654f 7264  ineOrder.lineOrd
00000e0: 6572 0001 0000 0000 7069 7865 6c41 7370  er......pixelAsp
00000f0: 6563 7452 6174 696f 0066 6c6f 6174 0004  ectRatio.float..
0000100: 0000 0000 0080 3f73 6372 6565 6e57 696e  ......?screenWin
0000110: 646f 7743 656e 7465 7200 7632 6600 0800  dowCenter.v2f...
0000120: 0000 0000 0000 0000 0000 7363 7265 656e  ..........screen
0000130: 5769 6e64 6f77 5769 6474 6800 666c 6f61  WindowWidth.floa
0000140: 7400 0400 0000 0000 803f 0053 0100 0000  t........?.S....
0000150: 0000 0000 0000 0008 0000 0000 3c00 0000  ............<...
0000160: 0000 3c                                  ..<

diff white.txt black.txt

22,23c22,23
< 0000150: 0000 0000 0000 0008 0000 0000 3c00 3c00  ............<.<.
< 0000160: 3c00 3c                                  <.<
---
> 0000150: 0000 0000 0000 0008 0000 0000 3c00 0000  ............<...
> 0000160: 0000 00

答案 2 :(得分:0)

简而言之,这可能不会给您带来有用的结果。

比较长的答案是,这种方法做出了一些关于图像处理根本不“安全”的假设。

主要假设是 255 的低动态范围值代表 65535 的 HDR 值。HDR 打算解决的主要问题是现实世界的信号必须压缩到有限的范围。想象一下直接拍摄太阳的数码照片:该光强度的输入值比任何成像软件支持的要大得多,因此必须以某种方式对其进行压缩。使用 LDR,太阳圆盘的中心和它周围的大部分花朵都将被钳制到 255。使用 HDR,您仍然会钳制,但仅限于 65535。如果您有一个真实世界的信号,它给出的值如下200、255、300 和 100,000,然后被限制到 255,你不能简单地将 255 缩放到 65535 并获得合理的结果应该是有道理的。 255 可能是从 256、300 或 100000 中截取的;没有办法知道。 (这是对成像的一种彻底的过度简化,但它应该足以理解特别是这个限制)。

第二个假设是,您在显示器上看到的内容与图像中的值有关。图像中 0 - 65535 范围的值必须显示在您的显示器上,这几乎肯定限于 sRGB 光谱 (255)。最有可能的是,如果您只是将 0-255 缩放到 0-65535,那么您范围的 99% 都在 255 以上。因此,无论您的图像中有多少信息,都很容易将其全部剪裁为“白色”。 "

此外,根据 Photoshop(或 GPU 驱动程序或操作系统或显示面板)如何将您的 HDR 65535 转换为 sRGB,它很可能再次被限制为 255,或者可能“愚蠢地”缩放,或者或许可以“巧妙地”缩放,或者它们的任意组合。如果 Photoshop 将您的图像显示为纯白色,则您必须确认该过程中的许多步骤,以确定“谁”特别是在转换您的颜色值以及如何转换。 Photoshop 可能会在发送到操作系统之前进行钳位。操作系统可能会在发送到 GPU 之前进行钳位。当 GPU 发送到显示器时,它可能处于夹紧状态。打开像素时,显示器可能处于钳位状态。 ...或在这些步骤中的任何一步中进行夹紧、缩放和变换的任何组合(我知道,并非所有这些组合实际上都是可能的,但关键是文件和您的眼球之间发生了很多事情)。

将 LDR 值转换为 HDR 色彩空间(反之亦然)是一项不平凡的追求,它本身就是一门学科。根据您的应用,您可能需要进行大量研究,然后才能找到一个好的解决方案。