Cyclops 模型优化
基于 Cyclops(单目全景深度估计)的多视图点云与 Mesh 建模优化
1. 项目信息
| 项 | 内容 |
|---|---|
| 项目名 | Cyclops 模型优化 |
| 时间 | 2019 年立项,后续持续迭代 |
| 应用场景 | 室内空间 Mesh 建模,服务于全景 VR 看房、房源三维重建 |
| 角色 | 算法设计与研发 |
| 输入 | 全景图(equirectangular)+ Cyclops 单目深度图 + 置信度图 + 初始位姿 |
| 输出 | 优化后的位姿、修正后的单视图深度图、房间级 Mesh |
整体流程如下图:

三个大阶段依次串行:位姿优化 → 点云优化 → 模型优化。每一阶段承接上一阶段的输出,逐级抑制单目深度带来的不一致性与噪声,最后再把优化后的 Mesh 反哺回每张深度图,让下游模块拿到一份彼此严格一致的几何。
2. 项目背景
Cyclops 是 2019 年自研的单目全景深度估计算法:输入一张室内全景图,网络直接回归一张全景深度图。相比多目立体匹配和激光扫描,它有几点非常鲜明的优势:
- 硬件成本低,只需要一个消费级全景相机
- 采集速度快,一个点位十几秒完成
- 视场完整,覆盖 360°×180°,一次拍摄几乎无死角
这些优势让它非常适合”轻装量房”的业务形态。但作为单目深度估计的通病,Cyclops 也有先天短板——它只能保证单张图内几何自洽,跨视图并不天然对齐。当业务需要用多个点位融合出一个连通、无漏洞、平面平整的房间 Mesh 时,这些先天缺陷会被放大成建模层面的破裂、分层、噪点、天花板漏洞等硬伤,严重影响下游看房体验和量房精度。
本项目的定位就是:不动 Cyclops 深度网络本身,通过一套几何后处理管线,把跨视图的位姿、点云、Mesh 一并优化到量产可用的质量水位。
3. 问题描述
3.1 单目深度的三大缺陷

在多视图室内场景下 Cyclops 深度主要暴露出三类问题:
尺度/深度不一致。 不同点位对同一堵墙的深度估计并不完全一致,跨点位差异累积到几厘米甚至几十厘米,直接融合会出现”双层墙”或者”错位墙”。这是单目深度最典型也是最难缠的短板:单张图内看不出问题,跨图才暴露。
点云歧义与外点。 反光、玻璃、纯色墙面、天空/窗外区域,网络会给出低置信度或错误的远距离深度,形成大量漂浮的外点和”穿墙”点。这些点在单视图深度图上不显眼,但一旦融合到三维空间里,就会污染整个模型。
几何噪声。 即使在”确定”的区域,深度值也有厘米级抖动。对表面法向和面片邻接关系而言,这已经足以让 Mesh 出现”波浪纹”和局部翻转。
3.2 下游 Mesh 建模的具体症状
上述缺陷传导到最终 Mesh,主要表现为五种典型问题:
- 分层:同一堵墙在最终 Mesh 里出现两层平行面片
- 漏洞:跨视图不一致导致体素融合失败,天花板/墙角出现大洞
- 飘片:天空、镜面、玻璃区域生成大量孤立的错误面片
- 平面不平:本应平整的地板/墙面出现”凹凸感”,量房精度下降
- 天花板噪声区:吊顶、灯具、烟感器等小物体被误处理为大面片,破坏整层观感
这些问题在纯几何管线(TSDF / Poisson / Delaunay)里几乎不可能靠调参解决——必须先把位姿和点云本身修正到几何一致,才谈得上下游 Mesh 的质量。
4. 解决方法
针对上一节的问题,本项目设计了一条三段式的优化管线:位姿优化负责让所有点位站得住,点云优化负责让点云本身干净且语义清晰,模型优化负责在此之上生成一个物理合理的 Mesh。三段的目标层层递进,边界也很清晰。
4.1 位姿优化:鲁棒的室内位姿 BA

动机。 室内场景纹理弱、平面多、光照差异大,传统基于特征点匹配的 BA 常常拉不动位姿;同时室内又是典型的 Manhattan world——不利用这一先验就是浪费。
做法。 我们构建了一个”点-面 + 冲突 + 曼哈顿”三合一的 BA,用 Ceres 作为求解器,并把位姿参数化成 6-DoF 加一个 y 轴自由旋转——这样重力方向被显式锁死,剩下的自由度只用来对齐水平朝向,收敛速度和稳定性都要好得多。
三类核心约束分别对应三种场景语义:
点云一致性约束。 跨视图搜索对应点后,用点到平面距离作为残差,比经典的点到点更适合墙面/地板这种大面积平面。对应点的搜索不是简单最近邻,而是先按当前深度反投出一个局部 Mesh,再用射线求交,避免”最近邻”落到墙的另一侧。
冲突约束(关键创新)。 Cyclops 深度经常在墙面前后各估出一片。如果 A 视图的墙落在 B 视图的相机-点连线之间,就构成物理不可能的遮挡。冲突约束把这种关系写成一个单侧惩罚项——只在冲突方向上产生残差,让墙面被反向推开。相比对称的点到面残差,这一项对分层的破解力度要大得多。
平面正交/平行约束(曼哈顿)。 每个视图先做一次法向区域生长得到主导平面,然后跨视图枚举平面对,判定为”平行”、“反平行”、“正交”三态之一,作为软约束加入。等价于让整个楼层收敛到一个全局的 Manhattan frame。
除了这三类主约束,管线还额外引入了两个稳定项:一是相对位置软约束,防止 BA 把点位飘到几十米外;二是绝对位置先验,以 SfM 初始位姿作为锚,让所有点位可以整层一起旋转。
外层控制。 每层楼单独优化,楼层之间再做粗对齐。位姿迭代默认 3 轮,每轮把匹配阈值逐步收紧(0.4m → 0.28m → 0.2m),做到”由粗到精”。BA 开跑前会先算一遍点位之间的遮挡率,如果发现严重”卡壳”就把阈值先放宽 1.5 倍让 BA 大幅收敛。BA 收敛后再跑一次法向 RANSAC,把整层旋转到 Y 轴对齐重力的姿态。
4.2 点云优化:适配深度不一致的点云处理

动机。 即使位姿已经收敛,单视图深度还是有厘米级抖动和一定比例的外点。要让下游 Mesh 拿到一份”每个点都可信、全局法向连贯、语义大类正确”的输入。
做法。 点云优化管线共分七步:
- 按视图重建 + 法向估计:用置信度过滤,KNN + PCA 计算每个点的法向。
- 鲁棒融合:对同一物理点的多视图观测取中位数而非均值。这一步是抗 Cyclops 深度粗大误差的核心——中位数天然免疫少数派离群值,比均值稳得多;同时对正反两面的观测做归并。
- KNN 外点去除:K=30,最大距离 0.5m,最多迭代 10 轮,把飘点整片剔除。
- 法向区域生长分割:用已知法向的 region growing 把点云拆成若干平面 segment。之所以用已知法向而不是通用曲率排序,是因为室内平面语义比曲率更可靠。
- 轴向对齐:把主导 segment 强制吸附到 Manhattan 三轴,抹平微小倾斜。
- 语义提取:按法向和 Y 坐标为 segment 打标签——地板、天花板、竖直墙、地面附着物、天花板附着物。这些标签为后续处理提供先验。
- 窄空间修正:检查平行墙对的距离,如果小于阈值就判定为”墙贴墙”错觉,把两片墙合并;多层场景下再处理水平方向的重叠。
管线最后输出一个带可见性权重的点云——每个点都带上”被哪些相机看到”以及逐点置信度,这份可见性信息是下一节 Mesh 建模的关键输入。
4.3 模型优化:抗噪的 Graph-Cut Mesh 重建

动机。 Poisson、Delaunay 这类通用几何方法直接生成的三角面片,一定会有大量”包壳”、“天空片”、“墙背片”。必须在面片级别做一次二分类切割,只保留物理上真实可见的表面。
思路。 把 Mesh 建模拆成三步走:先生成一份初始 Mesh,再检测其中的无效区域,最后用 Graph-Cut 做最终的面片保留/删除决策。
第一步:初始 Mesh。 Delaunay 三角化得到一份包含内外两层壳的初始 Mesh,Laplacian 平滑 3 轮把噪声碾平。
第二步:无效区域检测。 构建 BVH,对可见性点云中的每个点向它可见的相机中心投一条光线,标注命中的面片的置信度和视图归属。逐面片打 label:命中点置信度低且面法向朝上,判为候选去除(多数是噪声天花板或漏洞补片);命中点为 0 且最长边超过 一定长度,也判为候选去除(多数是跨房间的错误连接)。以这些候选面片为种子做 BFS 扩张,得到”无效区域”。
第三步:Graph-Cut 二分类。 把每个三角面片当成一个节点,构造图割问题:
- 数据项:无效区域内的面片强连汇端(sink),要求被删除;其他面片连源端(source),要求被保留。连接的权重跟面积成正比。
- 平滑项:邻接面片之间的边容量等于它们共享边的长度——共享边越长,两个面片被切开的代价越大。这样鼓励切割沿细长边界发生,避免把一个整体面撕碎。
- 求解:Boykov–Kolmogorov 最大流算法找到最小割,源端一侧的面片保留,汇端一侧的面片删除。
- 兜底:如果切完剩余面积小于 0.8m²,说明 Graph-Cut 判定过激,回退到平滑后的完整 Mesh,保证不产生”整层空 Mesh”这种极端 case。
Graph-Cut 相比启发式的逐面片阈值判定,最大的好处在于它能整体权衡:一个孤立的低置信度面片如果和一片高置信度面片邻接紧密,Graph-Cut 会把它保留下来;反之一个中等置信度的面片如果周围都是垃圾,它会被一并切掉。这种”看邻居决定命运”的能力是纯阈值方法给不了的。
4.4 深度重投影:把优化 Mesh 反哺回原始 depth

管线的最后一步,是把优化后的 Mesh 反过来覆写每个视图的深度图。这一步同时解决两件事——让所有点位的深度图彼此严格一致,同时修补原始深度里的漏洞和穿透。
具体做法:为整体 Mesh 构建 BVH;对每个视图,在球面上按纬度做等面积网格采样(避免赤道过采样、极点过密),对每个像素反投球面射线,与全局 Mesh 求交,命中距离就是这个像素的新深度值。
其中有两处工程细节值得一提:
- 距离阈值动态选择:先在所有视图上统计所有网格的最大深度,取 90% 分位作为
distance_thresh,避开极少数超远命中(外墙外的天空/远景)。 - 兜底 Mesh:如果一个点位有效像素少于 1000(多数是被 Graph-Cut 剪掉的边缘点位),退化为在相机上方 1.5m 生成一个 4m 半径的圆盘 Mesh 作为替代,保证下游模块不会拿到全零深度图。
对室内外混合场景,还会先算出室内 Mesh 的最低命中高度 yMin,把室外点位的深度重投影限制在 y ≥ yMin 的高度以下,防止室外远景把整体 Mesh 拉高。
4.5 效果示意

优化后主要指标(内部量产日志经验值):
| 指标 | 优化前 | 优化后 |
|---|---|---|
| 相邻点位平均遮挡率 | 5–15 处 | 0–2 处 |
| 墙面分层数 | 2–3 层 | 单层 |
| Mesh 天花板漏洞 | 大量 | 少量小洞 |
| 平面平整度 | 厘米级抖动 | 亚厘米级 |
5. 总结
Cyclops 深度网络本身解决了”单目全景一张图出深度”的可用性问题,本项目则解决了”多张 Cyclops 深度图如何拼成一个可用房间 Mesh”的工程问题。回过头看,整套方案有三个可以复用的设计取舍:
第一,不改单目网络,只在几何后处理修补。 这让算法团队可以独立于深度网络迭代,也让新版 Cyclops 权重上线时不需要重训后处理管线。深度网络研究组和几何后处理组之间形成了清晰的边界,长期维护成本大幅降低。
第二,把室内先验用到极致。 Manhattan 结构、Y 轴锁定、地板/天花板语义、平面区域生长、平面对齐——这些先验在通用场景里可能是”负担”,但在室内量房这个具体场景里就是”生产力”。位姿参数化为 6-DoF 加一个 y 轴自由旋转、BA 里的三类几何残差、点云管线里的平面语义分类,本质上都是同一件事——先验用得越到位,就越能对抗单目深度先天的不一致性。
第三,能量最小化和图论最小割分工明确。 位姿和点位置这类连续量用 Ceres BA 求解,面片保留/删除这类离散量用 Graph-Cut 求解。两个工具各自擅长自己的问题——把它们硬塞进一个统一的 CRF 里未必更好,反而会引入求解稳定性问题。分而治之,各得其所。
回顾几年下来的落地经验,这套方案能持续支撑多种硬件(全景相机、手机、云台、专业设备)的量产,最大的功臣其实是模块之间的解耦。每一段都可以独立替换:位姿模块可以换更强的匹配算法,点云模块可以换更专业的语义分割网络,Mesh 模块可以换更精细的表面重建。整条管线不是”一次做对”,而是”每一段都能持续变好”。
对后续工作有几个可能的方向:
- 位姿阶段引入基于学习的匹配(如 LoFTR / SuperGlue)替换纯几何点面对应,进一步提升弱纹理房间的鲁棒性
- 点云语义阶段引入语义分割网络输出,替换掉当前基于法向和高度的启发式规则
- Graph-Cut 数据项目前主要来自可见性和置信度,可以引入基于视差一致性的显式代价,进一步压制”半透明区域”面片