DIYer22 / bpycv

Computer vision utils for Blender (generate instance annoatation, depth and 6D pose by one line code)
MIT License
464 stars 58 forks source link

Wrong instance segmentation map with many objects #52

Open s70c3 opened 5 months ago

s70c3 commented 5 months ago

Hi! Thanks for the awesome blender util!

I use your util to create a segmentation map for bunch of clumped objects created with instances and geocodes. I realized before creating instance map and reassigned with data.copy(). The problem is that I have more than 100 objects on area, but some objects still have the same color on instance map, limited to 20-30. I used a lot of attempts to change inst_id, but situation stayed the same. How can I fix it?

Here is the code (some hacks was used to work with material, so code is not perfect)

for img_num in range(1):
    # remove all MESH objects
    bpy.ops.wm.read_homefile()
    update_camera(bpy.data.objects['Camera'])
    update_light(bpy.data.objects['Light'])
    with bpy.data.libraries.load('rocks.blend') as (data_from, data_to):
        data_to.collections = data_from.collections
    with bpy.data.libraries.load('froth_gm.blend') as (data_from, data_to):
        data_to.materials = data_from.materials

    # bpy.ops.mesh.primitive_cube_add(size=1, location=(0,0,0))
    cube =  bpy.data.objects.get('Cube')

    modifier=cube.modifiers.new("Bubbles", "NODES")
    modifier.node_group = geometry_nodes_node_group1(seed=(2,4, 3), dists=(70.0, 50.0, 50))

    for scene in bpy.data.scenes:
      scene.cycles.device = 'GPU'

    prefs = bpy.context.preferences
    cprefs = prefs.addons['cycles'].preferences
    bpy.context.scene.render.engine = 'CYCLES'
    bpy.context.preferences.addons[
        "cycles"
    ].preferences.compute_device_type = "CUDA" # or "OPENCL"
    # bpy.context.scene.cycles.samples = 32
    # Set the device and feature set
    bpy.context.scene.cycles.device = "GPU"

    result = bpycv.render_data()
    # save result
    cv2.imwrite(
        f"img{img_num}.jpg", result["image"][..., ::-1]
    )  # transfer RGB image to opencv's BGR

    # modifier=cube.modifiers.new("Bubbles", "NODES")
    modifier.node_group = geometry_nodes_node_group2(seed=(2, 4, 3),  dists=(70.0, 50.0, 50))

    cube.select_set(True)
    bpy.context.view_layer.objects.active = cube
    bpy.ops.object.mode_set(mode='OBJECT')
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.mesh.select_all(action='SELECT')
    bpy.ops.object.mode_set(mode='OBJECT')
    bpy.ops.object.duplicates_make_real()

    for i, o in enumerate(bpy.data.objects):
        if o.type in ("MESH", "CURVE"):
            o.data=o.data.copy()
            o["inst_id"] = randint(1, 8)*1000+i

    bpy.context.scene.render.engine = 'BLENDER_EEVEE'

    bpy.context.scene.render.resolution_y = 512
    bpy.context.scene.render.resolution_x = 512

    bpy.context.view_layer.cycles.use_denoising = True
    bpy.context.view_layer.cycles.denoising_store_passes = True
    bpy.context.scene.cycles.samples = 200
    # Set the device and feature set
    bpy.context.scene.cycles.device = "GPU"

    result = bpycv.render_data(render_image=False)
    objs = {
                obj.name: obj for obj in bpy.data.objects if obj.type in ("MESH", "CURVE")
            }

    print(len(objs))
    cv2.imwrite(f"mask{img_num}.png", np.uint16(result["inst"]))
    cv2.imwrite(f"demo-vis{img_num}.jpg", result.vis()[..., ::-1])

Here are the examples of render and instance map.

image image
zsy950116 commented 5 months ago

您好,您的邮件我已经接收。

DIYer22 commented 5 months ago

I don't quite understand this issue. But How about try:

    for i, o in enumerate(bpy.data.objects):
        if o.type in ("MESH", "CURVE"):
            o.data=o.data.copy()
            o["inst_id"] = i + 1

or o["inst_id"] = 2*i + 1