<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>多相机重建 | 聂畅</title><link>https://changnie.top/zh/tags/%E5%A4%9A%E7%9B%B8%E6%9C%BA%E9%87%8D%E5%BB%BA/</link><atom:link href="https://changnie.top/zh/tags/%E5%A4%9A%E7%9B%B8%E6%9C%BA%E9%87%8D%E5%BB%BA/index.xml" rel="self" type="application/rss+xml"/><description>多相机重建</description><generator>HugoBlox Kit (https://hugoblox.com)</generator><language>zh-Hans</language><lastBuildDate>Sat, 31 Jan 2026 00:00:00 +0000</lastBuildDate><image><url>https://changnie.top/media/icon_hu_3dd7560279821d57.png</url><title>多相机重建</title><link>https://changnie.top/zh/tags/%E5%A4%9A%E7%9B%B8%E6%9C%BA%E9%87%8D%E5%BB%BA/</link></image><item><title>MRASfM：驾驶场景中的多相机运动恢复结构与聚合</title><link>https://changnie.top/zh/publications/mrasfm/</link><pubDate>Sat, 31 Jan 2026 00:00:00 +0000</pubDate><guid>https://changnie.top/zh/publications/mrasfm/</guid><description>&lt;h2 id="驾驶数据的形态不适合摄影测量"&gt;驾驶数据的形态不适合摄影测量&lt;/h2&gt;
&lt;p&gt;驾驶场景的图像重建，通常交给视觉 SLAM 去做。可一旦目标是高精地图或者新视角合成，SLAM 这条路就暴露出一个结构性的短板：它的估计是增量式的，只在局部做优化，全局修正无从谈起，长轨迹上的漂移便一点点攒起来。运动恢复结构（structure-from-motion, SfM）走的是相反的路子，一次性读入全部数据，最后统一做一次全局束调整（bundle adjustment）。离线这个特点让它上不了实时机器人，也恰恰是它在这里的价值所在，因为它可以把实时系统花不起的算力花掉。&lt;/p&gt;
&lt;p&gt;顺理成章的下一步，是把 SfM 用在驾驶上。但驾驶数据有三个特点，让这件事比看上去难得多。&lt;/p&gt;
&lt;p&gt;第一个是采集几何。经典 SfM 假设你绕着目标走一圈，从各个方向拍照；汽车却是沿着一条走廊往前开。视点几乎共线，而共线正是 SfM 所依赖的平移估计最怕的情形。&lt;/p&gt;
&lt;p&gt;第二个是数据本身就是碎的。驾驶场景往往只录很短一段时间，重叠有限，覆盖同一片区域的两段行程甚至可能相隔几周。两个最终要落进同一张地图的数据集之间，常常连一张共享图像都没有。&lt;/p&gt;
&lt;p&gt;第三个是标定，也是它改变了我们设计整套方法的思路。车辆标定本来就不容易，初值里带着误差，到了起伏路面上误差还会更大。于是出发时手上的那组外参（extrinsics），并不是真正需要的那组，可它偏偏又是能拿到的最强先验。这对矛盾贯穿了整个设计。&lt;/p&gt;
&lt;h2 id="已有方法默认了什么"&gt;已有方法默认了什么&lt;/h2&gt;
&lt;p&gt;多相机 SLAM 系统精度不错，代价是把精确的相机间相对位姿与内参当成输入。标定必须在部署之前完成，换一套相机配置就很难适应，实际使用中的灵活性因此受限。&lt;/p&gt;
&lt;p&gt;增量式 SfM 是最接近的基线，我们对它的批评也很具体。它在增量重建的过程中完全不理会相机组的先验，等重建结束，才在刚性束调整里把先验加回去。到那个时候，增量估计阶段攒下的误差已经没有机会纠正，刚性束调整也抹不掉已经烙进结构里的漂移。逐图像束调整有另一个相关的毛病：相机之间的相对位姿在帧与帧之间可能对不上。&lt;/p&gt;
&lt;p&gt;全局多相机 SfM 确实从一开始就固定住相机之间的相对位姿，但它对误匹配敏感，而且当估计出的相对平移接近共线时容易退化。驾驶场景的轨迹默认就接近共线，所以这不是边界情况，而是结构性的隐患。&lt;/p&gt;
&lt;p&gt;里程计引导的 SfM 押的是相反的一边，直接拿里程计位姿和相机外参做配准。这对标定精度和里程计精度要求都很高，而这两样恰恰是实地部署最难稳定提供的。这类工作用单应（homography）寻找重叠图像对，这个思路我们借用了；“先验可以信任”这个前提，我们没有借。&lt;/p&gt;
&lt;p&gt;还有一个跟这个场景绑在一起的匹配问题。传统描述子在弱纹理图像里提不出多少特征点，而道路场景里到处都是弱纹理表面。&lt;/p&gt;
&lt;p&gt;最后，现有的聚合模块在合并重建时，一般默认待合并的两段之间存在共享图像。真实数据里，共享图像通常并不存在。&lt;/p&gt;
&lt;h2 id="难在哪里"&gt;难在哪里&lt;/h2&gt;
&lt;p&gt;先验要用，却不能被信任。外参和里程计是车上最强的信号，也是最不可靠的东西。全信，会得到一类失败；完全不用，会得到另一类。两者之间可以腾挪的设计空间很窄。&lt;/p&gt;
&lt;p&gt;共线是真正的退化，不是数值上的小毛病。固定相机组的全局方法把成败押在相对平移估计上，直线行驶让这个估计变得病态。&lt;/p&gt;
&lt;p&gt;失败模式恰好落在有用信号的位置上。路面在每张图像里都占去很大面积，却几乎不含纹理，于是既提不出足够的匹配，提出来的也多半不可靠。更麻烦的是车辆阴影的边缘：对比度高，会被当成特征点检测出来。阴影边缘不是场景里的一个点，阴影一动，这个特征就跟着动，等于把运动注进了路面，而那正是结构最要紧的地方。&lt;/p&gt;
&lt;p&gt;遮挡在相机组上和单相机上完全是两回事。单目系统里，一个相机被挡住就等于全线失败；环视相机组里，其他相机仍然看得见世界。但这份冗余只有在配准真的共享位姿时才算数，逐相机独立估计会把这点好处白白扔掉。&lt;/p&gt;
&lt;p&gt;鲁棒性也是有代价的。相机越多，束调整里要优化的位姿越多，效率随之下降。覆盖度买来鲁棒性，账单记在优化规模上，而抵消这笔开销，正是我们很大一部分设计存在的理由。&lt;/p&gt;
&lt;h2 id="相机组才是单元"&gt;相机组才是单元&lt;/h2&gt;
&lt;p&gt;我们的做法是换掉重建的原子。不再把每张图像当作一个待求解的独立相机，而是让刚性单元（rigid unit），也就是同一时刻拍下的全部图像，成为拿位姿的那个对象。这个位姿按定义就是该时刻的车辆位姿。&lt;/p&gt;
&lt;p&gt;好处在于，相机组的位姿可以分解成一个随时间变化的车辆位姿和一个静态的组内相对位姿。一个观测充分的相机，能把那些什么也看不到的相机的位姿一并背起来。相机组只估计一次，不必在每一帧重新学一遍。&lt;/p&gt;
&lt;p&gt;关键在这个分解用在哪里。我们把它当作配准和束调整内部的重参数化（reparameterization），而不是事后追加的约束。就这一个决定，同时带来三件事。位姿变量从“每相机每时刻一个”降到“每时刻一个加每相机一个”。优化出的相机组在帧间保持一致，因为本来就只有一个相机组需要一致。标定也从一项必须正确的输入，变成一个可以被改正的量。&lt;/p&gt;
&lt;h2 id="搭起一次重建"&gt;搭起一次重建&lt;/h2&gt;
&lt;p&gt;先做对应关系搜索。SuperPoint 负责检测，SuperGlue 负责匹配；匹配点落在不同语义类别的图像对直接丢掉，其余交给几何验证。图像对不是全都试一遍：手上有粗略的组内相对位姿和车辆位姿，就能估出每张图像大致的视场，只去匹配那些有机会重叠的图像对。这么过滤，效率和精度都会好一些，因为两两全匹配本身就昂贵，还会把永远不会共享内容的图像对所带来的噪声引进来。&lt;/p&gt;
&lt;p&gt;接下来配准分三步。先在对应关系最丰富的那些图像上估计 PnP。这些逐图像的估计换算成逐单元的估计，再用局部鲁棒旋转平均和平移平均融合成一个单元位姿。该单元里剩下的每张图像，拿单元位姿和标定一复合，位姿就出来了。&lt;/p&gt;
&lt;p&gt;中间那一步，正是本方法在前文两类失败模式之间的落点。它和全局那一类一样做平均，但平均的对象是从可靠图像推出来的单元假设，不是原始的相对平移，这才让它扛得住共线。&lt;/p&gt;
&lt;p&gt;对这个模块的交代要诚实，而且范围很窄。它对平均位姿精度和效率的作用都很小，真正的用处在遮挡视角上；对应关系丰富的场景里，它并不显眼。我们把这个取舍写出来，而不是把这个模块说成人人受益，因为冗余的价值本来就更集中在长尾。&lt;/p&gt;
&lt;p&gt;
&lt;figure id="figure-某个相机被遮挡不再让整个单元失败"&gt;
&lt;div class="flex justify-center"&gt;
&lt;div class="w-full"&gt;&lt;img
alt="配准先估计少数观测充分的相机，其余相机由相机组几何推得。"
srcset="https://changnie.top/publications/mrasfm/camera-set-registration_hu_15bd2d6c03d3c2fd.webp 320w, https://changnie.top/publications/mrasfm/camera-set-registration_hu_e94cc5b258840200.webp 480w, https://changnie.top/publications/mrasfm/camera-set-registration_hu_29c5c9ef2f2a51f.webp 768w, https://changnie.top/publications/mrasfm/camera-set-registration_hu_3a53e7ff654a13d6.webp 1024w, https://changnie.top/publications/mrasfm/camera-set-registration_hu_6684702da025f980.webp 1080w"
sizes="(max-width: 480px) 100vw, (max-width: 768px) 90vw, (max-width: 1279px) 88vw, 928px"
src="https://changnie.top/publications/mrasfm/camera-set-registration_hu_15bd2d6c03d3c2fd.webp"
width="1080"
height="625"
loading="lazy"
data-zoomable&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;a class="paper-image-original" href="https://changnie.top/publications/mrasfm/camera-set-registration_hu_ed2109669bad9638.webp" target="_blank" rel="noopener"&gt;查看原图 ↗&lt;/a&gt;
&lt;figcaption&gt;某个相机被遮挡，不再让整个单元失败。&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id="先把路面挪开"&gt;先把路面挪开&lt;/h2&gt;
&lt;p&gt;一个单元配准完成之后，我们用 LO-RANSAC 在路面点上拟合平面模型，再把它们去掉。这一步直接冲着阴影边缘的问题去。移动的阴影边缘会产生一个并不附着在场景上的特征，而它落在视野里面积最大、纹理最少的那个表面上，三角化的噪声于是默认往那里集中。去掉这些点，重建精度会提高，收敛也更快。&lt;/p&gt;
&lt;p&gt;这里用的假设是路面局部平坦，而我们自己采集的真实场景里就有坡度变化，所以这是一个近似，不是保证。&lt;/p&gt;
&lt;p&gt;
&lt;figure id="figure-在噪声最集中的地方去掉阴影驱动和纹理贫乏的点"&gt;
&lt;div class="flex justify-center"&gt;
&lt;div class="w-full"&gt;&lt;img
alt="三角化之前，先用平面模型滤掉路面点。"
srcset="https://changnie.top/publications/mrasfm/road-filtering_hu_2fdd79d6221cc441.webp 320w, https://changnie.top/publications/mrasfm/road-filtering_hu_7f5e12d343a2756b.webp 480w, https://changnie.top/publications/mrasfm/road-filtering_hu_d555188bccd5e091.webp 768w, https://changnie.top/publications/mrasfm/road-filtering_hu_f0f498a58b673a65.webp 1024w, https://changnie.top/publications/mrasfm/road-filtering_hu_a4e020bd76b5cdae.webp 1080w"
sizes="(max-width: 480px) 100vw, (max-width: 768px) 90vw, (max-width: 1279px) 88vw, 928px"
src="https://changnie.top/publications/mrasfm/road-filtering_hu_2fdd79d6221cc441.webp"
width="1080"
height="329"
loading="lazy"
data-zoomable&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;a class="paper-image-original" href="https://changnie.top/publications/mrasfm/road-filtering_hu_a78118426cf63e4f.webp" target="_blank" rel="noopener"&gt;查看原图 ↗&lt;/a&gt;
&lt;figcaption&gt;在噪声最集中的地方，去掉阴影驱动和纹理贫乏的点。&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id="在相机组上做束调整"&gt;在相机组上做束调整&lt;/h2&gt;
&lt;p&gt;相机组束调整（camera set bundle adjustment, CSBA）优化的对象是车辆位姿和组内相对位姿，靠代换约束（substitution constraints）把每个相机位姿写成车辆位姿与相机组几何的组合，局部阶段使用 Cauchy 鲁棒损失。变量包括内参、车辆位姿、组内相对位姿和场景点。&lt;/p&gt;
&lt;p&gt;它有两种模式，这个划分很要紧。局部 CSBA 固定内参和组内相对位姿，只动新注册的单元及其邻居。全局 CSBA 在所有已注册单元上优化全部变量，当还有大量单元没被优化时，我们就触发一次。&lt;/p&gt;
&lt;p&gt;全局 CSBA 重新优化内参和相对位姿，这就是论文所说的在线标定（online calibration）能力。它也是实际收益的所在，因为这一步把实地最不可靠的输入变成了输出。局部 CSBA 更便宜，而它冻结的恰恰是这几个参数，取舍就在这里：便宜的模式修不了标定，能修标定的模式更贵。&lt;/p&gt;
&lt;p&gt;从“每相机每时刻一个位姿”到“每时刻一个加每相机一个”的削减，值得多花点笔墨。六个相机跑一条长轨迹，逐图像的写法要优化出六倍于所需的位姿，而每多一个变量，就多一个噪声可以藏身的自由度。变量少了，收敛更快，结果也更一致。在这个问题上，鲁棒性和效率是同一条杠杆，这样的情况并不常见。&lt;/p&gt;
&lt;p&gt;
&lt;figure id="figure-车辆位姿与组内相对位姿联合优化标定才有可能在实地越用越准"&gt;
&lt;div class="flex justify-center"&gt;
&lt;div class="w-full"&gt;&lt;img
alt="相机组只优化一次，而不是在每一帧重新估计。"
srcset="https://changnie.top/publications/mrasfm/camera-set-ba_hu_391a21fdb2ae00d7.webp 320w, https://changnie.top/publications/mrasfm/camera-set-ba_hu_3055e59701d6c74b.webp 480w, https://changnie.top/publications/mrasfm/camera-set-ba_hu_30675cf7ac5742e2.webp 768w, https://changnie.top/publications/mrasfm/camera-set-ba_hu_b2d2d986141c6f07.webp 1024w, https://changnie.top/publications/mrasfm/camera-set-ba_hu_6f03584da827f2b9.webp 1080w"
sizes="(max-width: 480px) 100vw, (max-width: 768px) 90vw, (max-width: 1279px) 88vw, 928px"
src="https://changnie.top/publications/mrasfm/camera-set-ba_hu_391a21fdb2ae00d7.webp"
width="1080"
height="1029"
loading="lazy"
data-zoomable&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;a class="paper-image-original" href="https://changnie.top/publications/mrasfm/camera-set-ba_hu_d2b24cbe094d9e3f.webp" target="_blank" rel="noopener"&gt;查看原图 ↗&lt;/a&gt;
&lt;figcaption&gt;车辆位姿与组内相对位姿联合优化，标定才有可能在实地越用越准。&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id="合并没有共享图像的行程"&gt;合并没有共享图像的行程&lt;/h2&gt;
&lt;p&gt;聚合必须在没有共享图像的前提下工作，所以整套策略是粗到细的。先用卫星定位把场景放进一个全局坐标系，用轨迹中点来代表它：一个场景放在几何中心，最近的若干邻居成为候选，再由单应引导的空间图像对，从候选里挑出视觉重叠最大的那一个。&lt;/p&gt;
&lt;p&gt;粗放置与真实位置之间差着一个未知变换，因为定位误差比对齐容差更大。那就把这个变换本身当成变量。把新场景里的一张图像重定位，得到一个更精确的位姿，由此求出粗放置与真实放置之间的变换，再用这个变换一次性把整个刚性单元注册进去。接着是三角化，然后一个基于变换的束调整优化这个变换与场景点，同时固定住参考场景的相机位姿。&lt;/p&gt;
&lt;p&gt;配准、三角化和调整轮流迭代，直到新场景的每个单元都被吸收进来。合并后的结果接着成为下一段场景的新参考，于是聚合是链式推进的，而不是围绕单一全局锚点展开。道理很简单：链式推进，误差就不会全部来自某一次可能出错的粗对齐。&lt;/p&gt;
&lt;p&gt;这一阶段的设计意图是，聚合在粗对齐那一步永远不必精确，只要近到足够重定位即可。&lt;/p&gt;
&lt;p&gt;
&lt;figure id="figure-卫星定位把场景放到大概位置视觉再把它修准"&gt;
&lt;div class="flex justify-center"&gt;
&lt;div class="w-full"&gt;&lt;img
alt="分别采集的行程，从粗对齐一路绑到精化的变换上。"
srcset="https://changnie.top/publications/mrasfm/multi-scene-aggregation_hu_862a8ae5a668a769.webp 320w, https://changnie.top/publications/mrasfm/multi-scene-aggregation_hu_735f3b73e75077d6.webp 480w, https://changnie.top/publications/mrasfm/multi-scene-aggregation_hu_f1a7db34e45bc66c.webp 768w, https://changnie.top/publications/mrasfm/multi-scene-aggregation_hu_7c340760013fc14d.webp 1024w, https://changnie.top/publications/mrasfm/multi-scene-aggregation_hu_45954c91809187d9.webp 1080w"
sizes="(max-width: 480px) 100vw, (max-width: 768px) 90vw, (max-width: 1279px) 88vw, 928px"
src="https://changnie.top/publications/mrasfm/multi-scene-aggregation_hu_862a8ae5a668a769.webp"
width="1080"
height="967"
loading="lazy"
data-zoomable&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;a class="paper-image-original" href="https://changnie.top/publications/mrasfm/multi-scene-aggregation_hu_b5d8bdb2f368dd04.webp" target="_blank" rel="noopener"&gt;查看原图 ↗&lt;/a&gt;
&lt;figcaption&gt;卫星定位把场景放到大概位置，视觉再把它修准。&lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id="我们从中得到什么"&gt;我们从中得到什么&lt;/h2&gt;
&lt;p&gt;物理不变量最好的用法是重参数化，而不是加约束。事后强制刚性，拦不住此前已经积累的误差；把刚性写进变量结构，误差从一开始就没有积累的机会。&lt;/p&gt;
&lt;p&gt;先验应该用来剪枝，不该用来下结论。粗略位姿决定匹配哪些图像对、从哪里起步，几何最终仍然来自匹配到的证据。这正是我们的做法与我们批评的那类做法之间的分界。&lt;/p&gt;
&lt;p&gt;设计时，要让先验可以被改正，而不只是被信任。把相对位姿变成可优化量，最不可靠的输入才会变成输出。&lt;/p&gt;
&lt;p&gt;还有一点：判断一个模块的价值，要去它失败模式所在的地方看。相机组配准几乎不改变平均位姿误差，可当某个相机被遮挡时，它就是成功与失败的分水岭。聚合指标足以把一个模块的全部价值盖住。&lt;/p&gt;
&lt;h2 id="它仍然假设了什么"&gt;它仍然假设了什么&lt;/h2&gt;
&lt;p&gt;方法把粗略轨迹、粗略标定和语义信息当作输入。语义从哪里来，我们只做了假设，没有交代；标签质量对结果的影响，也没有报告。&lt;/p&gt;
&lt;p&gt;多场景聚合没做消融。大约三个候选场景这个选择，以及以几何中心为参考的启发式，论文里只做了陈述，既没有给出理由，也没有失败分析。&lt;/p&gt;
&lt;p&gt;刚性单元完全由“同时”来定义，这个假设松动时会怎样，我们没有测。相机时间同步误差和支架形变都会破坏它，而这两点都没有讨论。在线标定只做了声明，没有刻画：全局阶段对内参和相对位姿的优化，在多大的运动多样性、多少个相机之下才是良态的，我们没有说。&lt;/p&gt;
&lt;p&gt;平面模型假定路面局部平坦，而我们自己的部署里就有坡度变化。跨不同多相机配置的通用性只有论断，实验也只在六相机和七相机的相机组上做过。动机里提到了阴影之外的动态物体，正文里没有专门处理。&lt;/p&gt;
&lt;h2 id="它通向哪里"&gt;它通向哪里&lt;/h2&gt;
&lt;p&gt;如果要我们概括自己的贡献，那就是换了一个单元，其余的一切都由它推出来。这个更换换来了什么，值得说清楚：把相机组当作配准与优化的原子单元，能在复杂环境里得到稳健的位姿估计，效率也高于传统的逐相机方法。再配合路面过滤和聚合阶段，整条流程能从那些本来没打算合并的行程里，做出统一的一张地图。&lt;/p&gt;
&lt;p&gt;我们有意从两个方向做了验证。真实车辆上的实验说明它在数据集之外也站得住，公开基准则把精度上的论断摆到传统基线旁边。这件事实际的分量在于：智能车辆能更可靠地感知周围环境、估计自身位姿，而下游任务真正消费的，就是这两样东西。&lt;/p&gt;</description></item></channel></rss>