从 Blender 中的查看器节点检索的像素比实际渲染的图像更暗......为什么?

Pixels retrieved from Viewer Node within Blender are darker than the actually rendered image... Why?

我正在尝试创建一个管道,其中我首先使用搅拌机 python API(我使用的是 Blender 2.90)渲染图像,然后在 python.我想直接从搅拌机中获取图像,而不是先将渲染图像写入磁盘然后再次加载它。我 运行 在搅拌机 GUI 中使用以下代码来执行此操作:

import bpy
import numpy as np
import PIL.Image as Image 
from skimage.util import img_as_ubyte 

resolution_x = 512
resolution_y = 512

# render settings
scene = bpy.context.scene
scene.render.engine = 'BLENDER_EEVEE'
scene.render.resolution_x = resolution_x
scene.render.resolution_y = resolution_y
scene.render.image_settings.file_format = 'PNG'
scene.render.filepath = "path/to/good_image.png"

# create Viewer Layer in Compositor
scene.use_nodes = True
tree = scene.node_tree 
nodes = tree.nodes
links = tree.links

for node in nodes:
    nodes.remove(node)

render_layer_node = nodes.new('CompositorNodeRLayers')
viewer_node = nodes.new('CompositorNodeViewer')

links.new(viewer_node.inputs[0], render_layer_node.outputs[0])

# render scene and get pixels from Viewer Node
bpy.ops.render.render(write_still=True) 
pixels = bpy.data.images['Viewer Node'].pixels

# do some processing and save
img = np.flip(img_as_ubyte(np.array(pixels[:]).reshape((resolution_y, resolution_x, 4))), axis=0)
Image.fromarray(img).save("path/to/bad_image.png")

问题:我从查看器节点获得的图像暗得多 (bad image) than the image saved in the conventional way (good image)。有谁知道为什么会发生这种情况以及如何解决? Blender 处理像素值的方式可能与我预期的不同吗?

一些附加信息: 在转换为 uint8 之前,暗图像中 alpha 通道的值为 1.0(实际上应该是)。深色图像中的背景值不是 0.0 或负数(正如人们可能从 appea运行ce 中猜测的那样),而是 0.05...

我尝试了什么: 我认为像素可能会在 运行ge -1 到 1 范围内缩放,所以我在 t运行sforming 到 uint8 之前将像素重新缩放到 运行ge 0 到 1 ... 没有导致到正确的图像:(

这是因为您从 Viewer Node 获得的图像是颜色管理发生之前“直接合成”的图像。你可以看看文档here:这个图像仍然是线性的space。

另一方面,您的good_image.png是在转换为“显示Space”后获得的(参见文档中的图表)。因此它被转换成 log-space,也许是伽马校正等

最后,您可以通过调用 bpy.data.images['Viewer Node'].save_render(filepath) 从查看器节点获取接近(但略有不同)的好图像,但是无法直接提取颜色-托管版本,无需先呈现到文件。您可以通过将 PyOpenColorIO 添加到您的脚本并应用此模块的颜色管理来自己完成。