def add_camera_image_plane(
    matrix_world,
    blender_image,
    camera,
    name,
    transparency,
    add_image_plane_emission,
    image_planes_collection,
    op=None,
):
    """Add an image plane corresponding to a reconstructed camera."""
    # log_report('INFO', 'add_camera_image_plane: ...', op)
    # log_report('INFO', 'name: ' + str(name), op)

    width = camera.width
    height = camera.height
    focal_length = camera.get_focal_length()

    assert width is not None and height is not None

    bpy.context.scene.render.engine = "CYCLES"
    mesh = bpy.data.meshes.new(name)
    mesh.update()
    mesh.validate()

    plane_distance = 1.0  # Distance from camera position
    # Right vector in view frustum at plane_distance:
    right = Vector((1, 0, 0)) * (width / focal_length) * plane_distance
    # Up vector in view frustum at plane_distance:
    up = Vector((0, 1, 0)) * (height / focal_length) * plane_distance
    # Camera view direction:
    view_dir = -Vector((0, 0, 1)) * plane_distance
    plane_center = view_dir

    shift_x, shift_y = compute_principal_point_shift(
        camera, relativ_to_largest_extend=False
    )

    corners = ((-0.5, -0.5), (+0.5, -0.5), (+0.5, +0.5), (-0.5, +0.5))
    points = [
        (plane_center + (c[0] + shift_x) * right + (c[1] + shift_y) * up)[0:3]
        for c in corners
    ]
    mesh.from_pydata(points, [], [[0, 1, 2, 3]])
    mesh.uv_layers.new()

    # Add mesh to new image plane object:
    mesh_obj = add_obj(mesh, name, image_planes_collection)

    image_plane_material = bpy.data.materials.new(name="image_plane_material")
    # Adds "Principled BSDF" and a "Material Output" node
    image_plane_material.use_nodes = True

    nodes = image_plane_material.node_tree.nodes
    links = image_plane_material.node_tree.links

    shader_node_tex_image = nodes.new(type="ShaderNodeTexImage")
    shader_node_principled_bsdf = nodes.get("Principled BSDF")
    shader_node_principled_bsdf.inputs["Alpha"].default_value = transparency

    links.new(
        shader_node_tex_image.outputs["Color"],
        shader_node_principled_bsdf.inputs["Base Color"],
    )

    if add_image_plane_emission:
        links.new(
            shader_node_tex_image.outputs["Color"],
            shader_node_principled_bsdf.inputs["Emission Color"],
        )

    shader_node_tex_image.image = blender_image

    # Assign it to object
    if mesh_obj.data.materials:
        # assign to 1st material slot
        mesh_obj.data.materials[0] = image_plane_material
    else:
        # no slots
        mesh_obj.data.materials.append(image_plane_material)

    mesh_obj.matrix_world = matrix_world
    mesh.update()
    mesh.validate()
    # log_report('INFO', 'add_camera_image_plane: Done', op)
    return mesh_obj
Add an image plane corresponding to a reconstructed camera.
photogrammetry_importer/importers/camera_utility.py