解决blender投影歪斜问题

是否会出现blender里面的obj投影到原始视频流上存在偏移的情况,前几次关于blender的博客中也存在这种问题,可以去看看,接下来我们给出一张样图, 如下图所示:

【解决方法】:用重投影方式,投影矩阵去给原始图像增加一定偏移量,这个偏移量的产生是因为blender中obj物体旋转的角度偏移量导致的。

python 复制代码
def process_video_with_objects(camera, video_path, output_dir, output_video_path, obj_dir, fps=30, camera_dict={}):
    os.makedirs(output_dir, exist_ok=True)
    K, R, T = camera_dict['K'], camera_dict['R'], camera_dict['T']
    video = cv2.VideoCapture(video_path)
    if not video.isOpened():
        raise ValueError(f"Could not open video file: {video_path}")
    input_width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
    input_height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    out_video = cv2.VideoWriter(output_video_path, fourcc, fps, (input_width, input_height), True)
    frame_idx = 0
    while True:
        ret, frame = video.read()
        if not ret:
            break
        bpy.context.scene.frame_set(frame_idx)
        scene = bpy.context.scene
        # Load corresponding .obj file for the current frame
        obj_files = sorted([f for f in os.listdir(obj_dir) if f.endswith('_{}.obj'.format(frame_idx + 1))])
        clear_scene(visual_axis, visual_mark, base_keypoints_dict)  # 清空非相机对象并筛选是否可视化坐标轴
        for obj_file in obj_files:
            bpy.ops.import_scene.obj(filepath=os.path.join(obj_dir, obj_file))  # 导入 obj 文件
        # 计算世界坐标原点在相机局部坐标系中的位置
        world_origin = Vector((0, 0, 0))  # 世界坐标原点
        render = bpy.context.scene.render
        # Get the two components to calculate M
        modelview_matrix = camera.matrix_world.inverted()
        # Get the depsgraph for the current scene
        depsgraph = bpy.context.evaluated_depsgraph_get()
        # Get the projection matrix
        projection_matrix = camera.calc_matrix_camera(
                depsgraph,
                x=render.resolution_x,
                y=render.resolution_y,
                scale_x=render.pixel_aspect_x,
                scale_y=render.pixel_aspect_y,
        )
        # Compute P' = M * P
        p1 = np.dot(projection_matrix @ modelview_matrix,  Vector((world_origin.x, world_origin.y, world_origin.z, 1)))
        p2 = Vector(((p1[0] / p1[3]), (p1[1] / p1[3])))
        pixel_x_now, pixel_y_now = (p2.x + 1) * 0.5 * render.resolution_x, (1 - p2.y) * 0.5 * render.resolution_y
        pixel_target = project_points_3d_to_2d(np.array([[0, 0, 0]]), K, R, T)
        shift_x_pixels, shift_y_pixels = (int(pixel_x_now - pixel_target[0][0])), (
            int(pixel_y_now - pixel_target[0][1]))
        frame = shift_image(frame, shift_x_pixels, shift_y_pixels)
     
        scene.render.resolution_x = input_width
        scene.render.resolution_y = input_height
        scene.render.film_transparent = True
        scene.camera = camera

        output_frame_path = os.path.join(output_dir, f'rendered_{frame_idx:04d}.png')
        scene.render.filepath = output_frame_path
        bpy.context.view_layer.update()
        bpy.ops.render.render(write_still=True)
        for obj in bpy.context.selected_objects:
            bpy.data.objects.remove(obj, do_unlink=True)
        rendered_frame = cv2.imread(output_frame_path, cv2.IMREAD_UNCHANGED)
        if rendered_frame is None:
            continue

        if rendered_frame.shape[2] == 3:
            rendered_frame = cv2.cvtColor(rendered_frame, cv2.COLOR_BGR2BGRA)

        alpha = rendered_frame[:, :, 3] / 255.0
        for c in range(0, 3):
            frame[:, :, c] = (1 - alpha) * frame[:, :, c] + alpha * rendered_frame[:, :, c]

        out_video.write(frame)
        frame_idx += 1

    video.release()
    out_video.release()
    print(f"Processed video saved to {output_video_path}")

结果可视化:

blender渲染里面设置透明度

python 复制代码
def createMaterial(color=(0.8, 0.8, 0.8, 0.5), metallic=0, roughness=0., alpha=0.5):
    color_count = [m.name for m in bpy.data.materials].count(str(color))
    if color_count > 0:
        color_index = [m.name for m in bpy.data.materials].index(str(color))
        matg = bpy.data.materials[color_index]
    else:
        matg = bpy.data.materials.new(str(color))
        matg.use_nodes = True
        tree = matg.node_tree
        nodes = tree.nodes
        links = tree.links

        for node in nodes:
            nodes.remove(node)

        # 添加必要的节点
        output = nodes.new(type='ShaderNodeOutputMaterial')
        bsdf = nodes.new(type='ShaderNodeBsdfPrincipled')
        transparent = nodes.new(type='ShaderNodeBsdfTransparent')
        mix_shader = nodes.new(type='ShaderNodeMixShader')
        bsdf.inputs["Base Color"].default_value = color
        bsdf.inputs["Metallic"].default_value = metallic
        bsdf.inputs["Roughness"].default_value = roughness
        mix_shader.inputs[0].default_value = 1 - alpha  # 透明度控制
        links.new(bsdf.outputs[0], mix_shader.inputs[2])      
        links.new(transparent.outputs[0], mix_shader.inputs[1]) 
        links.new(mix_shader.outputs[0], output.inputs[0])    
        matg.blend_method = 'BLEND'
        matg.shadow_method = 'HASHED'
    return matg
相关推荐
一刀不二4 小时前
blender 制作莫比乌斯带
blender
子燕若水4 小时前
blender merge点Vertices 补洞hole(建模基础操作)
算法·blender
兔子小姐_13 天前
如何下载Blender插件BlanderGIS
arcgis·gis·blender
子燕若水14 天前
Groom Blender to UE5
ue5·blender
成都渲染101云渲染666620 天前
Blender 4.3的12项更新一览
blender
AI视觉网奇20 天前
Blender 运行python脚本
blender
windy贺蕾蕾21 天前
blender如何使用nerf插件得到渲染好的二维图像和相机内外参数(blender数据集的构建)
算法·blender·nerf
AI视觉网奇21 天前
blender 视频背景
音视频·blender
Maya动画技术21 天前
blender4.2.3三视图alt+鼠标中键无法平移视图快捷键冲突解决方法
blender·视图平移快捷键失效问题解决