1
$\begingroup$

I am using a node setup to render objects on top of a background image through the Python API.

EDIT: To make it more clear, I have reproduced the situation in Blender GUI: blender

My Note Setup:

def node_setting_init():
"""node settings for render rgb images

mainly for compositing the background images
"""

bpy.context.scene.use_nodes = True
tree = bpy.context.scene.node_tree
links = tree.links

for node in tree.nodes:
    tree.nodes.remove(node)

image_node = tree.nodes.new('CompositorNodeImage')
scale_node = tree.nodes.new('CompositorNodeScale')
alpha_over_node = tree.nodes.new('CompositorNodeAlphaOver')
render_layer_node = tree.nodes.new('CompositorNodeRLayers')
file_output_node = tree.nodes.new('CompositorNodeOutputFile')

# Scales image to dimensions set in the Render panel, my case 1280x720
scale_node.space = g_scale_space 

# Select output folder, i.e. where to store rendered images
file_output_node.base_path = g_syn_rgb_folder

# Scale background image
links.new(image_node.outputs[0], scale_node.inputs[0])

# Set background image as background image input to alpha node
links.new(scale_node.outputs[0], alpha_over_node.inputs[1]) #1

# Set rendered object as the foreground image to alpha node
links.new(render_layer_node.outputs[0], alpha_over_node.inputs[2]) #2

# Final image is the output image
links.new(alpha_over_node.outputs[0], file_output_node.inputs[0])

My rendering function:

def render(obj_path, viewpoint):
"""render rbg image 

render a object rgb image by a given camera viewpoint and
choose random image as background, only render one image
at a time.

Args:
    obj_path: a string variable indicate the obj file path
    viewpoint: a vp parameter(contains azimuth,elevation,tilt angles and distance)
"""

background_images = os.listdir(g_background_image_path)

# Set camera to the viewpoint
vp = viewpoint
cam_location = camera_location(vp.azimuth, vp.elevation, vp.distance)
cam_rot = camera_rot_XYZEuler(vp.azimuth, vp.elevation, vp.tilt)

cam_obj = bpy.data.objects['Camera']
cam_obj.location[0] = cam_location[0]
cam_obj.location[1] = cam_location[1]
cam_obj.location[2] = cam_location[2]

cam_obj.rotation_euler[0] = cam_rot[0]
cam_obj.rotation_euler[1] = cam_rot[1]
cam_obj.rotation_euler[2] = cam_rot[2]

# Make dir to store output rgb images
if not os.path.exists(g_syn_rgb_folder):
    os.mkdir(g_syn_rgb_folder)

# get random background from background_images folder
image_name = random.choice(background_images)
image_path = os.path.join(g_background_image_path, image_name)
print("\n\nBackground chosen:{}\n\n".format(image_path))

# Load background image and set output file
image_node = bpy.context.scene.node_tree.nodes[0]
image_node.image = bpy.data.images.load(image_path)
file_output_node = bpy.context.scene.node_tree.nodes[4]
file_output_node.file_slots[0].path = 'blender-######.color.png' # blender placeholder #

#start rendering
bpy.ops.render.render(write_still=True)

#"Current Frame, to update animation data from python frame_set() instead"
current_frame = bpy.context.scene.frame_current
#"Set scene frame updating all objects immediately"
bpy.context.scene.frame_set(current_frame + 1)

So I initiliaze:

def init_all():
"""init everything we need for rendering
an image
"""
scene_setting_init(g_gpu_render_enable)
node_setting_init()
cam_obj = bpy.data.objects['Camera']
cam_obj.rotation_mode = g_rotation_mode

#bpy.data.objects['Lamp'].data.energy = 50
#bpy.ops.object.lamp_add(type='SUN')
#xavier:
bpy.types.SpotLight.energy = 50

And call render()

So I am setting node[0], to my background image and I render it. However, my object is rendered on a grey background; my image nowhere to be found. I am pretty sure this worked for version 2.79, but I am running 2.83. I know quite a lot changed between these versions, but I can't find a proper tutorial or answer online.

(I have also tried to set the background image via the camera object, but still no luck.)

This is the result. No background present.

Rendered image, no background...

If I put the background image as foreground, and the object as background:

# Set background image as FOREGROUND image input to alpha node
links.new(scale_node.outputs[0], alpha_over_node.inputs[2]) #1

# Set rendered object as the BACKGROUND image to alpha node
links.new(render_layer_node.outputs[0], alpha_over_node.inputs[1]) #2

Now I only see the background, which makes sense I guess.

background as foreground

So something is going wrong with combining the images.

$\endgroup$

1 Answer 1

1
$\begingroup$

You have to set the background transparent, otherwise you will render the grey part onto the images.

In Blender GUI:

Go to the Render properties tab > Film dropdown and check Transparent. This will tell Blender to only render the cube as opposed to the cube and the gray background.

In Python API:

bpy.context.scene.render.film_transparent = True
$\endgroup$
1
  • $\begingroup$ thank you so much I was searching for hours and I couldn't get to the root of the problem. this one liner saved me <3 $\endgroup$
    – Evan
    Commented Mar 4, 2022 at 6:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .