PyTorch3D Implicitron render_flyaround 详解:用相机环绕轨迹将 3D 重建模型渲染为可视化视频
2026/9/24 22:19:22 网站建设 项目流程
  • 人工智能
  • 深度学习
  • 计算机视觉
  • 图形学

【免费下载链接】pytorch3d

PyTorch3D is FAIR's library of reusable components for deep learning with 3D data

项目地址:https://gitcode.com/gh_mirrors/py/pytorch3d
点击查看免费下载

导读

render_flyaround是 PyTorch3D Implicitron 中负责"场景环绕渲染"的核心可视化函数:它读取一个训练/测试序列的全部帧数据,围绕场景生成一条相机飞行轨迹,逐帧调用训练好的模型进行渲染,最终合成一个 mp4 视频,输出该场景从多视角观测的重建结果(RGB 图、掩码、深度图)。本文以 render_flyaround.rst 为主线,完整讲解该函数的全部 22 个参数、四种相机轨迹类型、从数据加载到视频导出的完整工作流,并结合源码、CLI 脚本与测试用例,给出可直接运行的实战方案。

一、函数定位与文档来源

docs/modules/implicitron/models/visualization/render_flyaround.rst本身是一个 Sphinx 文档占位文件,通过automodule指令自动抽取源码中的 docstring 生成 API 文档:

.. automodule:: pytorch3d.implicitron.models.visualization.render_flyaround :members: :undoc-members: :show-inheritance:

因此该文档的"正体"是 render_flyaround.py 中的render_flyaround函数(定义于第 49 行)及其完整的参数文档。该函数处于 Implicitron 可视化工具链的顶层,向下依次依赖:

  • eval_video_trajectory.py 中的generate_eval_video_cameras:负责生成相机轨迹;
  • video_writer.py 中的VideoWriter:负责把渲染帧编码为视频;
  • vis_utils.py 中的get_visdom_connectionmake_depth_image:负责 visdom 可视化与深度图伪彩色化。

从源码结构看,render_flyaround是 Implicitron 模型评估与结果展示的重要出口:训练好的 NeRF、NeRFormer、SRN 等通用模型(GenericModel 体系)都可以直接接入该函数完成环绕视频导出。

二、函数签名与全部参数详解

def render_flyaround( dataset: DatasetBase, sequence_name: str, model: torch.nn.Module, output_video_path: str, n_flyaround_poses: int = 40, fps: int = 20, trajectory_type: str = "circular_lsq_fit", max_angle: float = 2 * math.pi, trajectory_scale: float = 1.1, scene_center: Tuple[float, float, float] = (0.0, 0.0, 0.0), up: Tuple[float, float, float] = (0.0, -1.0, 0.0), traj_offset: float = 0.0, n_source_views: int = 9, visdom_show_preds: bool = False, visdom_environment: str = "render_flyaround", visdom_server: str = "http://127.0.0.1", visdom_port: int = 8097, num_workers: int = 10, device: Union[str, torch.device] = "cuda", seed: Optional[int] = None, video_resize: Optional[Tuple[int, int]] = None, output_video_frames_dir: Optional[str] = None, visualize_preds_keys: Sequence[str] = ( "images_render", "masks_render", "depths_render", "_all_source_images", ), ) -> None:

各参数按职责可分为四组:

1. 输入与输出核心参数

参数默认值说明
dataset必填包含sequence_name场景全部帧的DatasetBase数据集对象(Implicitron 的 dataset_base.py 体系)
sequence_name必填要可视化的场景在dataset中的名称
model必填用于预测的模型(torch.nn.Module),其输出字典需包含visualize_preds_keys指定的键
output_video_path必填输出视频的文件路径(实际产出为{output_video_path}_{sequence_name}_{key}.mp4多个文件)

2. 相机轨迹参数

参数默认值说明
n_flyaround_poses40环绕轨迹上的相机位姿数量,即视频总帧数
fps20输出视频帧率
trajectory_type"circular_lsq_fit"轨迹类型,支持四种,详见下文"四种相机轨迹"小节
max_angle轨迹总长度。所有轨迹都以time == 2π为周期,例如circular_lsq_fit配合time=4π会让相机绕物体旋转 720°
trajectory_scale1.1轨迹的尺度(半径/幅度缩放因子)
scene_center(0.0, 0.0, 0.0)场景中心的世界坐标,轨迹上所有相机都看向该点
up(0.0, -1.0, 0.0)场景的"上"向量(即场景地面的法线),对circular_lsq_fit轨迹生效
traj_offset0.0加到轨迹每个点上的 3D 偏移向量(注:源码中作为traj_offset_canonical=(0.0, 0.0, traj_offset)传入,即作用于轨迹局部坐标系的 z 轴)

3. 模型输入与批处理参数

参数默认值说明
n_source_views9从训练序列已知视角中采样、加入每个评估批次的源视角数量。这类源视角是 NeRFormer、NeRF-WCE 等模型的必需输入(见 visualize_reconstruction.py 第 59-60 行注释)
num_workers10加载训练数据的 DataLoader worker 数量
device"cuda"模型推理设备
seedNone源视角可复现采样的随机种子;为None时使用hash(sequence_name)(源码第 138-139 行)

4. 可视化与输出格式参数

参数默认值说明
visdom_show_predsFalseTrue时将预测结果同步导出到 visdom
visdom_environment"render_flyaround"visdom 环境名
visdom_server"http://127.0.0.1"visdom 服务器地址
visdom_port8097visdom 端口
video_resizeNone可选,定义输出视频尺寸(H, W)
output_video_frames_dirNone若指定,视频的逐帧图像会永久存储到该目录(否则使用临时目录)
visualize_preds_keys见上要可视化的模型预测键名序列,默认包含渲染图、掩码、深度图和源视角拼图

三、四种相机轨迹类型

trajectory_type支持四种轨迹(源码 eval_video_trajectory.py 第 84-163 行):

  1. circular_lsq_fit(默认):对训练相机的光心进行 3D 圆拟合,相机中心沿拟合出的圆运动,所有相机始终看向scene_center。拟合逻辑由 circle_fitting.py 的fit_circle_in_3d实现,拟合后轨迹还会以trajectory_scale缩放(源码第 154-155 行)。

  2. figure_eight:围绕训练数据集"中心相机"(离所有相机光心均值最近的相机)画 8 字轨迹,参数方程为(源码第 266-269 行):

    x = t.cos() y = (2 * t).sin() / 2 z = t.sin() * z_scale
  3. trefoil_knot:三叶结轨迹,参数方程为(源码第 259-263 行):

    x = t.sin() + 2 * (2 * t).sin() y = t.cos() - 2 * (2 * t).cos() z = -(3 * t).sin() * z_scale
  4. figure_eight_knot:八字结轨迹,参数方程为(源码第 252-256 行):

    x = (2 + (2 * t).cos()) * (3 * t).cos() y = (2 + (2 * t).cos()) * (3 * t).sin() z = (4 * t).sin() * z_scale

对于三种结轨迹(figure_eight/trefoil_knot/figure_eight_knot),其参数曲线先生成于规范坐标系,再通过Scale(cam_centers.std(dim=0).mean() * trajectory_scale)与中心相机的世界到视图变换逆矩阵转换到场景坐标系(源码第 109-124 行),并以infer_up_as_plane_normal=True自动把up向量推断为相机光心拟合平面的法线(源码第 126-128 行)。最终所有轨迹都会经过look_at_view_transform(见 cameras.py)统一看向scene_center,且若focal_length/principal_point未指定,会取训练相机相应参数的平均值构造PerspectiveCameras(源码第 177-190 行)。

trajectory_type还有两个隐藏的净化开关:remove_outliers_rate在大于 0 时可移除训练相机中的离群光心(按每个维度上下各裁掉指定比例),使轨迹拟合更稳健(源码第 81-82 行、第 200-214 行)。

四、完整工作流程解析

render_flyaround的执行过程可以拆解为六个阶段(对照源码 render_flyaround.py 第 138-222 行):

阶段 1:加载整条序列

通过sequence_indices_in_order(sequence_name)拿到序列帧索引,用_load_whole_dataset(源码第 225-235 行)构造一个batch_size=len(idx)的 DataLoader 一次性加载全部帧,并以FrameData.collate整理为FrameData批次。随后用is_train_frame判断该序列属于 train 还是 test 集合(源码第 151 行)。

阶段 2:生成环绕相机轨迹

time = torch.linspace(0, max_angle, n_flyaround_poses + 1)[:n_flyaround_poses] test_cameras = generate_eval_video_cameras( train_cameras, time=time, n_eval_cams=n_flyaround_poses, trajectory_type=trajectory_type, trajectory_scale=trajectory_scale, scene_center=scene_center, up=up, focal_length=None, principal_point=torch.zeros(n_flyaround_poses, 2), traj_offset_canonical=(0.0, 0.0, traj_offset), )

time[0, max_angle]上均匀取n_flyaround_poses个采样点,作为轨迹参数方程的输入(源码第 154 行)。注意这里principal_point被显式置零,而focal_lengthNone以使用训练相机的平均焦距。

阶段 3:可复现地采样源视角

with torch.random.fork_rng(): torch.manual_seed(seed) source_views_i = torch.randperm(len(seq_idx))[:n_source_views]

使用fork_rng隔离随机状态,保证源视角采样不污染全局随机数生成器;随后在批次头部pad一个占位视图,该视图会被逐帧替换为目标相机(源码第 169-175 行)。

阶段 4:逐帧渲染

n_flyaround_poses中的每一帧:

  1. test_cameras[n]RTfocal_lengthprincipal_point写入批次首个相机(源码第 182-183 行);
  2. 将整个批次搬到device,在torch.no_grad()下以EvaluationMode.EVALUATION调用模型(源码第 186-188 行);
  3. 将模型预测与网络输入合并为一个大字典,调用_images_from_predsvisualize_preds_keys抽取并预处理成可视化图像(源码第 191-196 行);
  4. 若开启 visdom,每 5% 的迭代(n % max(n_flyaround_poses // 20, 1) == 0)调用_show_predictions推送一次中间结果(源码第 199-209 行)。

_images_from_preds(源码第 238-271 行)内部做了三类关键处理:

  • depth开头的键,用masks_render作掩码插值后调用make_depth_image生成伪彩色深度图;
  • _all_source_images特殊键,从preds["image_rgb"][1:]取源视角并用_stack_images拼成网格图(源码第 274-286 行);
  • 对单通道图自动repeat(1, 3, 1, 1)扩成 RGB。

阶段 5:生成视频

_generate_prediction_videos(源码第 335-393 行)为每个预测键创建一个VideoWriter

vws[k] = VideoWriter( fps=fps, out_path=f"{video_path}_{sequence_name}_{k}.mp4", cache_dir=cache_dir, )

随后逐帧写入并调用get_video()编码。VideoWriter(video_writer.py 第 34-214 行)默认调用系统ffmpeg(可用环境变量FFMPEG覆盖,_DEFAULT_FFMPEG = os.environ.get("FFMPEG", "ffmpeg")),使用h264编码、crf=18b=2000kpix_fmt=yuv420p参数;也可设置use_torchvision_video_writer=True改用torchvision.io.write_video。帧尺寸会被强制调整为偶数(resize[i] + resize[i] % 2)。

阶段 6:visdom 推送

viz非空,把每个生成的视频文件通过viz.video(...)推送到 visdom 指定环境,窗口名复用预测键名(源码第 387-392 行)。

五、实战:从训练好的模型一键导出环绕视频

方式一:使用官方 CLI 脚本

Implicitron 训练工程提供了封装好的可视化入口 visualize_reconstruction.py,其模块 docstring 给出了典型命令行调用:

pytorch3d_implicitron_visualizer \ exp_dir='./exps/checkpoint_dir' visdom_show_preds=True visdom_port=8097 \ n_eval_cameras=40 render_size="[64,64]" video_size="[256,256]"

该脚本的核心参数包括:

参数默认值说明
exp_dir""存放已训练模型与expconfig.yaml的实验目录
restrict_sequence_nameNone若设置,仅可视化指定场景序列
output_directoryNone自定义输出目录;默认输出到{exp_dir}/vis
render_size(512, 512)生成渲染的分辨率,会覆盖模型配置中的render_image_width/height(源码第 98-99 行)
video_sizeNone输出视频尺寸,透传给video_resize
split"train"数据集划分,可选"train"/"val"/"test"
n_source_views9每个批次附加的源视角数量
n_eval_cameras40每条环绕轨迹的相机数量,映射为n_flyaround_poses
visdom_*visdom 开关、服务器、端口与环境名

脚本会从实验目录加载expconfig.yaml,用force_resume=True恢复模型权重,遍历数据集中的每个序列,在torch.no_grad()下逐序列调用render_flyaround(源码第 121-139 行)。注意第 85-92 行的关键行为:为确保 CO3D 数据集全量加载,脚本会强制test_on_train=False,并支持通过restrict_sequence_name过滤序列。

方式二:在代码中直接调用

测试用例 test_model_visualize.py 第 82-110 行展示了一个完整的直接调用示例:

render_flyaround( train_dataset, show_sequence_name, model, video_path, n_flyaround_poses=10, fps=5, max_angle=2 * math.pi, trajectory_type="circular_lsq_fit", trajectory_scale=1.1, scene_center=(0.0, 0.0, 0.0), up=(0.0, 1.0, 0.0), traj_offset=1.0, n_source_views=1, visdom_show_preds=visdom_show_preds, visdom_environment="test_model_visalize", visdom_server="http://127.0.0.1", visdom_port=8097, num_workers=10, seed=None, video_resize=None, visualize_preds_keys=[ "images_render", "depths_render", "masks_render", "_all_source_images", ], output_video_frames_dir=output_video_frames_dir, )

该测试还展示了自定义模型的最低要求:模型只需在forward中接受camera等 Implicitron 批次字段,并返回包含images_rendermasks_renderdepths_render的字典(见_PointcloudRenderingModel,第 113-153 行),即可被render_flyaround驱动。同时测试验证了output_video_frames_dirNone或指定目录两种模式均可工作。

运行前提

  • 视频导出依赖系统安装ffmpeg(或通过环境变量FFMPEG指定可执行文件路径);
  • visdom 功能需要在环境中安装visdom并启动 visdom 服务(默认http://127.0.0.1:8097);get_visdom_connectionvisdom不可导入时会静默返回None(vis_utils.py 第 58-62 行),不影响视频生成;
  • 默认device="cuda",需要可用 GPU;纯 CPU 环境需显式传入device="cpu"
  • 该测试用例本身需要interactive_testing_requested()与 visdom 连接才执行,属于交互式/人工验收类测试(第 31-32 行、第 64 行)。

六、可视化内容与输出物约定

visualize_preds_keys默认输出四类内容,每类对应一个独立 mp4:

  1. images_render:模型渲染的 RGB 重建图;
  2. masks_render:前景掩码;
  3. depths_render:经make_depth_image伪彩色化的深度图(渲染前会用masks_render做最近邻插值作为深度掩码,源码第 260-266 行);
  4. _all_source_images:当前批次所用源视角的网格拼图,用于对照"模型看到了哪些输入"。

输出文件命名规则为{output_video_path}_{sequence_name}_{key}.mp4。若指定了output_video_frames_dir,逐帧 PNG(frame_%08d.png)会持久保存在{output_video_frames_dir}/{sequence_name}_{key}目录下,便于逐帧检查或二次剪辑。

七、小结

render_flyaround是 PyTorch3D Implicitron 面向"多视角重建结果展示"的标准可视化组件,它将"数据集加载 → 轨迹生成 → 源视角采样 → 批量推理 → 视频编码"封装为一次调用,配合四种参数化轨迹(圆拟合、8 字、三叶结、八字结)与可配置的输出键,既能用于训练过程中的实时监控(visdom),也能用于训练完成后的离线结果交付(mp4 + 帧目录)。其完整 API 文档由 render_flyaround.rst 通过automodule自动生成,本文给出的参数语义、运行流程与调用示例均与 render_flyaround.py 源码、visualize_reconstruction.py CLI 与 test_model_visualize.py 测试逐行对应,可直接作为二次开发与排障的参考。

  • 人工智能
  • 深度学习
  • 计算机视觉
  • 图形学

【免费下载链接】pytorch3d

PyTorch3D is FAIR's library of reusable components for deep learning with 3D data

项目地址:https://gitcode.com/gh_mirrors/py/pytorch3d
点击查看免费下载

相关推荐

上一篇:5分钟视频修复指南:使用untrunc无损拯救损坏的MP4/MOV文件终极教程
下一篇:AMD GPU的AI计算革命:ZLUDA技术如何重塑Stable Diffusion生态

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询