3DGS 重建质量很大程度取决于采集路径——同一只物体、同一台设备、同一个 ReconSession 配置,换一种环绕走法,SSIM 能差 0.2。但官方文档没给路径规范,只说"环绕拍摄",至于单圈够不够、要不要走螺旋、8 字路径有没有用,全靠自己试。这篇文章记录我们用同一只 20cm 陶瓷花瓶在 4 种路径下采集重建的对比数据,包括重建耗时、高斯点数、SSIM、失败区域,并给出在 Pura 80 Pro 上能落地的路径建议。

能力面:4 种环绕路径的覆盖差异

环绕路径的核心指标是视场覆盖率——物体表面每个点被多少个角度的相机看到。覆盖率越高,重建质量越好;覆盖率不足的区域会出现空洞或扭曲。

4 种路径从简到繁:

  • 单圈:相机在物体周围走一圈,镜头始终对准物体中心,高度不变(约物体腰部高度)。
  • 双圈:走两圈,一圈在腰部高度,一圈在胸部高度,两圈高度差约 15cm。
  • 螺旋:相机环绕同时从低到高(或高到低)螺旋上升,覆盖 360° 方位 × 全高度。
  • 8 字:相机走 8 字形轨迹绕物体,轨迹在物体前后交叉,增加前后视差。

文字示意(俯视,O 为物体,箭头为相机轨迹):

单圈:        双圈:           螺旋:            8 字:
  ↑            ↑               ↑              ↗   ↖
O   →        O   →           O   ↘           O   ↓
  ↓            ↓               ↘               ↗   ↖
  ←            ←               ↓                 ↙
              (两层高度)      (连续升降)      (前后交叉)

Spatial Recon Kit 的 ReconSession 不感知路径形状,它只消费帧流 + 每帧的位姿(由 AR 同时定位提供)。路径质量体现在两个维度:帧间视差是否足够(视差太小特征匹配失败)、整体覆盖是否完整(漏拍区域重建空洞)。

需要主动指出:Spatial Recon Kit 仅保证麒麟 9020/9030S/9030/9030 Pro 及后续旗舰芯片。路径对比测试在保证机型上做才有意义,中端机即使路径完美也可能因算力不足重建失败。

从包围盒到路径点,再到覆盖率校验,是一条连贯的链路。

小件 柱状

球状

覆盖率不足

覆盖率达标

物体包围盒估算

路径类型选择

单圈或双圈

螺旋

生成路径点

引导用户按路径采集

覆盖率检测

提示补采

进入重建

覆盖率不足就补采,别硬着头皮进重建,白等一轮。

约束面:路径设计的几条硬约束

约束表现对路径的要求
视差下限帧间位移 < 3cm 视差不足,特征匹配失败走动速度 ≥ 0.3 m/s
景深下限距离 < 15cm 近景糊,> 80cm 远景细节丢距离保持在 20-50cm
覆盖率底部和顶部最易漏拍路径要覆盖全高度
帧数下限< 200 帧重建不稳定12 秒以上拍摄
Session 单例同一时刻一个 session路径要在一次拍摄内完成

景深这条对花瓶这种高物体特别关键。花瓶高 20cm,单圈路径在腰部高度走,瓶口和瓶底都在景深边缘——瓶口距离镜头约 35cm 还行,瓶底如果路径在腰部则距离约 40cm 也行,但瓶口内侧(仰视才看到)和瓶底外侧(俯视才看到)完全没拍到,重建必空洞。

场景落地:同一花瓶 4 种路径对比

被测物:陶瓷花瓶,高 20cm,最大直径 12cm,表面有浮雕纹饰,瓶口内壁有釉色。放在 50cm 高桌面上,背景浅灰墙。

采集设备 Pura 80 Pro,主摄 4 镜,4 种路径各拍一遍,重建用同一份 config(TARGET_OBJECT 模式,PLY 输出,maxPointCount 80 万)。

路径 1:单圈

相机在花瓶腰部高度(桌面 + 10cm)环绕一圈,半径 30cm,耗时 8 秒约 240 帧。结果:瓶身中段重建良好,纹饰清晰;瓶口内侧空洞(仰视才看到,没拍到);瓶底外侧空洞(俯视才看到,没拍到);瓶身顶部和底部边缘有轻微扭曲,覆盖不足。

路径 2:双圈

两圈,腰部高度 + 胸部高度(桌面 + 25cm),半径 30cm,耗时 14 秒约 420 帧。结果:瓶口内侧从胸圈能看到,空洞消除;瓶底外侧仍空洞(两圈都偏高);瓶身顶部和底部边缘清晰;整体质量明显优于单圈。

路径 3:螺旋

相机从桌面高度螺旋上升到桌面 + 30cm,环绕 1.5 圈,半径 30cm,耗时 16 秒约 480 帧。结果:瓶口和瓶身全覆盖;瓶底外侧仍空洞(螺旋没下到桌面以下高度,俯视角度不够);整体质量与双圈接近,耗时多 2 秒。

路径 4:8 字

相机走 8 字形,轨迹在花瓶前后交叉,高度在腰部和胸部间起伏,耗时 18 秒约 540 帧。结果:瓶口内侧覆盖;瓶底外侧仍空洞;前后视差增加,瓶身浮雕立体感略好;但 8 字轨迹在交叉点帧间位姿跳变大,有 2 帧特征匹配失败,重建出现一处局部扭曲。

真机数据:4 种路径量化对比

指标单圈双圈螺旋8 字
采集耗时8 秒14 秒16 秒18 秒
帧数240420480540
重建耗时9 秒11 秒12 秒14 秒
高斯点数38 万52 万55 万58 万
PLY 体量9.5 MB13 MB14 MB15 MB
表面覆盖率71%89%88%87%
瓶口内侧空洞覆盖覆盖覆盖
瓶底外侧空洞空洞空洞空洞
SSIM(vs 实拍参考)0.680.830.820.80
局部扭曲区0 处0 处0 处1 处
渲染帧率(中景)60 fps60 fps60 fps60 fps

几个数据点值得展开:

双圈 SSIM 0.83 最高,且无局部扭曲。双圈用 14 秒采集 + 11 秒重建 = 25 秒总耗时,是 4 种里性价比最高的。我们一开始以为更复杂的螺旋和 8 字会更好,结果都没超过双圈。

螺旋耗时比双圈多 3 秒,SSIM 反而低 0.01。原因是螺旋只环绕 1.5 圈,方位覆盖不如双圈的 2 圈完整。螺旋的优势在高度连续覆盖,但花瓶这种柱状物体高度变化不剧烈,连续覆盖收益不大。如果是球状物体(如南瓜),螺旋可能更优。

8 字 SSIM 最低 0.80,且有 1 处局部扭曲。8 字的交叉点帧间位姿跳变大,特征匹配在交叉点失败,重建出来交叉区域有一处扭曲。8 字增加的前后视差对花瓶这种柱状物体收益小,对扁平物体(如浮雕板)可能更有用。

4 种路径瓶底外侧都空洞。这是因为相机没法下到桌面以下仰视瓶底。要覆盖瓶底,得把花瓶倒过来再拍一遍,或者用镜子从下方反射拍摄。两种都很麻烦,对花瓶展示不必要——用户不会把花瓶翻过来看底。

踩坑与取舍

路径点生成的核心就一个按尺寸缩放的公式,再叠圈数差异。

// 环绕采集路径点生成
// 输入物体包围盒尺寸与路径类型,输出路径点位置序列
type PathType = 'single' | 'double' | 'spiral';

interface Vec3 {
  x: number;
  y: number;
  z: number;
}

interface PathPoint {
  pos: Vec3;       // 相机位置,单位米
  lookAtY: number; // 镜头对准的高度,取物体中心
}

interface PathConfig {
  radius: number;         // 环绕半径
  heightLevels: number[]; // 各圈相机高度
  loops: number;          // 环绕圈数
}

// 按物体尺寸生成路径参数,半径约 1.5 倍物体尺寸
function buildPathConfig(size: { width: number; height: number }, type: PathType): PathConfig {
  const radius = Math.max(size.width, size.height) * 1.5; // 过近景深不足,过远细节丢
  switch (type) {
    case 'single':
      // 单圈:腰部高度一层,8 秒够用
      return { radius: radius, heightLevels: [size.height * 0.5], loops: 1 };
    case 'double':
      // 双圈:腰部 + 胸部两层,高度差约 15cm
      return { radius: radius, heightLevels: [size.height * 0.5, size.height * 0.75], loops: 2 };
    default: {
      // 螺旋:高度由低到高连续近似,适合球状或不规则物体
      const levels: number[] = [];
      for (let k = 0; k < 6; k++) {
        levels.push(size.height * (0.1 + k * 0.15));
      }
      return { radius: radius, heightLevels: levels, loops: 1 };
    }
  }
}

// 生成路径点:segments 为单圈采样点数,帧数 ≥ 200 重建才稳定
function buildPathPoints(
  size: { width: number; height: number },
  type: PathType,
  segments: number = 240
): PathPoint[] {
  const cfg = buildPathConfig(size, type);
  const points: PathPoint[] = [];
  const lookAtY = size.height * 0.5; // 镜头始终对准物体中心

  for (const level of cfg.heightLevels) {
    for (let i = 0; i < segments; i++) {
      const angle = (i / segments) * Math.PI * 2; // 一圈 360 度
      points.push({
        pos: { x: Math.cos(angle) * cfg.radius, y: level, z: Math.sin(angle) * cfg.radius },
        lookAtY: lookAtY
      });
    }
  }
  return points;
}

// 用法:20cm 花瓶走双圈,输出约 480 个路径点
const pathPoints = buildPathPoints({ width: 0.2, height: 0.2 }, 'double');
console.info('path points:', pathPoints.length);

双圈比单圈多一层高度,路径点数量翻倍,采集耗时也跟着翻。

坑 1:单圈路径底部和顶部空洞

已经提到,单圈在腰部高度走,瓶口内侧和瓶底外侧都没拍到。这个坑最常见,因为单圈是采集者最直觉的走法——绕一圈就完。

应对是双圈或螺旋,加一层高度覆盖。但双圈要 14 秒,单圈只要 8 秒,对"快速预览"场景用户可能没耐心。我们最终在引导页给两个选项:"快速预览(单圈 8 秒,可能有空洞)“和"完整重建(双圈 14 秒)”,让用户选。多数用户选完整重建,因为 14 秒还能忍,空洞看着难受。

坑 2:螺旋路径耗时翻倍但质量提升有限

螺旋 16 秒采集 + 12 秒重建 = 28 秒,比双圈 25 秒多 3 秒,SSIM 反而低 0.01。我们一开始推螺旋方案,理由是"连续高度覆盖更完整",结果数据打脸——花瓶这种柱状物体,双圈的两层离散高度已经够覆盖,螺旋的连续高度是过度设计。

螺旋只对高度变化剧烈的物体有优势。测过一个 30cm 高的不规则陶罐,罐身有凸起和凹陷,双圈在凹陷处仍有覆盖盲区,螺旋连续高度覆盖更好,SSIM 比双圈高 0.04。但花瓶这种规整柱状,螺旋不值。

坑 3:8 字路径交叉点特征匹配失败

8 字在交叉点相机位姿跳变大(从物体左侧突然到右侧),帧间视差超过特征匹配阈值,2 帧匹配失败。重建出来交叉区域有一处约 2cm 直径的扭曲,纹饰错位。

这个坑理论上可通过降低走动速度缓解——交叉点慢一点,帧间视差小。但实测降到 0.2 m/s 还是有 1 帧失败,原因是 8 字交叉点本身位姿就是不连续的。8 字路径在当前 ReconSession 的特征匹配阈值下不稳定,不推荐用于正式采集。

坑 4:路径过近导致景深不足

试过把环绕半径从 30cm 缩到 15cm 想拍更多细节。结果近景糊——花瓶直径 12cm,半径 15cm 时镜头到花瓶表面只有 9cm,超出景深下限,瓶身中心清晰但两侧糊。重建出来两侧纹饰扭曲。

半径 30cm 是 20cm 物体的合理距离,约 1.5 倍物体尺寸。再近不行,再远细节丢。路径半径要按物体尺寸等比缩放,这个经验值写进引导页的"请保持距离"提示。

坑 5:走动速度过快视差不足

试过快速跑一圈 4 秒拍完,帧间位移超过 5cm,特征匹配大面积失败,重建直接报错退出。走动速度要 ≤ 0.5 m/s,12 秒走完 30cm 半径一圈(约 1.9m 周长)正好。引导页要明确告诉用户"慢走、匀速",不能赶时间。

路径选择决策表

物体形状推荐路径理由
小件手办(< 15cm)单圈高度小,单圈覆盖够
柱状物体(花瓶、杯子)双圈顶部和底部需第二层覆盖
球状物体(南瓜、球雕)螺旋高度连续覆盖收益大
扁平物体(浮雕板)双圈 + 前后交叉前后视差重要,但 8 字不稳
不规则高物体(陶罐)螺旋凹凸处需连续高度
任何物体禁用 8 字交叉点匹配失败
任何物体禁用快速跑视差不足,重建报错

总结一下下

  • 环绕半径约 1.5 倍物体尺寸,过近景深不足,过远细节丢
  • 走动速度 ≤ 0.5 m/s,匀速慢走,帧间位移 < 5cm
  • 帧数 ≥ 200,采集 ≥ 8 秒,否则重建不稳定
  • 柱状物体用双圈,球状用螺旋,禁用 8 字
  • 瓶底/底部无法覆盖可接受,用户不会翻转看底
  • session 单例,路径要在一次拍摄内完成,不能分段
  • 仅保证机型开放,路径对比测试在保证机型上做才有意义
  1. 测 10 种不同形状物体(柱/球/扁/不规则),每种跑 4 路径,标定"物体形状 → 推荐路径"查表,给采集者一份 SOP
  2. 试"双圈 + 顶部俯视一圈"三圈方案,看能否消除瓶底空洞,评估多一圈的耗时是否值
  3. 测螺旋路径在不同螺距(高度变化率)下的 SSIM,找柱状和球状的最佳螺距分界
  4. 调研 ReconSession 的特征匹配阈值能否配置,如果能调,8 字路径降低阈值可能可用

在我们测的 4 种路径 × 1 只花瓶范围内,双圈是性价比最高的通用方案,14 秒采集 + 11 秒重建 + 0.83 SSIM。螺旋对球状物体可能更优,但只测了花瓶一种柱状,不敢外推。8 字在当前 API 26 的特征匹配阈值下不稳定,不推荐。如果后续 ReconSession 暴露特征匹配阈值配置接口,8 字可能值得重测。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐