DLR-RM / BlenderProc

A procedural Blender pipeline for photorealistic training image generation
GNU General Public License v3.0
2.83k stars 452 forks source link

[BUG]: Changing film exposure breaks segmap rendering #692

Closed jczarnowski closed 2 years ago

jczarnowski commented 2 years ago

Issue

Setting the cycles film exposure via bpy.context.scene.cycles.film_exposure to a value sufficiently larger than the default 1 shifts the colors in the instance segmentation render, causing them to map back to incorrect object indices and trigger a check in render_segmap():

Error: Python: Traceback (most recent call last):
  File "/exposure_bug.py", line 17, in <module>
  File "/home/BOSDYN/jczarnowski/code/BlenderProc/blenderproc/python/renderer/SegMapRendererUtility.py", line 123, in render_segmap
    raise Exception("There are more object colors than there are objects")
Exception: There are more object colors than there are objects

Steps to reproduce

import blenderproc as bproc
import bpy
import numpy as np

bproc.init()
bpy.ops.mesh.primitive_monkey_add(location=[0,0,0])

cam_pos = np.array([2, 2, 2])
rotation_matrix = bproc.camera.rotation_from_forward_vec(-cam_pos, up_axis='Y')
cam2world_matrix = bproc.math.build_transformation_mat(cam_pos, rotation_matrix)
bproc.camera.add_camera_pose(cam2world_matrix)

bpy.context.scene.cycles.film_exposure = 10

bproc.renderer.render()
bproc.renderer.render_segmap(map_by=["class", "instance", "name"])

Solution

For a workaround, I added setting the exposure to the safe value within the UndoAfterExecution() block in render_segmap():

diff --git a/blenderproc/python/renderer/SegMapRendererUtility.py b/blenderproc/python/renderer/SegMapRendererUtility.py
index f13b89f4..537e548b 100644
--- a/blenderproc/python/renderer/SegMapRendererUtility.py
+++ b/blenderproc/python/renderer/SegMapRendererUtility.py
@@ -53,6 +53,7 @@ def render_segmap(output_dir: Optional[str] = None, temp_dir: Optional[str] = No
         RendererUtility.set_noise_threshold(0)
         RendererUtility.set_denoiser(None)
         RendererUtility.set_light_bounces(1, 0, 0, 1, 0, 8, 0)
+        bpy.context.scene.cycles.film_exposure = 1

         attributes = map_by
         if 'class' in default_values:

Alternatively, the indices saved in the EXR with changed exposure should technically still be unique as exposure is a global change. Maybe you could re-enumerate them to new sequential indices?

themasterlink commented 2 years ago

Hey,

thanks for this report.

We are currently working on integrating the semantic segmentation inside the usual render call removing this issue completely.

Best, Max

themasterlink commented 2 years ago

Hey,

I started on a PR for this, see #693. This will solve this problem completely.

This PR is not done, yet. I haven't tested it properly.

Best, Max

themasterlink commented 2 years ago

This should no longer be an issue as the segmap rendering is now integrated into the normal render pass.