1

PASS · raw annular → 矩形全景图展开(v1)

核心哲学:先报告事实,再讲方法,最后讲差距——以工程评审视角看进展

单帧 + Python Pseudo-Calibration v1 POC 已完成 非物理标定
0.8804
训练 NCC
0.9038
评估 NCC
30 张
demo 产物
① 任务定义

PASS(Panoramic Annular Semantic Segmentation)要求把井筒/钻孔全向相机采集的 raw annular 环形图(6000×4000)展开成矩形全景图(2048×692),作为语义分割网络的训练域。

仓库本身不包含raw → panorama 展开代码;本轮工作补齐了这一前置步骤,用 image-pair driven pseudo-calibration(伪标定)在无真实相机标定 JSON 的前提下完成了 POC。

详细交接文档:../PASS/HANDOVER.md(简体中文 single source of truth)。

② 结果对比 · Before & After(3 序列 × 2 张)

左:raw 环形图(采集域,6000×4000);右:展开后的矩形全景(训练域,2048×692)。共 6 张样本,覆盖 3 个采集序列(1027 / 1210 / 7100)。

A · 1027/0raw 6000×4000
raw 1027/0
B · 1027U/0unfolded 2048×692
unfolded 1027/0
A · 1027/5raw 6000×4000
raw 1027/5 (use 0 as proxy)
(同序列第 5 张;与左同图示意)
B · 1027U/5unfolded 2048×692
unfolded 1027/5
A · 1210/1raw 6000×4000
raw 1210/1
B · 1210U/1unfolded 2048×692
unfolded 1210/1
A · 1210/8raw 6000×4000
raw 1210/8 (use 1 as proxy)
(同序列第 8 张;与左同图示意)
B · 1210U/8unfolded 2048×692
unfolded 1210/8
A · 7100/1raw 6000×4000
raw 7100/1
B · 7100U/1unfolded 2048×692
unfolded 7100/1
A · 7100/6raw 6000×4000
raw 7100/6 (use 1 as proxy)
(同序列第 6 张;与左同图示意)
B · 7100U/6unfolded 2048×692
unfolded 7100/6
多样性说明:3 序列由不同采集设备或不同日期得到:1027 含 334 张(公园/林荫道),1210 含 700 张(街道/交叉路口),7100 含 16 张(同一场景连拍)。每序列抽 2 张以保证覆盖:
  • 1027: 0(首张) + 5(中间段)
  • 1210: 1(首张) + 8(中段)
  • 7100: 1(首张) + 6(中段)
raw 侧因未做"配对索引到 5/8/6"(PASS 库未给 raw/published 编号映射表),这里用同序列 0/1 作 proxy;如需严格配对请用 6.5 节给出的 24 对复核 NCC 数字。
③ 方法:环形 → 矩形的 8 参数伪标定

用一个共享的环形 remap 模型近似 published 矩形全景的展开方式:

· 中心 (center_x, center_y)、内外半径 (inner_radius, outer_radius)

· 径向非线性指数 radial_gamma

· 方位角偏移 angle_offset_deg、横纵翻转 flip_x, flip_y

scipy.optimize.minimize(method="Powell") 在 6 对 raw/published 匹配样本上做归一化互相关(NCC)最大化。

决策轴定位
模型族: 自定义伪标定(非 py-OCamCalib 物理标定)
输入域: raw 6000×4000 JPG
输出域: unfolded 2048×692 PNG
优化器: Powell (scipy),无梯度
度量: 灰度归一化互相关 (NCC)
训练数据: 6 对(每序列 2 对)
关键公式(参考 scripts/pass_pseudo_calibration_lib.py:remap_from_parameters
设全景图坐标 (X, Y) ∈ [0, W) × [0, H)
  x_norm = X / W   ∈ [0, 1)
  y_norm = Y / H   ∈ [0, 1)

θ = angle_offset_rad + (2π) · (flip_x ? 1 - x_norm : x_norm)
ρ_norm = (flip_y ? 1 - y_norm : y_norm) ^ radial_gamma
ρ = inner_radius + (outer_radius - inner_radius) · ρ_norm

源坐标 (u, v) = (center_x + ρ·cosθ, center_y + ρ·sinθ)
然后 cv.remap 双线性插值采样。
④ 验证:NCC 指标
指标数值说明
训练 NCC(6 对)0.8804拟合阶段同源样本
评估 NCC(6 对)0.9038同源独立切分
1027 evaluation0.8815per-sequence
1210 evaluation0.8814per-sequence
7100 evaluation0.9485per-sequence(场景最稳定)
24 对覆盖样本复核≈ 0.7018demo 产物 vs published 直接配对
结论:训练/评估 NCC 均在 0.88+,说明伪标定能稳定学到一种有意义的 annular → panorama 变换;24 对复核 ≈ 0.70 不是逐像素完美匹配,是 pseudo-calibration 的天花板。
⑤ 当前局限(按重要性排序)
  1. 1.非物理标定:模型用 8 参数拟合,是图像配对反求,不是 chessboard 物理标定,理论上不能完全代表真实镜头畸变。
  2. 2.拟合样本小:当前 6 对(每序列 2 对),运行时/鲁棒性折中;可通过 --fit-pairs-per-sequence 12 提升但耗时显著增长。
  3. 3.只处理 RGB:未做 GT 投影(Annotation/<U>/*.png);若需要,标签必须用最近邻,不能用双线性。
  4. 4.单帧 + Python:未做视频流;unfolder 仍是 Python 实现。
  5. 5.label 语义不匹配Groundtruth/label.txt 是 6 类(Road/Car/Crosswalk/Curb/Person/Sidewalk),预训练模型 erfpspnet.pth 是 28 类,混用需 class id 重映射。
  6. 6.GT 数据未挂上dataset/gtFine/pass/ 不存在;eval_color*.py --subset pass 只能做无 GT 推理。建议 ln -sAnnotation/
⑥ 未来目标 · 图 C 占位
A · 当前
raw (today)
单帧 + Python
Pseudo-Calibration
B · 已完成
unfolded (today)
展开到 2048×692
NCC 0.8804 / 0.9038
C · 未来
实时视频 + C++ + AI 分割
see what AI sees
C++ 实现已就位(仓库内)
unfolders-OCamCalib/cpp-omni_cam-master/src/ocam.cpp(6,631 B)已经能完成类似展开, 桥接视频流的差距主要是:
  1. 把当前 scripts/pass_pseudo_calibration_lib.py::remap_from_parameters 翻译为 C++ cv::remap
  2. PASS-Datasets/IV2019_1384x3432.mp4(74.6 MB)做实时帧源。
  3. 串接 trained_models/erfpspnet.pth 的 ONNX/C++ 推理输出实时彩色分割。
⑦ 交付物索引
代码
  • scripts/fit_pass_pseudo_calibration.py 拟合
  • scripts/unfold_pass_with_pseudo_calibration.py 应用
  • scripts/pass_pseudo_calibration_lib.py 共享模型
  • scripts/run_pass_pseudo_calibration_demo.sh wrapper
产物 / 文档
  • pseudo_calibration/pass_annular_pseudo_calibration_v1.json
  • dataset/leftImg8bit/pass_pseudo_calibrated_demo/{1027U,1210U,7100U}/*.png 30 张
  • HANDOVER.md 唯一权威交接文档(简体中文)
PASS · 进展展示 · 方案 1/3(技术汇报型)· 数据截至 2026-06-03