Render a Segmentation Map for an arbitrary Scene

As stated in the title I am trying to render a segmentation map for an arbitrary scene (all objects in a scene should have a different gray-tone). I am relatively new to Blender, and probably do not grasp all the internal relations that scenes may have. In theory, my approach is the following:

  1. Load the scene, for which I need a segmentation map.
  2. Change global settings such that only ambient light is contained in the scene.
  3. Get the total number of objects N in a scene and define color-steps as 1/N.
  4. Iterate over all objects: set material properties of object to last color plus color-step.
  5. Render

The Python Code which is supposed to do this job for me looks as follows:

Step 1:

bpy.ops.wm.open_mainfile(filepath=“path-to-my-scene.blend”)

Step 2:

bpy.data.worlds[“World”].light_settings.use_ambient_occlusion = True
bpy.data.worlds[“World”].horizon_color = (0,0,0)
bpy.data.worlds[“World”].zenith_color = (0,0,0)
bpy.data.worlds[“World”].ambient_color = (1,1,1)

Step 3:

N = len(bpy.context.scene.objects) + 1
colStep = 1/N
col = 0

Step 4:

for obj in bpy.context.scene.objects:
bpy.context.scene.objects.active = obj
if obj.type == ‘MESH’:
# Get material
if bpy.data.materials.get(“Material”) is not None:
mat = setMaterialProperties(col)
else:
mat = makeMaterial(‘Material’, col)
if len(obj.data.materials):
for material in obj.data.materials:
material = mat
else:
obj.data.materials.append(mat)
col = col + colStep

Step 5:

fnSegment = ‘path-to-segmentationFile.jpg’
bpy.data.scenes[0].render.filepath = fnSegment
bpy.ops.render.render( write_still=True )

#########################

In Step 4 the functions “setMaterialProperties” and “makeMaterial” are very similar, they both set specular intensity to 0, diffuse intensity to 0 and ambient intensity to the color value, which corresponds to the gray level the object should have:
mat.diffuse_intensity = 0.0
mat.specular_intensity = 0.0
mat.ambient = color

My output, sadly, does only very little look like the output I want to get :frowning: For some scenes all the objects have the same gray level, for other scenes I have lots of reflections on the (gray-level) objects, and again other scenes still have color after rendering.

Does anyone have a hint what I might be doing wrong?

Do you need to do this as a script ?
If not you can just set an over ride material to give each object a random colour using material nodes


Thanks, Richard, for the reply! It took me a couple of days to try your suggestion.

It works, but with a couple of downs:

  1. I was not successful in assigning specific colors w/o touching each object individually. This leads to
    a) possible color repetitions
    b) changing object colors when rendering a scene repeatedly
  2. I tried to script the overlay with a random material, but sadly failed again. Scripting would be really helpful, as I have roughly 40 different scenes, with a total of 1600 different content combinations for which I would like to generate segmentation maps. Manual steps are possible, but if I can reduce those to a minimum, that would be awesome!

You can also use the vision_blender addon for this. It generates segmentation masks when you render an image.

1 Like

Perhaps a segmentation of the code will help to do!