{"componentChunkName":"component---src-templates-acg-portal-new-template-tsx","path":"/Tmu0pyy1k","result":{"data":{"markdownRemark":{"html":"<h2 id=\"简介\"><a href=\"#%E7%AE%80%E4%BB%8B\" aria-label=\"简介 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>简介</h2>\n<p>视频相机位姿估计算子。抽帧后先用 MoGe-2 逐帧估计单目深度与内参，再把 (image, depth, intrinsics) 喂给 MegaSaM 的 DROID-SLAM 做跟踪与全局 bundle adjustment，输出相机内参与每帧 camera-to-world 位姿。仅支持 GPU，三个 CUDA 扩展与全部权重必须离线预置，算子内零网络零编译。</p>\n<h3 id=\"功能描述\"><a href=\"#%E5%8A%9F%E8%83%BD%E6%8F%8F%E8%BF%B0\" aria-label=\"功能描述 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>功能描述</h3>\n<ul>\n<li>两级流水线：MoGe-2 出的是<strong>归一化内参</strong>，乘回 width / height 变成像素单位；第二级把每帧等比缩放到 384×512 面积、裁到 8 的倍数，内参同步按缩放比修正，深度用 <code>nearest-exact</code> 插值到同尺寸</li>\n<li>DROID 吃的是原始通道序（BGR），本实现不做转换；落 npz 时才转回 <code>(T,H,W,3)</code> RGB，与 mega-sam <code>cvd_opt</code> 的约定一致</li>\n<li>逐帧 <code>track</code> → <code>track_final</code> → <code>terminate(_opt_intr=opt_intrinsics, full_ba=full_ba)</code> 做全局 BA；内参取 <code>droid.video.intrinsics[0] * 8.0</code>（SLAM 在 1/8 特征分辨率上算），位姿用 <code>lietorch.SE3(traj).inv().matrix()</code> 从 w2c 转成 c2w</li>\n<li>DROID 全部超参（<code>buffer</code> / <code>filter_thresh</code> / <code>warmup</code> / <code>keyframe_thresh</code> / frontend 四项 / backend 三项 / <code>beta</code>）逐个开放为算子参数，以普通对象而非 dict 传入（DROID 内部直接读属性）</li>\n<li><code>count_k</code><strong>默认 64</strong>：DROID 的 <code>warmup=8</code> 意味着 3 帧根本起不了轨迹；另加前置检查，抽到的帧数少于 <code>warmup</code> 时直接给出「调大 <code>count_k</code> / <code>max_frames</code>」的错误信息，而不是让 SLAM 崩在内部</li>\n<li><strong>大张量不进列</strong>：<code>intrinsic</code> / <code>cam_c2w</code> 以 <code>{shape, data}</code>（形状 + 一维 float32）存出，<code>depths</code> 默认关闭，images 完全不进列（一段 300 帧视频的 images 与 depths 是百 MB 量级）。需要完整产物时设 <code>output_npz_dir</code>，落成键名与 mega-sam <code>cvd_opt</code> 一致（<code>images</code> / <code>depths</code> / <code>intrinsic</code> / <code>cam_c2w</code>）的 npz，文件名为 <code>&#x3C;视频名>_droid.npz</code>（视频名取路径/URL 去参数后的 stem，取不到用 <code>video_&#x3C;行号></code>）</li>\n<li><code>torch.load</code> 打补丁：mega-sam 的 <code>Droid.load_weights</code> 是裸 <code>torch.load</code>，torch>=2.6 默认 <code>weights_only=True</code> 会失败，构建 Droid 期间临时包一层 <code>weights_only=False</code>，构建完立即还原</li>\n<li>两个源自 DROID 本身的既有行为：① <code>full_ba=True</code> 时 DROID 返回的是<strong>关键帧</strong>轨迹 <code>video.poses[:counter]</code>，逐帧的 <code>traj_filler</code> 结果在这条分支里被算出来又丢弃，所以 <code>frame_count</code> 通常小于抽帧数（实测抽 32 帧出 31 个关键帧）；② 输出的 <code>depths</code> 是 MoGe 深度按 SLAM 分辨率缩放后的结果，<strong>不是</strong> BA 优化后的 <code>depth_est</code>（BA 返回的优化深度未被使用）</li>\n<li>抽帧走 <code>VideoFrameSampler</code> 在内存里完成，不把帧写盘；输入支持 <code>video_url</code>（含 BOS 路径）、<code>video_base64</code>、<code>video_binary</code></li>\n<li>抽不到帧或单个视频估计失败时，该行张量为空、<code>npz_path</code> 为空串、<code>status</code> 记录原因，不中断整列；每个视频处理完调 <code>torch.cuda.empty_cache()</code></li>\n</ul>\n<h2 id=\"算子参数\"><a href=\"#%E7%AE%97%E5%AD%90%E5%8F%82%E6%95%B0\" aria-label=\"算子参数 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>算子参数</h2>\n<h3 id=\"输入\"><a href=\"#%E8%BE%93%E5%85%A5\" aria-label=\"输入 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>输入</h3>\n<table>\n<thead>\n<tr>\n<th>输入</th>\n<th>含义</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>videos</td>\n<td>视频列。按 video_src_type 取值分别是视频路径/URL（含 bos://）、base64 字符串或二进制内容</td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"输出\"><a href=\"#%E8%BE%93%E5%87%BA\" aria-label=\"输出 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>输出</h3>\n<p>输出为一个 struct 列，字段如下（<code>tensor</code> 均指 <code>struct&#x3C;shape: list&#x3C;int32>, data: list&#x3C;float32>></code>，<code>data</code> 是按行优先展平的 float32；缺失时为 <code>{\"shape\": [], \"data\": []}</code>）：</p>\n<table>\n<thead>\n<tr>\n<th>输出</th>\n<th>含义</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>frame_count</td>\n<td>int32，输出的位姿帧数，等于 min(output_max_frames, 关键帧数)；失败时 0</td>\n</tr>\n<tr>\n<td>image_size</td>\n<td>list<int32>，SLAM 分辨率下的 [H, W]，实测 [384, 512]</td>\n</tr>\n<tr>\n<td>intrinsic</td>\n<td>tensor，BA 后的像素单位内参矩阵，形状 (3,3)，fx=data[0]、fy=data[4]</td>\n</tr>\n<tr>\n<td>cam_c2w</td>\n<td>tensor，每帧 camera-to-world 位姿，形状 (frame_count,4,4)，每个 4×4 的最后一行是 [0,0,0,1]</td>\n</tr>\n<tr>\n<td>depths</td>\n<td>tensor，深度图 (frame_count,H,W)；if_output_depths=False（默认）时为空</td>\n</tr>\n<tr>\n<td>npz_path</td>\n<td>string，落盘的 npz 绝对路径（键 images / depths / intrinsic / cam_c2w）；未设 output_npz_dir 时为空串</td>\n</tr>\n<tr>\n<td>status</td>\n<td>string，success / error: no frames / error: &#x3C;异常信息></td>\n</tr>\n</tbody>\n</table>\n<h3 id=\"参数\"><a href=\"#%E5%8F%82%E6%95%B0\" aria-label=\"参数 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>参数</h3>\n<table>\n<thead>\n<tr>\n<th>参数名称</th>\n<th>类型</th>\n<th>默认值</th>\n<th>描述</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>video_src_type</td>\n<td>str</td>\n<td>\"video_url\"</td>\n<td>输入视频编码形式：video_url / video_base64 / video_binary，其他取值抛 ValueError</td>\n</tr>\n<tr>\n<td>model_path</td>\n<td>str</td>\n<td>\"/opt/aihc/model\"</td>\n<td>权重根目录</td>\n</tr>\n<tr>\n<td>moge_model_name</td>\n<td>str</td>\n<td>\"Ruicheng/moge-2-vitl/model.pt\"</td>\n<td>相对 model_path 的 MoGe-2 权重，须是 .pt 文件；默认使用 Ruicheng/moge-2-vitl</td>\n</tr>\n<tr>\n<td>megasam_repo_path</td>\n<td>str</td>\n<td>\"/opt/aihc/thirdparty/mega-sam\"</td>\n<td>mega-sam 源码根目录，须含 base/droid_slam</td>\n</tr>\n<tr>\n<td>megasam_ckpt_name</td>\n<td>str</td>\n<td>\"megasam/megasam_final.pth\"</td>\n<td>相对 model_path 的 DROID 权重</td>\n</tr>\n<tr>\n<td>sample_mode</td>\n<td>str</td>\n<td>\"by_count_uniform\"</td>\n<td>抽帧模式，透传 VideoFrameSampler：by_count_uniform / by_interval_time / by_interval_frames / by_fps / by_timestamps</td>\n</tr>\n<tr>\n<td>start_time_sec</td>\n<td>float</td>\n<td>0.0</td>\n<td>抽帧起始秒</td>\n</tr>\n<tr>\n<td>end_time_sec</td>\n<td>float 或 None</td>\n<td>None</td>\n<td>抽帧结束秒，None 表示到视频末尾</td>\n</tr>\n<tr>\n<td>count_k</td>\n<td>int 或 None</td>\n<td>64</td>\n<td>by_count_uniform 模式抽帧数。默认取 64 是因为帧数过少（如 3 帧）起不了 DROID 轨迹</td>\n</tr>\n<tr>\n<td>interval_sec</td>\n<td>float 或 None</td>\n<td>None</td>\n<td>by_interval_time 模式间隔秒</td>\n</tr>\n<tr>\n<td>interval_frames</td>\n<td>int 或 None</td>\n<td>None</td>\n<td>by_interval_frames 模式间隔帧</td>\n</tr>\n<tr>\n<td>target_fps</td>\n<td>float 或 None</td>\n<td>None</td>\n<td>by_fps 模式目标帧率</td>\n</tr>\n<tr>\n<td>timestamps_sec</td>\n<td>list[float] 或 None</td>\n<td>None</td>\n<td>by_timestamps 模式时间戳列表</td>\n</tr>\n<tr>\n<td>max_frames</td>\n<td>int 或 None</td>\n<td>300</td>\n<td>抽帧上限，显存与耗时随帧数线性增长</td>\n</tr>\n<tr>\n<td>buffer</td>\n<td>int</td>\n<td>1024</td>\n<td>DROID 关键帧缓冲区大小，短片可下调省显存</td>\n</tr>\n<tr>\n<td>filter_thresh</td>\n<td>float</td>\n<td>2.0</td>\n<td>MotionFilter 运动阈值，低于此值的帧不作为关键帧</td>\n</tr>\n<tr>\n<td>warmup</td>\n<td>int</td>\n<td>8</td>\n<td>frontend 启动所需帧数；抽帧数小于该值时算子直接报错</td>\n</tr>\n<tr>\n<td>keyframe_thresh</td>\n<td>float</td>\n<td>2.0</td>\n<td>关键帧剔除阈值</td>\n</tr>\n<tr>\n<td>frontend_window</td>\n<td>int</td>\n<td>25</td>\n<td>frontend 优化窗口</td>\n</tr>\n<tr>\n<td>frontend_thresh</td>\n<td>float</td>\n<td>12.0</td>\n<td>frontend 边构建距离阈值</td>\n</tr>\n<tr>\n<td>frontend_radius</td>\n<td>int</td>\n<td>2</td>\n<td>frontend 邻接半径</td>\n</tr>\n<tr>\n<td>frontend_nms</td>\n<td>int</td>\n<td>1</td>\n<td>frontend 非极大抑制</td>\n</tr>\n<tr>\n<td>backend_thresh</td>\n<td>float</td>\n<td>16.0</td>\n<td>backend 边构建距离阈值</td>\n</tr>\n<tr>\n<td>backend_radius</td>\n<td>int</td>\n<td>2</td>\n<td>backend 邻接半径</td>\n</tr>\n<tr>\n<td>backend_nms</td>\n<td>int</td>\n<td>3</td>\n<td>backend 非极大抑制</td>\n</tr>\n<tr>\n<td>beta</td>\n<td>float</td>\n<td>0.3</td>\n<td>几何 / 运动项权重</td>\n</tr>\n<tr>\n<td>opt_intrinsics</td>\n<td>bool</td>\n<td>True</td>\n<td>是否在 BA 里一并优化内参（对应 DROID terminate 的 _opt_intr）；DROID 内部若判定焦距不可观测会自动关掉</td>\n</tr>\n<tr>\n<td>full_ba</td>\n<td>bool</td>\n<td>True</td>\n<td>是否做全帧 BA（对应 DROID terminate 的 full_ba）</td>\n</tr>\n<tr>\n<td>output_max_frames</td>\n<td>int</td>\n<td>1000</td>\n<td>输出帧数上限</td>\n</tr>\n<tr>\n<td>if_output_depths</td>\n<td>bool</td>\n<td>False</td>\n<td>是否把深度图写进输出列，默认关（单帧 384×512 就是 20 万个 float32）</td>\n</tr>\n<tr>\n<td>output_npz_dir</td>\n<td>str 或 None</td>\n<td>None</td>\n<td>非空时把 images / depths / intrinsic / cam_c2w 落成 npz，目录会自动创建</td>\n</tr>\n<tr>\n<td>video_format</td>\n<td>str</td>\n<td>\"mp4\"</td>\n<td>二进制 / base64 输入的容器格式</td>\n</tr>\n<tr>\n<td>rank</td>\n<td>int</td>\n<td>0</td>\n<td>多卡场景 worker 序号，只影响 MoGe 的落卡</td>\n</tr>\n</tbody>\n</table>\n<h2 id=\"注意事项\"><a href=\"#%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9\" aria-label=\"注意事项 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>注意事项</h2>\n<ul>\n<li><strong>三个 CUDA 扩展需要提前按目标 GPU 架构编好</strong>：<code>droid_backends</code>、<code>lietorch</code>、<code>torch_scatter</code>。算子只做 import 检查，缺失时抛 <code>ImportError</code>，运行期不做编译。</li>\n<li><strong>编译产物与 python 版本、torch 版本、GPU sm 架构三重绑定</strong>：换 python 小版本、换 torch 或换卡都得重编；要同时覆盖多种架构的卡，需要编出含对应架构的 fat binary。</li>\n<li><strong>必须有 GPU</strong>：无 CUDA 时 <code>__init__</code> 直接 <code>RuntimeError</code>，DROID-SLAM 的 CUDA 扩展没有 CPU 实现。</li>\n<li><code>moge_model_name</code><strong>必须指到</strong><code>.pt</code><strong>文件</strong>：MoGe 的 <code>from_pretrained</code> 传目录会被当成 HF repo id 处理而报错。<code>megasam_ckpt_name</code> 同样指向具体的 <code>.pth</code> 文件，两个路径任一不存在即 <code>FileNotFoundError</code>；<code>megasam_repo_path</code> 下缺 <code>base/droid_slam</code> 也会直接报错。</li>\n<li><strong>多卡靠 worker 级隔离</strong>：<code>Droid.load_weights</code> 内部把网络固定放到 <code>cuda:0</code>，算子的 <code>rank</code> 只影响 MoGe 落卡，多卡场景需要 worker 级 <code>CUDA_VISIBLE_DEVICES</code>。</li>\n<li><strong>按</strong><code>concurrency=1</code><strong>起</strong>：测试用法是 <code>num_cpus=4, num_gpus=1, concurrency=1, batch_size=1</code>；<code>buffer</code> 默认 1024 个关键帧槽位占显存，短片建议下调（测试用 256）。实测 <code>test_video.mp4</code> 抽 32 帧全程 85 秒，npz 42.7M。</li>\n<li><strong>首帧位姿只是接近单位矩阵</strong>：DROID 以第一个关键帧为世界原点，但 full BA 会把所有位姿（含首帧）一起再优化、不做 gauge 固定，实测首帧 c2w 与单位矩阵偏差约 2e-3。做校验时要留容差。</li>\n<li>mega-sam README 里要求的 DepthAnything / RAFT 权重是它自己 mono-depth 与 <code>cvd_opt</code> 流程用的，本算子这条路径<strong>不需要</strong>。</li>\n</ul>\n<h2 id=\"调用示例\"><a href=\"#%E8%B0%83%E7%94%A8%E7%A4%BA%E4%BE%8B\" aria-label=\"调用示例 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>调用示例</h2>\n\n    <div class=\"code-block-wrapper\">\n        <div class=\"code-block\">\n            <div class=\"code-block-header\">\n                <span class=\"code-block-name\">Python</span>\n                <button class=\"code-copy-btn\" data-tooltip-text=\"\">\n                    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\"> <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M5.57894 3.45614C5.57894 3.38832 5.63392 3.33333 5.70175 3.33333H12.5439C12.6117 3.33333 12.6667 3.38832 12.6667 3.45614V10.2982C12.6667 10.3661 12.6117 10.4211 12.5439 10.4211H11.7544V5.70175C11.7544 4.89754 11.1025 4.24561 10.2982 4.24561H5.57894V3.45614ZM4.24561 4.24561V3.45614C4.24561 2.65194 4.89754 2 5.70175 2H12.5439C13.3481 2 14 2.65194 14 3.45614V10.2982C14 11.1025 13.3481 11.7544 12.5439 11.7544H11.7544V12.5439C11.7544 13.3481 11.1025 14 10.2982 14H3.45614C2.65194 14 2 13.3481 2 12.5439V5.70175C2 4.89754 2.65194 4.24561 3.45614 4.24561H4.24561ZM3.33333 5.70175C3.33333 5.63392 3.38832 5.57894 3.45614 5.57894H10.2982C10.3661 5.57894 10.4211 5.63392 10.4211 5.70175V12.5439C10.4211 12.6117 10.3661 12.6667 10.2982 12.6667H3.45614C3.38832 12.6667 3.33333 12.6117 3.33333 12.5439V5.70175Z\" fill=\"currentColor\"></path> </svg>\n                    复制\n                </button>\n            </div>\n            <div class=\"code-block-content\">\n                <pre class=\"language-python\"><code><span class=\"line-number\">1</span><span class=\"token keyword\">from</span> __future__ <span class=\"token keyword\">import</span> annotations\n<span class=\"line-number\">2</span>\n<span class=\"line-number\">3</span><span class=\"token keyword\">import</span> os\n<span class=\"line-number\">4</span>\n<span class=\"line-number\">5</span><span class=\"token keyword\">import</span> daft\n<span class=\"line-number\">6</span><span class=\"token keyword\">from</span> daft <span class=\"token keyword\">import</span> col\n<span class=\"line-number\">7</span>\n<span class=\"line-number\">8</span><span class=\"token keyword\">from</span> daft<span class=\"token punctuation\">.</span>aihc<span class=\"token punctuation\">.</span>common<span class=\"token punctuation\">.</span>udf <span class=\"token keyword\">import</span> aihc_udf\n<span class=\"line-number\">9</span><span class=\"token keyword\">from</span> daft<span class=\"token punctuation\">.</span>aihc<span class=\"token punctuation\">.</span>functions<span class=\"token punctuation\">.</span>embodied<span class=\"token punctuation\">.</span>perception<span class=\"token punctuation\">.</span>video_camera_pose <span class=\"token keyword\">import</span> VideoCameraPose\n<span class=\"line-number\">10</span>\n<span class=\"line-number\">11</span><span class=\"token keyword\">if</span> __name__ <span class=\"token operator\">==</span> <span class=\"token string\">\"__main__\"</span><span class=\"token punctuation\">:</span>\n<span class=\"line-number\">12</span>    <span class=\"token keyword\">if</span> os<span class=\"token punctuation\">.</span>getenv<span class=\"token punctuation\">(</span><span class=\"token string\">\"DAFT_RUNNER\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"native\"</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">==</span> <span class=\"token string\">\"ray\"</span><span class=\"token punctuation\">:</span>\n<span class=\"line-number\">13</span>        <span class=\"token keyword\">import</span> ray\n<span class=\"line-number\">14</span>        ray<span class=\"token punctuation\">.</span>init<span class=\"token punctuation\">(</span>dashboard_host<span class=\"token operator\">=</span><span class=\"token string\">\"0.0.0.0\"</span><span class=\"token punctuation\">,</span> ignore_reinit_error<span class=\"token operator\">=</span><span class=\"token boolean\">True</span><span class=\"token punctuation\">)</span>\n<span class=\"line-number\">15</span>        daft<span class=\"token punctuation\">.</span>set_runner_ray<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"line-number\">16</span>    daft<span class=\"token punctuation\">.</span>set_execution_config<span class=\"token punctuation\">(</span>actor_udf_ready_timeout<span class=\"token operator\">=</span><span class=\"token number\">6000</span><span class=\"token punctuation\">,</span> min_cpu_per_task<span class=\"token operator\">=</span><span class=\"token number\">0</span><span class=\"token punctuation\">)</span>\n<span class=\"line-number\">17</span>\n<span class=\"line-number\">18</span>ds <span class=\"token operator\">=</span> daft<span class=\"token punctuation\">.</span>from_pydict<span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span><span class=\"token string\">\"video\"</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span><span class=\"token string\">\"bos://your-bucket/sample.mp4\"</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"line-number\">19</span>    ds <span class=\"token operator\">=</span> ds<span class=\"token punctuation\">.</span>with_column<span class=\"token punctuation\">(</span>\n<span class=\"line-number\">20</span>        <span class=\"token string\">\"pose\"</span><span class=\"token punctuation\">,</span>\n<span class=\"line-number\">21</span>        aihc_udf<span class=\"token punctuation\">(</span>\n<span class=\"line-number\">22</span>            VideoCameraPose<span class=\"token punctuation\">,</span>\n<span class=\"line-number\">23</span>            construct_args<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>\n<span class=\"line-number\">24</span>                <span class=\"token string\">\"model_path\"</span><span class=\"token punctuation\">:</span> <span class=\"token string\">\"/path/to/models\"</span><span class=\"token punctuation\">,</span>\n<span class=\"line-number\">25</span>                <span class=\"token string\">\"megasam_repo_path\"</span><span class=\"token punctuation\">:</span> <span class=\"token string\">\"/path/to/thirdparty/mega-sam\"</span><span class=\"token punctuation\">,</span>\n<span class=\"line-number\">26</span>                <span class=\"token string\">\"count_k\"</span><span class=\"token punctuation\">:</span> <span class=\"token number\">32</span><span class=\"token punctuation\">,</span>\n<span class=\"line-number\">27</span>                <span class=\"token string\">\"buffer\"</span><span class=\"token punctuation\">:</span> <span class=\"token number\">256</span><span class=\"token punctuation\">,</span>\n<span class=\"line-number\">28</span>                <span class=\"token string\">\"output_npz_dir\"</span><span class=\"token punctuation\">:</span> <span class=\"token string\">\"/tmp/camera_pose_npz\"</span><span class=\"token punctuation\">,</span>\n<span class=\"line-number\">29</span>            <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n<span class=\"line-number\">30</span>            num_cpus<span class=\"token operator\">=</span><span class=\"token number\">4</span><span class=\"token punctuation\">,</span>\n<span class=\"line-number\">31</span>            num_gpus<span class=\"token operator\">=</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span>\n<span class=\"line-number\">32</span>            concurrency<span class=\"token operator\">=</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span>\n<span class=\"line-number\">33</span>            batch_size<span class=\"token operator\">=</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span>\n<span class=\"line-number\">34</span>        <span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span>col<span class=\"token punctuation\">(</span><span class=\"token string\">\"video\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n<span class=\"line-number\">35</span>    <span class=\"token punctuation\">)</span>\n<span class=\"line-number\">36</span>    ds <span class=\"token operator\">=</span> ds<span class=\"token punctuation\">.</span>with_column<span class=\"token punctuation\">(</span><span class=\"token string\">\"frame_count\"</span><span class=\"token punctuation\">,</span> col<span class=\"token punctuation\">(</span><span class=\"token string\">\"pose\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">[</span><span class=\"token string\">\"frame_count\"</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n<span class=\"line-number\">37</span>    ds <span class=\"token operator\">=</span> ds<span class=\"token punctuation\">.</span>with_column<span class=\"token punctuation\">(</span><span class=\"token string\">\"status\"</span><span class=\"token punctuation\">,</span> col<span class=\"token punctuation\">(</span><span class=\"token string\">\"pose\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">[</span><span class=\"token string\">\"status\"</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n<span class=\"line-number\">38</span>    ds<span class=\"token punctuation\">.</span>show<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre>\n            </div>\n        </div>\n    </div>\n  ","fields":{"slug":"Tmu0pyy1k","title":"视频相机位姿估计（MegaSaM）","date":"2026-09-14","extractedHeadings":[]},"headings":[{"value":"简介","depth":2},{"value":"功能描述","depth":3},{"value":"算子参数","depth":2},{"value":"输入","depth":3},{"value":"输出","depth":3},{"value":"参数","depth":3},{"value":"注意事项","depth":2},{"value":"调用示例","depth":2}]}},"pageContext":{"isCreatedByStatefulCreatePages":false,"slug":"Tmu0pyy1k","prev":{"id":"Fmu0pxx3f","name":"图像三维人体重建（SAM 3D Body）","path":"Fmu0pxx3f","filePath":"操作指南/AI数据处理/算子列表/具身/图像三维人体重建（SAM 3D Body）.md","seo":null,"parentIds":["ilib2qygp","Ymo88m8hi","Imob3m6so","Qmob46txp"],"parents":[{"id":"ilib2qygp","documentId":"bfa43a8b-968a-41a1-8c9d-906507eeaed9","name":"操作指南","repoName":"AIHC","filePath":"操作指南","disabled":false,"path":"ilib2qygp","lastMergeTime":null,"isApiDoc":null,"httpMethod":null,"seo":null,"sourceOrgName":null,"sourceRepoName":null,"sourceDocumentId":null,"solutionTag":null,"solutionColor":null},{"id":"Ymo88m8hi","documentId":"c8cb5e38-f8c5-40f4-a424-b0c7895f0c0a","name":"AI数据处理","repoName":"AIHC","filePath":"操作指南/AI数据处理","disabled":false,"path":"Ymo88m8hi","lastMergeTime":"2026-04-21 14:23:10","isApiDoc":null,"httpMethod":null,"seo":null,"sourceOrgName":null,"sourceRepoName":null,"sourceDocumentId":"","solutionTag":null,"solutionColor":null},{"id":"Imob3m6so","documentId":"fe548e34-6659-4ff5-86f6-eee2c43aec90","name":"算子列表","repoName":"AIHC","filePath":"操作指南/AI数据处理/算子列表","disabled":false,"path":"Imob3m6so","lastMergeTime":null,"isApiDoc":null,"httpMethod":null,"seo":null,"sourceOrgName":null,"sourceRepoName":null,"sourceDocumentId":"","solutionTag":null,"solutionColor":null},{"id":"Qmob46txp","documentId":"f9104826-f58e-4fe5-beaa-11c45b4333dc","name":"具身","repoName":"AIHC","filePath":"操作指南/AI数据处理/算子列表/具身","disabled":false,"path":"Qmob46txp","lastMergeTime":null,"isApiDoc":null,"httpMethod":null,"seo":null,"sourceOrgName":null,"sourceRepoName":null,"sourceDocumentId":"","solutionTag":null,"solutionColor":null}]},"next":{"id":"Ymu0q11by","name":"旋转表示转换","path":"Ymu0q11by","filePath":"操作指南/AI数据处理/算子列表/具身/旋转表示转换.md","seo":null,"parentIds":["ilib2qygp","Ymo88m8hi","Imob3m6so","Qmob46txp"],"parents":[{"id":"ilib2qygp","documentId":"bfa43a8b-968a-41a1-8c9d-906507eeaed9","name":"操作指南","repoName":"AIHC","filePath":"操作指南","disabled":false,"path":"ilib2qygp","lastMergeTime":null,"isApiDoc":null,"httpMethod":null,"seo":null,"sourceOrgName":null,"sourceRepoName":null,"sourceDocumentId":null,"solutionTag":null,"solutionColor":null},{"id":"Ymo88m8hi","documentId":"c8cb5e38-f8c5-40f4-a424-b0c7895f0c0a","name":"AI数据处理","repoName":"AIHC","filePath":"操作指南/AI数据处理","disabled":false,"path":"Ymo88m8hi","lastMergeTime":"2026-04-21 14:23:10","isApiDoc":null,"httpMethod":null,"seo":null,"sourceOrgName":null,"sourceRepoName":null,"sourceDocumentId":"","solutionTag":null,"solutionColor":null},{"id":"Imob3m6so","documentId":"fe548e34-6659-4ff5-86f6-eee2c43aec90","name":"算子列表","repoName":"AIHC","filePath":"操作指南/AI数据处理/算子列表","disabled":false,"path":"Imob3m6so","lastMergeTime":null,"isApiDoc":null,"httpMethod":null,"seo":null,"sourceOrgName":null,"sourceRepoName":null,"sourceDocumentId":"","solutionTag":null,"solutionColor":null},{"id":"Qmob46txp","documentId":"f9104826-f58e-4fe5-beaa-11c45b4333dc","name":"具身","repoName":"AIHC","filePath":"操作指南/AI数据处理/算子列表/具身","disabled":false,"path":"Qmob46txp","lastMergeTime":null,"isApiDoc":null,"httpMethod":null,"seo":null,"sourceOrgName":null,"sourceRepoName":null,"sourceDocumentId":"","solutionTag":null,"solutionColor":null}]},"parents":[{"id":"ilib2qygp","documentId":"bfa43a8b-968a-41a1-8c9d-906507eeaed9","name":"操作指南","repoName":"AIHC","filePath":"操作指南","disabled":false,"path":"ilib2qygp","lastMergeTime":null,"isApiDoc":null,"httpMethod":null,"seo":null,"sourceOrgName":null,"sourceRepoName":null,"sourceDocumentId":null,"solutionTag":null,"solutionColor":null},{"id":"Ymo88m8hi","documentId":"c8cb5e38-f8c5-40f4-a424-b0c7895f0c0a","name":"AI数据处理","repoName":"AIHC","filePath":"操作指南/AI数据处理","disabled":false,"path":"Ymo88m8hi","lastMergeTime":"2026-04-21 14:23:10","isApiDoc":null,"httpMethod":null,"seo":null,"sourceOrgName":null,"sourceRepoName":null,"sourceDocumentId":"","solutionTag":null,"solutionColor":null},{"id":"Imob3m6so","documentId":"fe548e34-6659-4ff5-86f6-eee2c43aec90","name":"算子列表","repoName":"AIHC","filePath":"操作指南/AI数据处理/算子列表","disabled":false,"path":"Imob3m6so","lastMergeTime":null,"isApiDoc":null,"httpMethod":null,"seo":null,"sourceOrgName":null,"sourceRepoName":null,"sourceDocumentId":"","solutionTag":null,"solutionColor":null},{"id":"Qmob46txp","documentId":"f9104826-f58e-4fe5-beaa-11c45b4333dc","name":"具身","repoName":"AIHC","filePath":"操作指南/AI数据处理/算子列表/具身","disabled":false,"path":"Qmob46txp","lastMergeTime":null,"isApiDoc":null,"httpMethod":null,"seo":null,"sourceOrgName":null,"sourceRepoName":null,"sourceDocumentId":"","solutionTag":null,"solutionColor":null}],"specificSeo":null}}}