# 双目测距技术路线 > 本文档把双目测距(立体目标测距)抽象为**与编程语言、硬件平台无关**的技术路线: > 只讲几何模型、数据结构、算法流程与质量语义,不依赖任何语言特性、加速器 > 型号或操作系统。可作为任意语言(C++/Rust/Python 仿真/嵌入式 C)在任意 > 算力平台上重新实现或移植的规格说明。 > > **文档分工**(各司其职,不重复抄录): > > | 文档 | 定位 | 与本文的分工 | > |------|------|--------------| > | `docs/双目深度估计思路.md` | 平台工程路线 + 原稿对照 | **平台与工程细节权威**:采集/解码链路、加速器预算、线程与文件落点、原稿缺陷对照;本文一律不涉及 | > | 本文 | **算法路线** | **算法与语义权威**:几何、取点、匹配、有效性、滤波、方位源、误差模型、职责与缺点 | > | `docs/视觉跟踪控制律技术路线.md` | 距离/方位的消费者 | 其距离通道与方位源如何消费本文输出,见其 §1.2/§2/§6.4 | > | `docs/双目测距方案讨论纪要.md` | 决策索引 | D2/D4/D5/S1~S3 等拍板结论的唯一索引,本文只落实、不重新讨论 | > > 三份技术路线若出现表述分歧:拍板结论以《双目测距方案讨论纪要》为准, > 算法语义以本文为准,平台工程以《双目深度估计思路》为准。 > > **参考实现**:`utils/stereo_ranger/`(Python,构件划分与本文逐条对应)。 > 实现时冻结的补充决策与发现的原文矛盾已回填本文(§4/§6.1/§6.2/§6.4/ > §6.7/§9/§11),两文档以本文为准。 > > ⚠️ **全部数值均为占位值**:焦距/标定参数待厂商数据(P1/P2),各阈值未整定。 > 标定与地面真值验证完成前,本模块输出**仅限静态标靶/回放/台架验证, > 不得作为飞行控制决策依据**(见 §12.3 红线)。 --- ## 目录 1. [概述与系统定位](#1-概述与系统定位) 2. [输入输出接口定义](#2-输入输出接口定义) 3. [坐标系与符号约定](#3-坐标系与符号约定) 4. [核心构件与状态清单](#4-核心构件与状态清单) 5. [单周期处理流程(主流程伪代码)](#5-单周期处理流程主流程伪代码) 6. [各环节算法细节](#6-各环节算法细节) 7. [误差模型与有效距离域](#7-误差模型与有效距离域) 8. [职责、边界与已知缺点](#8-职责边界与已知缺点) 9. [配置参数全量表](#9-配置参数全量表) 10. [设计取舍记录(为什么不是别的做法)](#10-设计取舍记录为什么不是别的做法) 11. [实现与重写指引](#11-实现与重写指引) 12. [验证路线与待定项](#12-验证路线与待定项) --- ## 1. 概述与系统定位 ### 1.1 模块职责 本模块是**目标距离与方位的机载唯一来源**(决策 D2:双目替代激光雷达, 与提交 b96111e 一致)。它对**同一时刻**左右两幅已立体校正图像上的目标 检测框做立体几何解算,输出**少量目标的**距离与方位(不是稠密深度图)。 职责四件事: 1. **匹配**:把左右两目的检测框按"同一物理目标"配对(硬约束筛选 + 贪心代价排序); 2. **测距**:同侧边缘视差 D → `Z = F·B / D` 前向距离(斜距 R 仅参考输出); 3. **方位源**:输出**虚拟双目中心**像素 `c_mid`(两目框中心等权平均, 消除单目近场视差偏差,§6.6); 4. **质量语义**:输出有效性标志与置信度(有效域内 + 匹配成功 + 一致性 正常),对距离做轻量时间滤波;域外/失配/异常时**明确输出无效**, 不得强行估计。 ### 1.2 在系统中的位置 ```text 平台采集/解码/立体校正(平台相关,见《双目深度估计思路》第 3/8 章) → 校正后左/右图像(同帧) → 左/右目标检测(外部模块,输出原图坐标系的检测框) → 本模块:匹配 + 测距 + 方位源 + 有效性 + 滤波 → 目标距离记录 ├─ 距离 Z(valid)──▶ 控制律距离通道(Δd → PID → 前向速度,域内闭环) ├─ 方位 c_mid ──────▶ 接入层填入控制律目标中心(虚拟中心相机像素) └─ valid / 置信度 ──▶ 接入层降级语义: 域外/失配 → "无距离"策略(方位闭环 + 定速接近,D4) 持续无距离 → exit 档降级(S1 门限,消费侧实现) ``` **上游**:同帧校正图像对与左右检测框(检测、采集、解码、校正均为外部 模块);**下游**:跟踪控制律与接入层。"域外定速接近"的远场补偿策略 属消费侧行为,本文只负责提供诚实的有效性标志与持续的方位。 ### 1.3 设计特点 | 特点 | 含义 | 带来的约束 | |------|------|-----------| | **稀疏输出** | 只算检测到的目标,不做逐像素匹配 | 无检测即无输出;距离精度受框质量制约(§8) | | **纯值输入/输出** | 每帧传入同帧框对 + 参数,输出纯值记录列表 | 无隐藏输入、可离线回放 | | **纯函数构件** | 取点、测距、域判定均为无状态纯函数 | 可独立单元测试(合成框对即可,无需真实图像) | | **有状态部分极小** | 仅滤波器、一致性监控与目标隔离状态,且按目标隔离 | 重写时状态清单见 §11.1,漏一个就变行为 | | **参数全外置** | 几何、阈值、滤波参数全部来自配置 | 代码内不得写死任何相机参数或阈值 | | **诚实降级** | 域外/失配输出 `valid = false` 而非勉强给值 | 消费侧的远场策略建立在"不撒谎"的有效性上 | ### 1.4 明确不做的事(边界) - **不做采集/解码/立体校正**:消费校正后的图像与框;校正与自标定属 平台工程(v1.1 备选),不在本文范围; - **不做稠密匹配**:不做 SGBM 类逐像素立体匹配,不输出深度图; - **不做环境感知/避障**:环境深度由避障侧深度模型负责,与本模块并存 互不替代; - **不做目标跟踪**:不维护轨道与运动滤波;上游 track_id 只用作目标 状态隔离键(§4),不参与匹配打分与连续性先验(后者留 v1.1); - **不做运动/IMU 补偿**:帧间运动引起的虚假视差靠帧同步契约与一致性 监控兜底,不做解算级补偿; - **不做多传感器融合**:双目是目标距离机载唯一来源(D2),无交叉校验 基准;数据质量靠内部一致性监控自检(§6.7); - **不在域外强行估计**:超出有效距离域一律输出 `valid = false`。 --- ## 2. 输入输出接口定义 ### 2.1 输入(每帧一次,由平台层供给) | 分组 | 项 | 语义与约束 | |------|----|-----------| | 帧对 | 左帧、右帧 | 各含**帧标识**;两帧标识必须一致(同帧契约,见下) | | 检测 | 检测框数组 ×2 | 每框含:类别、置信度、框(左上/右下角像素);**已映射回校正图像坐标系** | | 几何 | 基线 `B`、焦距 `F`、主点 `cx, cy` | 校正后内参(`fx = fy = F`);来自标定配置,禁止写死 | | 参数 | 匹配/有效性/滤波阈值 | 配置外置(§9),启动期加载并校验 | | 时钟 | 当前单调时刻 | 用于输出打戳 | **契约要点**: - **同帧契约**:左右帧必须来自同一曝光时刻(同步与配对由平台层保证, 形态差异见《双目深度估计思路》§3.2)。本文把"左右帧标识一致"作为 输入违约检查:不一致直接拒收本帧、输出空、告警节流——**不同帧的 框配对解算没有物理意义**; - **校正契约**:检测框位于**已立体校正**的图像上("两目 y 对齐"是校正 的结果而非假设,§3);未校正图像上的框不得进入本模块; - **坐标基准一致**:检测若在缩放/裁剪图上运行,框必须先映射回校正图像 基准,且几何参数 `F/cx/cy` 使用同一基准的内参——否则视差与几何失配, 距离系统性错误; - **时间戳纪律**:输出取样时刻以**平台接收时刻的单调时钟**为准, 不伪造采集时刻。 ### 2.2 输出:目标距离记录(每帧每目标一条,纯值) | 字段 | 单位/类型 | 语义 | |------|-----------|------| | 帧标识 | — | 继承自输入帧对 | | 类别 | 枚举 | 目标类别 | | 轨道关联 | 整数或"无" | 检测侧 track 关联(如有;v1.0 可无) | | `Z` | m | 前向距离(沿光轴分量,**距离通道唯一消费量**) | | `R` | m | 斜距(参考值,不进控制回路;与已发布的 `Z` **同基准**——按滤波后 Z 换算,保证 `R ≥ Z`) | | `D` | px | 本次视差(调试与交叉校验用) | | `c_mid` | 像素 (x, y) | **虚拟双目中心**框中心:方位控制源(§6.6) | | 参考目框 | 像素框 | 左目(参考目)检测框,供交叉校验与调试 | | `confidence` | [0,1] | 匹配质量与一致性综合置信度 | | `valid` | 布尔 | 是否落在有效距离域且匹配成功且一致性正常(§6.4) | | 退化标记 | 枚举 | `完整`(距离+方位)/ `仅方位`(单目检出,§5 第 ⑤ 步) | | 取样时刻 | 单调时钟 | 平台接收时刻打戳(§2.1 时间戳纪律) | **记录两态**: - **完整记录**(匹配成功):距离 + 方位 + 有效性; - **仅方位记录**(仅一目检出,v1.0 允许):发布该目框中心作方位, `valid = false`,无距离;单目方位存在近场视差偏差(§6.6,v1.0 接受)。 ### 2.3 输出语义与消费侧衔接 - `valid == true` 的 `Z` 才可作为控制律距离通道输入;消费侧另有自己的 "有效性 + 正值 + 未超龄"三重门(见《视觉跟踪控制律技术路线》§6.4); - `valid == false`(域外/失配/一致性异常)→ 消费侧进入"无距离"策略 (方位闭环 + 定速接近,默认档),持续无距离达门限才退出近距操作 (消费侧 exit 门限,S1); - **`c_mid` 始终随检测发布**(域外仍有方位)——这是远场"方位闭环 + 定速接近"策略得以成立的输入基础; - 消费侧以 `track_id` 一致性校验本记录与追踪主目标对应(调用方约定 S3,库内不实现)。 --- ## 3. 坐标系与符号约定 ### 3.1 符号表 | 符号 | 含义 | 单位 | |------|------|------| | `B` | 基线长度(左右光心间距) | m | | `F` | 像素焦距(校正后 `fx = fy`) | px | | `cx, cy` | x/y 方向主点 | px | | `xL, yL` | 目标点在**左目(参考目)**图像中的像素坐标 | px | | `xR` | 同一目标点在右目图像中的像素坐标 | px | | `D` | 视差 = `xL − xR` | px | | `Z` | 前向距离(沿光轴分量) | m | | `X, Y` | 相机(左目)坐标系横向/纵向偏移 | m | | `X_C` | 目标在**模组中心系**的横向偏移 | m | | `R` | 斜距 | m | | `cL, cR` | 同一目标在左/右目中的**检测框中心** | px | | `c_mid` | 虚拟双目中心框中心(方位源) | px | **统一约定**:校正后**以左目为参考系**,视差 `D = xL − xR > 0` (正视差是物理前提;`D ≤ 0` 视为违例,§6.3)。 ### 3.2 公式(校正后坐标系) ```text D = xL − xR (同一物理特征点的 x 坐标差) Z = F × B / D X = (xL − cx) × Z / F (左目系) Y = (yL − cy) × Z / F R = sqrt(X² + Y² + Z²) ``` - **距离通道使用 Z(前向分量)而非 R**:与机头前向的期望射程语义对齐, 也与地面真值仪(手持激光测距仪)的测量方向一致(决策 D8); 小角度下 `Z ≈ R`,大偏航角目标时二者差异增大,地面验证解读数据须注意; - **X/Y 以左目系表达**;模组中心系下 `X_C = X − B/2`(左目光心在模组中线 −B/2 侧,符号与 §6.6 一致;原文 `+B/2` 为笔误),`B/2` 对 `Z`、`R` 的 影响可忽略(本机型 3cm)。 --- ## 4. 核心构件与状态清单 | 构件 | 职责 | 运行期持久状态 | 备注 | |------|------|---------------|------| | 流程编排 | 单周期五步流程(§5) | 无 | 每帧一次 | | 视差取点器 | 框 → 取点 x(同侧边缘,回退中心) | 无(纯函数) | §6.1 | | 匹配器 | 左右框配对 | 无(纯函数) | **接口注入**,默认贪心;可替换为匈牙利等而不动调用方 | | 测距计算 | `(D, 框)` → `(Z, X, Y, R, c_mid)` | 无(纯函数) | §3.2/§6.6 | | 有效性判定 | 域内 + 误差预算判定 | 无(纯函数) | §6.4 | | 一致性监控 | 时序层面质量自检 | **每目标**:上次视差 + 连续异常计数 | §6.7 | | 时间滤波器 | 距离低通 + 跳变重置 | **每目标**:上次滤波值、初始化标志、连续失效计数 | §6.5 | | 目标状态容器 | 隔离键解析 + 帧末老化清理 | **每目标**:最近框中心、最近出现帧 | 隔离键见下;连续 `filter_reset_frames` 帧未出现则整体清理 | | 告警节流器 | 异常日志限频 | 每类异常:首见标记 + 累计计数 | 第 1 次 + 每满 100 次 | **目标隔离键(v1.0 冻结)**:`track_id` 优先——左右目的 track_id 一致且 为正时,用 `(轨道, 类别, id)` 作键(v1.1 语义提前启用,上游追踪库已在 链路中);否则回退**框位置最近邻**(同类别、门限 `isolation_gate_px` 内、 本帧尚未被占用的最近状态,一一归属)。 重写/移植时最容易漏的是**每目标隔离**的一致性计数与滤波状态——按 "全局单份"实现会在多目标下互相污染。 --- ## 5. 单周期处理流程(主流程伪代码) ```text 函数 单周期处理(左帧, 右帧, 参数, now_ms) -> 目标距离记录列表: # ---- ① 输入违约检查 ---- 若 左帧.帧标识 ≠ 右帧.帧标识: 告警节流("左右帧非同帧,拒收") 返回 空列表 # ---- ② 取点(每目每框一次,纯函数) ---- 左点表 ← 对 左帧.框列表 逐框取点(同侧边缘 x) # §6.1 右点表 ← 对 右帧.框列表 逐框取点(同侧边缘 x) 丢弃 坐标非有限值 的框(不参与匹配,也不发布记录;告警节流) # ---- ③ 左右匹配(接口注入,默认贪心) ---- 配对表 ← 匹配器.匹配(左点表, 右点表, 参数.匹配) # §6.2 # ---- ④ 配对成功的目标:测距 + 方位源 + 有效性 + 滤波 ---- 对 配对表 中每个 (左框, 右框, 代价): D ← 视差选择(左框, 右框) # 同侧边缘;越窗且中心在域内→回退中心(§6.1) (Z, R) ← 测距(D, 参数.几何) # §3.2 c_mid ← (左框.中心 + 右框.中心) / 2 # §6.6 域内 ← 有效性判定(D, Z, 代价, 参数.有效性) # §6.4 门①② 一致性 ← 一致性监控(目标键).推进(D) # §6.7 置信度 ← 置信度映射(代价, 一致性) # §6.4 映射 有效 ← 域内 且 一致性 正常 若 有效: Z_out ← 滤波器(目标键).推进(Z, 参数.滤波) # §6.5 否则: 滤波器(目标键).记失效() # §6.5 失效策略 Z_out ← 无 发布 记录(帧标识, 类别, Z_out, R, D, c_mid, 左框, 置信度, 有效, 完整, 取样时刻 = now_ms) # ---- ⑤ 单目退化(仅一目检出) ---- 对 未匹配的左框: 发布 记录(仅方位 = 左框.中心, valid = false, 退化 = 单目) 对 未匹配的右框: 发布 记录(仅方位 = 右框.中心, valid = false, 退化 = 单目) # ---- ⑥ 空输入 ---- 若 两目框列表均为空: 发布 无目标记录(或空列表);不告警(正常空帧) ``` **失败路径语义**: | 情形 | 行为 | 日志 | |------|------|------| | 左右帧标识不一致 | 拒收本帧,输出空 | WARN 节流 | | 单目检测为空 | 另一目发布仅方位记录 | 不告警(正常退化) | | 匹配全部失败 | 全部按仅方位发布 | 不告警 | | 视差违例(`D ≤ 0` 或超界) | 该目标 `valid = false`,仍配对并发布 `D`/`c_mid` | WARN 节流 | | 边缘视差越窗、中心回退 | 该目标用中心视差解算(框宽差可能混入,§6.1) | WARN 节流 | | 框坐标非法(非有限值) | 丢弃该框,不参与匹配也不发布 | WARN 节流 | | 两目均无检测 | 无目标记录 | 不告警 | 高频热路径(每帧执行的数学)不打日志;所有异常日志按节流规范 (第 1 次 + 每满 100 次,带累计计数)。 --- ## 6. 各环节算法细节 ### 6.1 视差取点:同侧边缘(v1.0 主方案) 同一物理目标在两目中的检测框宽并不严格相等(检测抖动、外观差异), **框中心**视差会混入框宽差的一半,**同一侧边缘**视差可抵消框宽项: | 取点方式 | 误差来源 | 结论 | |----------|----------|------| | 框中心 | 两目框宽差直接进入视差 | 作对照/回退 | | **同侧边缘(v1.0)** | 边缘定位噪声 | **v1.0 主方案** | | 多边缘 + 亚像素精化(灰度重心/抛物线拟合) | 实现复杂度 | v1.1 | ```text 取法: D = 左框.左上角x − 右框.左上角x (同取左侧边缘) 回退: 边缘视差越窗 且 中心视差在域内 → 回退框中心并告警节流 两者均越窗 → 保留边缘值(供诊断与违例告警),由 §6.4 门 ① 判无效 ``` > **不做"左右两边缘各算一次取中值"(v1.0 冻结)**:两边缘视差的中值恒 > 等于二者均值,即 `(cL.x − cR.x)`——**框中心视差**,与本表"同侧边缘 > 抵消框宽差"的理由自相矛盾(早期原文笔误),故不实现;亚像素精化留 > v1.1(§8.3)。 ### 6.2 左右匹配:硬约束 + 贪心代价 **硬约束**(任一不满足直接拒绝配对,不进代价排序): - 类别一致; - `|yL − yR| ≤ τ_y`(校正后 y 应对齐;这是校正质量的运行期体现); - 框高相近:`|hL − hR| / max(hL, hR) ≤ τ_h`。 **视差域不是配对硬约束(v1.0 冻结)**:越界目标仍应配对、仍发布 `D` 与 `c_mid`(远场"方位闭环 + 定速接近"的输入基础),仅由 §6.4 门 ① 判 `valid = false`。若把域并入硬约束,越界目标会退化为无方位的失配记录, 与 §2.3/§5 失败路径表的语义冲突。 **代价与贪心**: ```text cost = |Δy| / τ_y + |Δh| / (τ_h × max(hL, hR)) 按 cost 升序逐一配对,cost < 1 才接受,一一配对(一个左框至多配一个右框) ``` - 本场景目标数极少(1~2 个),O(n²) 贪心足够(§10.3); - 失败处理:任一目未匹配 → 该目标本帧无距离(仅方位发布), 不阻塞其他目标。 ### 6.3 测距计算与违例处理 ```text Z = F × B / D (D ≤ 0:物理违例 → valid = false,告警节流) R = sqrt(X² + Y² + Z²) (参考输出) ``` - `D ≤ 0` 在校正正确的正视差几何下不应出现;出现说明匹配错误或校正 残差过大,宁可无效不可给值; - `D ≤ 0` 时**不出解算结果**(无 `Z`、无 `R`);超界(`0 < D < D_min` 或 `> D_max`)仍解算 `Z`/`R` 供诊断与告警,同样 `valid = false`; - 边缘取点为像素级整数(取整/插值规则由实现自定,但**左右目必须一致**); - 所有除法分母(`D`)在使用前校验为正。 ### 6.4 有效性判定:三道门(缺一不可) | 门 | 判据 | 拦截什么 | |----|------|---------| | ① 域内 | `D ∈ [D_min, D_max]`(含边界);距离域由 `Z = F·B/D` 派生 | 远场小视差病态 + 近场大视差盲区 | | ② 误差预算 | `δZ(δD=1px) = Z²/(F·B) ≤ δZ_max` | 有效域边界处的精度下限 | | ③ 一致性正常 | §6.7 监控未判异常 | 持续视差跳变(标定漂移/同步故障/匹配错误) | ```text valid = 域内 且 误差预算内 且 匹配成功 且 一致性正常 ``` 匹配成功由第 ③ 步保证(只有配对目标才进入本节判定)。 **门 ① 以视差域为唯一真源(v1.0 冻结)**:配置只存 `disparity_min_px / disparity_max_px`,`Z_min / Z_max` 由 `Z = F·B/D` 派生为只读量——`D` 是直接观测量,`Z` 是导出量,用 `D` 判域可避免 "距离阈值反推视差阈值"的舍入不一致;两处冗余存储正是该不一致的根源 (原文 §9.2 占位值即不自洽:`D_min = 3px` ⇔ 19.2m ≠ 20m),故不再 "互推并校验自洽"。 **门 ② 的 δD 基准固定为 1px(⚠占位,v1.0 冻结)**:δD 的真实构成 (边缘定位噪声 + 校正残差 + 帧不同步 + 压缩伪影,§7.1)留待地面真值 拟合(§12.2),当前不做估计、不随目标状态变化。 **置信度映射(⚠占位,v1.0 冻结)**:基值 = `clamp(1 − 匹配代价, 0, 1)`; 连续跳变 ≥ N 帧(§6.7)时乘降级系数(⚠0.5);判 invalid(≥ M 帧)时置 0。 ### 6.5 时间滤波与跳变重置(每目标独立) ```text 推进(Z_new): 若 未初始化: 状态 ← Z_new; 返回 Z_new 若 |Z_new − 上次| > 跳变门限: 状态 ← Z_new # 直接重置而非滤波,防止拖尾 否则: 状态 ← 上次 + α × (Z_new − 上次) # 一阶低通,α ∈ (0,1] 返回 状态 记失效(): # 无效帧与"目标本帧缺席"均记失效(§6.5 失效策略) 连续失效计数 +1 若 连续失效 ≥ filter_reset_frames: 清空滤波状态(下次有效帧重新初始化) ``` - **单帧毛刺由跳变重置处理,持续性异常由 §6.7 一致性监控处理**, 两者职责不同不得合并; - `α = 1` 等效不滤波;滤波只在**有效帧**之间进行,无效帧不参与平滑; - 清理门限 `filter_reset_frames` **独立配置**(不复用 §6.7 的 M,⚠占位 5 帧),防"陈旧状态平滑新测量"; - 参考斜距 `R` 与**滤波后**的 `Z_out` 同基准(`X/Y/Z ∝ Z`,按 `Z_out/Z_raw` 精确换基,保证 `R ≥ Z`,§2.2); - 滤波引入的群延迟约 `1/α` 帧(⚠占位 α=0.3 → 约 3 帧 ≈ 0.1s), 接近阶段的距离滞后由消费侧 PID 与限幅吸收。 ### 6.6 方位源:虚拟双目中心 `c_mid` **问题**:双目模组两枚相机分列模组中线两侧(各偏 ±B/2),都不在机身 中轴上。校正后严格成立的只有 **y 对齐**(垂直方向不受两目差异影响); 水平方向上直接以某一目(如左目)的像素做方位控制,收敛后对准的是 **该相机的光轴**,相对模组中线存在恒定视差偏差: ```text β_bias ≈ atan( (B/2) / Z ) ``` | 距离 Z | 角度偏差 | 像素等效(F≈960px,⚠占位) | |-------:|-------:|-------:| | 3 m | 0.57° | ≈10 px | | 10 m | 0.17° | ≈2.9 px | 远距离可忽略,**近场不可忽略**;偏差方向恒定、随距离减小。 **精确修正(零额外成本)**:校正后几何下,位于基线中点的**虚拟相机** 对任一物理点 P 的投影恰为该点在两目投影的**等权平均**: ```text xL = cx + F·(X_C + B/2)/Z (左目光心在模组中线 −B/2 侧) xR = cx + F·(X_C − B/2)/Z (右目光心在模组中线 +B/2 侧) (xL + xR) / 2 = cx + F·X_C/Z (= 虚拟相机投影,逐点精确,无近似) ``` 检测框的每条边缘都是物理点、逐点满足上式,因此: ```text 虚拟框 = 两目框逐边平均 ⇒ 虚拟框中心 c_mid = (cL + cR) / 2 c_mid.y = (cL.y + cR.y) / 2 (校正后两目 y 天然相等,取平均兼得降噪) ``` 即**等权平均等价于把相机搬到模组中线**,方位控制对标的是虚拟中心相机, 与机体中轴的安装偏移(如有)属安装外参,按安装标定处理。 **方位源与视差取点是两个不同的取点,不得混用**: | 用途 | 取点 | 原因 | |------|------|------| | 视差 D(测距) | **同侧边缘** | 抵消两目框宽差(§6.1) | | 方位 c_mid(控制) | **框中心等权平均** | 瞄点语义 = 虚拟框中心;误用边缘点平均会把瞄点偏到目标边缘(约半个框宽) | **单目退化**(仅一目检出,v1.0):退化为该目框中心,接受上表偏差; v1.1 可用最近一次有效 Z 做定值修正 `Δx = F·(B/2)/Z` px。 ### 6.7 内部一致性监控(替代原激光交叉校验) 机载激光移除后无外部距离基准,飞行中只能靠自身时序一致性监控数据 质量(**只能降级、不能纠偏**,绝对精度靠地面静态验证,§12.1): ```text 逐目标推进(D): 视差跳变 = |D − 上次 D|(或等效 Z 跳变量;门限 consistency_jump_px) 连续 N 帧跳变超门限 → confidence 降级(⚠×0.5) 连续 M 帧异常 → valid 置 false 并 WARN(节流) 任一正常帧 → 清零连续计数 ``` - 匹配层面质量(|Δy| 残差、框高一致性、代价门限)已由 §6.2 硬约束 承担;本节只管**时序层面**; - 跳变门限 `consistency_jump_px`(⚠占位 3px)、N / M(⚠ 3 / 5 帧)均 为占位,实测后整定(§9.3); - **推进时机(v1.0 冻结)**:只在配对成功帧推进——仅方位帧没有 `D` 观测量,不推进 D 序列、也不清零;目标缺席/无效帧的**滤波失效**由 §6.5 记,两条状态机职责不混; - 监控判 invalid 是"质量语义"而非"错误":输出仍正常发布(仅方位), 由消费侧按无距离策略接管。 --- ## 7. 误差模型与有效距离域 ### 7.1 误差模型 由 `D = F·B/Z` 微分得: ```text δZ ≈ Z² · δD / (F·B) (绝对误差,随距离平方增长) δZ / Z ≈ Z · δD / (F·B) (相对误差,随距离线性增长) ``` `δD` 的构成:检测框边缘定位噪声 + 校正残差(|Δy| 失配混入)+ 帧不同步 引入的运动虚假视差 + 有损压缩伪影(平台相关,抽象计入边缘噪声)。 基线与焦距误差(δB/B、δF/F)线性传递、量级小,出厂标定后可忽略。 **这是"双目只能作近场距离源"的定量依据**,也是第 8 章多数缺点的根源。 ### 7.2 有效距离域判据 ```text valid 域 ⇔ D ∈ [D_min, D_max](⚠占位 3 ~ 57.6px) 且 δZ(δD = 1px) ≤ δZ_max(⚠占位 2m) ``` - 按占位焦距计算:宽角档(HFOV≈90°)有效域约 **≤15m**、窄角档 (HFOV≈60°)约 **≤20m**(**⚠占位,待厂商实焦距回填后重算**; 数值回填的权威位置在《双目深度估计思路》§5.3 误差表); - 近界:`D_max`(或 `Z_min`)限定最近可测距离——目标过近时视差超上限、 框占满画面、边缘取点失效(§8 第 3 条); - 敏感性:误差 ∝ 1/B。更换大基线机型误差按比例缩小、有效域等比扩大 ——**换机型(P6)是扩大远场能力的唯一杠杆**。 ### 7.3 远场空洞(如实声明) 双目有效域之外(预计 >15~20m,待焦距回填),系统**不存在任何机载 目标距离源**。补偿方式是消费侧的远场策略(方位闭环 + 定速接近,D4), 而非强行使用不可靠的远场估计。本模块的职责边界是:把"测不了"诚实 地表达为 `valid = false` + 持续发布方位。 --- ## 8. 职责、边界与已知缺点 ### 8.1 职责(一句话版) > 对同帧左右检测框做立体几何解算:**有效域内给出目标前向距离, > 全程给出虚拟中心方位,测不了时诚实输出无效**——供控制律做 > 近场距离闭环与远场方位闭环 + 定速接近。 边界(不做什么)见 §1.4;与避障深度模型的分工见《双目深度估计思路》§1.3。 ### 8.2 已知缺点与局限(如实声明,不得因文档目的删减) | # | 缺点 | 根因 | 影响 | 现行对策 / 接受理由 | |---|------|------|------|---------------------| | 1 | **误差随距离平方增长** | `δZ ∝ Z²`(§7.1) | 远距离距离值不可用 | 有效域判据硬性拦截(§6.4);域外交给定速接近 | | 2 | **远场空洞** | 有效域 >15~20m 外无任何机载距离源 | 远场无法距离闭环 | 消费侧 D4 策略(方位闭环 + 定速接近);扩域唯一杠杆是换机型(P6) | | 3 | **近场盲区** | 视差超 `D_max`、框占满画面、边缘取点失效 | 反制逼近的最后阶段恰是最需要距离时失效 | 消费侧判丢刹车/定速接近兜底;`Z_min` 如实设界 | | 4 | **检测框是单点依赖** | 全部几何量从框导出 | 无检测即无距离也无方位;框抖动直接进入 δD | 检测置信度门槛在检测侧;追踪库 Coast 补帧兜底 | | 5 | **框级精度上限** | 取点在框边缘/中心,非特征级匹配 | 精度天花板高于特征级方案 | 接受(几何换算换实时性,§10.1);v1.1 亚像素精化 | | 6 | **小视差病态** | 远距 D → 1px,量化误差主导 | 远场 δD=1px 假设过于乐观 | 同上由有效域拦截 | | 7 | **标定与校正依赖** | y 对齐、无畸变是解算前提 | 未标定则系统性偏差,甚至全盘不成立 | P2 出厂标定为 v1.0 首要前置;不达标则 v1.1 自标定提前 | | 8 | **帧不同步敏感** | 非同瞬曝光 → 运动目标虚假视差 | 快速横移目标距离失真 | 同帧契约(§2.1)+ 13 章快速横移验证;同步形态待 P3 | | 9 | **固定基线/焦距** | 单一几何配置 | 近盲远废的区间固定 | 参数化配置;换机型只改配置(红线 2) | | 10 | **贪心匹配局限** | O(n²) 局部最优 | 目标多/邻近/遮挡时错配风险 | 目标数极少(1~2)可接受;匹配器接口注入保留替换空间 | | 11 | **无飞行中绝对基准** | 激光移除后无外部真值(D2/D8) | 一致性监控只能降级、不能纠偏 | 绝对精度靠地面手持激光测距仪静态验证(§12.1) | | 12 | **单目退化有瞄偏** | 单目光轴偏离模组中线(§6.6) | 仅方位记录时方位存在 0.5° 量级近场偏差 | v1.0 接受并如实标注退化;v1.1 定值修正 | **阅读提示**:1/2/3/6/9 是几何固有,只能拦截或换硬件,不能修好; 4/5/8/10/12 是工程折中,有 v1.1/v2.0 改进路径;7/11 是流程前提, 靠标定与地面验证闭环。 ### 8.3 缺点对策索引 | 路径 | 覆盖的缺点 | |------|-----------| | v1.1(算法) | 亚像素边缘(5)、真值拟合误差修正项(1/6)、track_id 辅助匹配(10)、单目定值修正(12)、自标定(7,视 P2 结论提前) | | v2.0(远期) | 实例分割替代框(4/5)、端到端立体评估(5)、更大基线/长焦机型(1/2/3/6/9,P6) | | 消费侧兜底 | 定速接近 + 判丢刹车 + exit 门限(2/3 的安全网) | | 地面验证 | 7/8/11 的唯一闭环手段 | --- ## 9. 配置参数全量表 全部参数**配置外置、启动期一次加载并校验**:缺项、类型错误、非法取值 一律拒绝进入运行期(fail-fast,语义要求,不绑定具体配置格式)。 所有数值均为占位(⚠),整定后回填。 ### 9.1 几何组(来自标定,P1/P2) | 键 | 单位 | 占位值 | 作用 | |----|------|-------|------| | `baseline_m` | m | 0.06 | 基线 B;更换机型只改此项 | | `fx_px` / `fy_px` | px | 960.0(⚠占位,待 P1) | 像素焦距(校正后 `fx = fy = F`) | | `cx_px` / `cy_px` | px | 960.0 / 540.0(⚠占位,待 P2) | 主点 | ### 9.2 匹配组 | 键 | 单位 | 占位值 | 作用 | |----|------|-------|------| | `tau_y_px` | px | 2.0 | \|Δy\| 硬约束(同时是校正质量的运行期体现) | | `tau_h_ratio` | — | 0.25 | 框高相对差硬约束 | | `disparity_min_px` | px | 3.0 | 最小可测视差(远界);**域唯一真源**(§6.4) | | `disparity_max_px` | px | 57.6 | 最大可测视差(近界);⚠占位:按 F=960/B=0.06 反推 ⇔ 1.0 m | | `distance_min_m` / `distance_max_m` | m | **不再配置** | v1.0 冻结:距离域由 `Z = F·B/D` 从视差域派生为只读量(§6.4) | ### 9.3 有效性组 | 键 | 单位 | 占位值 | 作用 | |----|------|-------|------| | `max_delta_z_m` | m | 2.0 | 误差预算 `δZ(δD=1px)` 上限(δD 基准固定 1px,§6.4) | | `consistency_N_frames` | 帧 | 3 | 连续跳变降置信度的帧数 | | `consistency_M_frames` | 帧 | 5 | 连续异常判 invalid 的帧数 | | `consistency_jump_px` | px | 3.0 | 单帧视差跳变门限(§6.7);**v1.0 补充项**(原文缺项) | ### 9.4 滤波组 | 键 | 单位 | 占位值 | 作用 | |----|------|-------|------| | `smooth_alpha` | — | 0.3 | 一阶低通系数(§6.5 定义,1 = 不滤波) | | `jump_reset_m` | m | 5.0 | 单帧跳变直接重置的门限 | | `filter_reset_frames` | 帧 | 5(⚠独立配置,不复用 M) | 连续失效多久后清空滤波状态(§6.5) | ### 9.5 目标隔离组 | 键 | 单位 | 占位值 | 作用 | |----|------|-------|------| | `isolation_gate_px` | px | 50.0 | 最近邻兜底的匹配门限(§4);**v1.0 补充项**(原文缺项) | --- ## 10. 设计取舍记录(为什么不是别的做法) ### 10.1 两次目标检测代替稠密像素匹配 双目深度最难的是逐像素匹配:稠密立体匹配(SGBM 类)在该分辨率与 嵌入式 CPU 预算下不可行,而系统需求只是**少量目标的距离**。用左右 各一次轻量检测 + 框级几何换算绕开逐像素匹配,以"检测框天然给出 ROI" 换"精度天花板"(§8 第 5 条)。检测算力实测单核 20~30ms,NPU 预算 成立(平台侧见《双目深度估计思路》第 9 章)。 ### 10.2 不先上端到端深度网络 需采集标注数据集、可解释性差、误差行为不可解析;先以几何法建立 **可验证的真值基线**,端到端立体/深度网络留 v2.0 评估。 ### 10.3 贪心匹配而非匈牙利 目标数 1~2 个,贪心与全局最优几乎必然同解;O(n²) 足够。匹配器做 **接口注入**,保留替换为匈牙利/带连续性先验算法的空间而不动调用方。 ### 10.4 同侧边缘而非框中心取视差 框宽差直接污染中心视差;同侧边缘可抵消框宽项(§6.1,原稿缺陷 2 的修正)。 ### 10.5 距离通道用 Z 不用 R 与机头前向期望射程语义对齐,也与地面真值仪测量方向一致(决策 D8); R 仅作参考输出。 ### 10.6 方位源取两目框中心等权平均(虚拟中心像素) 两目均偏于模组中线 ±B/2,单目存在近场视差偏差(3m 处约 0.57°); 等权平均是投影几何**精确解**(§6.6,原稿"offset 加权"构想的正确形式, 决策 D5)。注意与视差取点(同侧边缘)分工不同、不可混用。 ### 10.7 双目为机载唯一距离源、域外定速接近 替代激光(b96111e / D2);远场误差平方发散,强行估计不可靠——以 "诚实 invalid + 持续方位"支撑消费侧的方位闭环 + 定速接近(D4), 而不是在算法侧掩盖远场空洞。 --- ## 11. 实现与重写指引 ### 11.1 必须持久化的状态(漏一个就变行为) | 状态 | 所属 | 初值 | 何时改变 | |------|------|------|---------| | 上次视差 + 连续异常计数 ×目标 | 一致性监控 | 无 / 0 | 配对帧写入上次视差;异常 +1 / 正常清零 | | 上次滤波值 ×目标 | 时间滤波器 | 无(未初始化) | 每有效帧写入 | | 滤波初始化标志 ×目标 | 时间滤波器 | false | 首个有效帧置 true;清空时回 false | | 连续失效计数 ×目标 | 时间滤波器 | 0 | 每无效/缺席帧 +1 / 有效帧清零 | | 最近框中心、最近出现帧 ×目标 | 目标状态容器 | 首帧写入 | 每次解析隔离键时刷新;连续 `filter_reset_frames` 帧未出现则整体清理 | | 帧序号 | 流程编排 | 0 | 每帧 +1(被拒收的违约帧不加) | | 告警节流状态 ×异常类 | 节流器 | 首见未打印 + 计数 0 | 每次异常更新 | 构造期预计算量:针孔系数与常量(如 `F·B`)一次算好,热路径只做乘除。 ### 11.2 数值与精度注意 | 事项 | 处理方式 | 理由 | |------|---------|------| | 除零 | `D ≤ 0` 先判违例再除 | 正视差是物理前提(§6.3) | | 视差取整 | 左右目规则必须一致 | 不一致会引入系统性 δD | | 域判定基准 | 用 `D` 判域而非 `Z` | 直接观测量,避免往返舍入(§6.4) | | 域配置单一来源 | 只配视差域,距离域派生 | 两处冗余存储是互推舍入不一致的根源(§6.4/§9.2) | | 误差预算基准 | δD 固定 1px(⚠占位),不做在线估计 | 真实 δD 留待地面真值拟合(§12.2) | | 浮点比较 | 阈值比较用 `≥/≤` 含边界语义 | 边界帧的归类必须确定 | ### 11.3 并发与生命周期 - 本模块是**纯计算单元**:驱动方式(独立线程 / 订阅回调 / 同步调用) 由平台层决定,本文只约定数据契约; - 同一实例**不得并发调用**单周期处理(含滤波/一致性状态的无锁前提); - 输出记录为**值拷贝**语义:多消费者各自持有快照,不得共享可变状态; - 单周期处理应当无阻塞、无 IO(日志走节流通道,不落在数学热路径上)。 ### 11.4 可测试性设计(构件边界即测试边界) | 构件 | 是否纯函数 | 测试要点 | |------|-----------|---------| | 取点器 | 是 | 同侧边缘取值;框宽差不进入视差(构造两目等框不同宽断言 D 相同);越窗回退中心;边界含等号 | | 匹配器 | 是 | 硬约束拦截各一例;贪心排序;一一配对;cost ≥ 1 拒绝 | | 测距计算 | 是 | 已知 Z 反推 D 构造框对,断言 `Z = F·B/D` 回收;`D ≤ 0` 违例;`c_mid` 等权平均精确性(§6.6 恒等式);`R` 与发布 Z 同基准(`R ≥ Z`) | | 有效性判定 | 是 | 三道门各一例;边界帧(恰在域界)归类确定;预算门通过/拦截两侧 | | 时间滤波器 | 否 | 低通收敛;跳变重置不拖尾;失效清理 | | 一致性监控 | 否 | N 帧降级、M 帧判 invalid、正常帧清零 | | 目标隔离 | 否 | track_id 一致跨大位移保持状态;最近邻越门限新建;老化清理 | | 全流程 | 否 | 合成帧对端到端:单目标/多目标/单目退化/非同帧拒收/记录顺序/非有限框/reset | **无需真实图像**:全部测试用合成框对驱动,几何是解析可断言的。参考实现 的构件级用例已全部通过(§12.1)。 --- ## 12. 验证路线与待定项 ### 12.1 验证项 | 项 | 方法 | 通过标准 | |----|------|----------| | 构件级 | §11.4 合成框对单测 | 全部通过(无硬件依赖);Python 参考实现 `utils/stereo_ranger/` 用例已跑通 | | 校正质量 | 静态场景统计匹配框 \|Δy\| 分布 | P95 ≤ 1px(⚠占位);不达标触发自标定提前 | | 测距精度 | 5/10/15/20m 静态标靶,以**地面手持激光测距仪**为真值(非机载,D8),记录误差曲线 | 趋势与 §7 一致;有效域内 δZ ≤ 2m(⚠占位) | | 帧同步 | 目标横向快速移动,观察视差时序抖动 | 无系统性虚假视差 | | 控制联动 | 回放/SITL:距离闭环 ↔ 定速接近切换、invalid 持续降级路径 | 《视觉跟踪控制律技术路线》第 7 章场景全覆盖 | | 日志纪律 | 检查异常路径日志 | 节流规范(第 1 次 + 每 100 次,带累计计数) | ### 12.2 待定项 开放问题(P1 焦距规格、P2 出厂标定、P3 帧同步形态、P6 换机型、 P7 性能实测、P8 避障激光去留)以《双目深度估计思路》第 15 章为权威 清单,本文不另立编号;其中: - **P1/P2 直接决定本文 §7 结论与 §9 几何组能否从占位变实值**; - **v1.0 实现补充的占位量**:`consistency_jump_px`(3px)、 `isolation_gate_px`(50px)、置信度降级系数(0.5)、误差预算基准 δD (固定 1px)——随 P1/P2 回填与实测一并整定(§9.3/§9.5); - **P6 是扩大有效域的唯一杠杆**(§7.2); - P8(避障单点激光去留)不影响本链路——目标测距职责已由本模块承担。 ### 12.3 红线 1. **占位数值不得用于飞行决策**:§7/§9 中所有 ⚠ 数值未经厂商数据与 整定确认前,本模块输出仅限静态标靶/回放/台架验证; 2. **相机参数与阈值一律配置外置**,禁止写死(后续可能更换机型); 3. **域外/失配必须输出 `valid = false`**,不得强行估计距离(远场策略 的正确性建立在有效性不撒谎之上); 4. **标定与地面真值验证完成前不得接入实飞控制回路**(与消费侧控制律 红线一致,见《视觉跟踪控制律技术路线》§12.3)。