Python:从 OpenEXR 通道获取辐射值
大家早上好!我在 Blender 中创建了一个物理上精确的场景,我的目标是使用 Python 研究渲染场景的辐射条件,以获得 [W/m^2] 的照明图。由于其高动态范围属性,我将图像保存为 OpenEXR 文件格式,并且我想获取从“R”“G”“B”通道中的 RGB 值开始的相对亮度图。主要问题是如何缩放来自 OpenEXR 通道的线性值,使其具有 [0, 1] 之间的物理精确值,这是获取保持文件格式的 HDR 属性所需的相对亮度图所需的。部分代码报告如下。
pt = Imath.PixelType(Imath.PixelType.FLOAT)
exrfile = exr.InputFile(filename)
dw = exrfile.header()['dataWindow']
size = (dw.max.x - dw.min.x + 1, dw.max.y - dw.min.y + 1)
redstr = exrfile.channel('R', pt)
red = np.fromstring(redstr, dtype = np.float32)
red.shape = (size[1], size[0]) # Numpy arrays are (row, col)
greenstr = exrfile.channel('G', pt)
green = np.fromstring(greenstr, dtype = np.float32)
green.shape = (size[1], size[0]) # Numpy arrays are (row, col)
bluestr = exrfile.channel('B', pt)
blue = np.fromstring(bluestr, dtype = np.float32)
blue.shape = (size[1], size[0]) # Numpy arrays are (row, col)
rel_luminance = 0.2126*red[:,:]+0.7152*green[:,:]+0.0722*blue[:,:]
对于测试图像,得到的三个通道的Max值分别为:
Max(R) = 198.16421508789062
Max(G) = 173.5792999267578
Max(B) = 163.20120239257812
得到的值显然不在[0, 1]之间,而且我无法理解全球最大价值渠道并获得我想要的东西。
有人有一些建议可以解决我的问题吗?谢谢指教。
Good morning everybody! I created a physically accurate scene in Blender and my aim, using python, is to study radiometric conditions over the rendered scene in order to obtain an illumination map in terms of [W/m^2]. I saved images in OpenEXR file format, due to its high dynamic-range properties and I wanted to obtain a Relative Luminance Map starting from RGB values in "R" "G" "B" channels. The major issue is how to scale linear values from OpenEXR channels to have physically accurate values between [0, 1], needed to obtain Relative Luminance map maintaining the HDR properties of the file format. Part of the code is reported below.
pt = Imath.PixelType(Imath.PixelType.FLOAT)
exrfile = exr.InputFile(filename)
dw = exrfile.header()['dataWindow']
size = (dw.max.x - dw.min.x + 1, dw.max.y - dw.min.y + 1)
redstr = exrfile.channel('R', pt)
red = np.fromstring(redstr, dtype = np.float32)
red.shape = (size[1], size[0]) # Numpy arrays are (row, col)
greenstr = exrfile.channel('G', pt)
green = np.fromstring(greenstr, dtype = np.float32)
green.shape = (size[1], size[0]) # Numpy arrays are (row, col)
bluestr = exrfile.channel('B', pt)
blue = np.fromstring(bluestr, dtype = np.float32)
blue.shape = (size[1], size[0]) # Numpy arrays are (row, col)
rel_luminance = 0.2126*red[:,:]+0.7152*green[:,:]+0.0722*blue[:,:]
For a test image the obtained Max values of the three channels are respectively:
Max(R) = 198.16421508789062
Max(G) = 173.5792999267578
Max(B) = 163.20120239257812
The obtained values are obviously not in the range between [0, 1], moreover I am not able to understand the global maximum value to scale the channels and obtain what i want.
Has someone some tips to solve my problem? Thanks in advice.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
几点...
lum
一词出现在单词中,它都是光度测量的(即以人为中心的域),而rad
可能是辐射测量的。照度、亮度等是光度按摩值,而辐照度和辐射度是物理模型侧。0.2126 * R + 0.7152 * G + 0.0722 * B
。再次注意,这是基于 CIE 1920 发光效率函数的近似值。另请注意,亮度并不能充分代表累积等效消色差亮度贡献。A few points…
lum
is in a word, it is photometric (IE human-centric domain) whererad
is likely radiometric. Illuminance, luminance etc. are photometric massaged values,while irradiance and radiance are the physical model side.0.2126 * R + 0.7152 * G + 0.0722 * B
. Again, note this is an approximation based off of the CIE 1920 luminous efficacy function. Also note, luminance does not adequately represent the cumulative equivalent achromatic luminance contribution.