## `StripStitch.py` 说明文档(遥感航带批量配准) `StripStitch.py` 用于 **批量将文件夹内的 `.bip` 航带影像配准到一张参考 GeoTIFF(`.tif`)底图**。脚本默认启动 **GUI(Tkinter)**,也支持通过 `--cli` 走“无界面批处理”(但当前版本 **没有 argparse 参数**,CLI 模式仍使用脚本内的默认配置/或你手动改常量)。 --- ## 1. 功能概览 - **批量处理**:遍历 `BIP_DIR` 下的 `*.bip`,逐个配准到参考底图。 - **自动裁剪参考 ROI**:根据源图有效像素掩膜推算与底图的重叠范围,并在底图上取 ROI(可额外 padding)。 - **特征匹配**:通过 `vismatch.get_matcher()` 调用多种 matcher(可选 GPU/CPU)。 - **质量控制**: - 掩膜羽化(降低硬边界导致的假匹配) - 掩膜边缘带剔除(减少“掩膜边界”上的伪匹配点) - 纹理过滤(低梯度/低纹理区域的匹配点剔除) - 最少内点数/最少内点比例阈值 - **多模型变换尝试并自动选最优**:按你设置的优先级尝试 `similarity/affine/homography/piecewise_affine/polynomial/tps...`,以重投影误差(p95)选择最优。 - **输出**: - 配准后的 `.bip`(ENVI driver) - 匹配可视化图(匹配线、关键点) - 统计 CSV(每个航带一行:内点数、内点比例、选用模型、误差等) - **可选底图掩膜**:先用另一个 mask GeoTIFF 对参考底图做掩膜生成新底图,再用新底图进行配准(依赖 `tif_caijain.py`)。 --- ## 2. 运行方式 ### 2.1 GUI(默认) 在脚本所在目录执行: ```bash python StripStitch.py ``` GUI 会打开“遥感影像批量配准工具”,在界面里选择: - 参考底图(GeoTIFF) - BIP 文件夹 - 输出文件夹 - matcher、设备(CUDA/CPU) - 变换模型优先级 - 一系列阈值/过滤参数 点击“开始”后批处理运行,日志会实时显示;可点击“停止”中断。 ### 2.2 CLI(无界面批处理) ```bash python StripStitch.py --cli ``` 注意: - 当前脚本仅通过 `if "--cli" in sys.argv` 切换模式,**没有命令行参数解析**。 - CLI 模式使用脚本顶部的默认常量(如 `REF_TIF / BIP_DIR / OUT_DIR / MATCHER_NAME ...`)构造配置。 - 如果你希望 CLI 可配置参数,需要额外改造(例如用 `argparse`)。 --- ## 3. 输入数据要求 - **参考底图**:GeoTIFF(`.tif`),必须有 **有效 CRS/transform**(脚本会报错或无法正确投影/裁剪)。 - **待配准航带**:ENVI BIP(扩展名 `.bip`,内部 profile 由 `rasterio` 读取)。 - **坐标系**: - 源 `.bip` 若缺少 CRS,脚本会尝试使用参考底图 CRS 继续(可能导致错误配准,建议为源数据补齐 CRS)。 - ROI 的推算使用 `rasterio.warp.transform_bounds` 从源 CRS 转到参考 CRS。 --- ## 4. 输出结构与文件命名 假设输出目录为 `OUT_DIR`,运行一次批处理会生成: - **配准结果**:`OUT_DIR/_registered.bip` - 写入使用 `rasterio.open(..., driver="ENVI", interleave="bip")` - 旁边通常会伴随 ENVI 的头文件(如 `.hdr` 等,取决于 `rasterio/GDAL` 行为) - **可视化**:`OUT_DIR/visualizations/` - `_matches.png`:匹配线可视化 - `_keypoints_src.png`:源图关键点 - `_keypoints_ref.png`:参考 ROI 关键点 - **统计**:`OUT_DIR/stats/registration_stats_.csv` - 列:`timestamp, filename, num_inliers, num_matches, inlier_ratio, selected_method, median_error, p95_error, success` - **(可选)掩膜后的参考底图**:`OUT_DIR/masked_refs/_masked_.tif` - 仅当 GUI 勾选“启用底图掩膜”且 `tif_caijain.py` 可用时生成 --- ## 5. 参数说明(GUI 与脚本配置一致) ### 5.1 基础路径 - **参考 TIF 文件**:配准目标底图(匹配在底图 ROI 上进行)。 - **BIP 文件夹**:批量遍历 `*.bip`。 - **输出文件夹**:结果、可视化、统计都写入这里。 ### 5.2 底图掩膜(可选) GUI 勾选“启用底图掩膜”后: - 需要提供 **掩膜 TIF**,并要求与底图 **严格对齐**(同 CRS、分辨率、范围、尺寸)。 - 掩膜值为 `remove_value` 的区域会被设置为 NoData(由 `tif_caijain.mask_data_by_binary_mask` 实现)。 - 脚本会先生成“掩膜后的底图”,后续配准基于该底图进行。 ### 5.3 matcher 与设备 - **匹配算法(matcher_name)**:由 `vismatch.get_matcher(name, device=...)` 创建。 - GUI 下拉框内内置了一长串候选(如 `matchanything-roma`, `loftr`, `sift-lightglue`, `roma`, `xfeat-star` 等)。 - 不同 matcher 在速度/鲁棒性/显存占用方面差异很大。 - **设备(device)**: - `cuda`:更快,但需要 GPU + CUDA 环境 - `cpu`:更通用,但会慢 ### 5.4 变换模型(按优先级) 可多选并排序;脚本会按优先级逐一估计并评估误差,最终选 p95 重投影误差最小者。 常用含义(对应 GUI 列表): - **`similarity`**:相似变换(平移 + 旋转 + 等比缩放) - **`affine`**:仿射变换(含非等比缩放/切变) - **`homography`**:单应(透视)变换,最灵活但更易受离群点影响 - **`piecewise_affine` / `polynomial` / `polynomial_order3` / `tps`**:非刚性/高阶模型(依赖可选库,见“依赖”) ### 5.5 匹配与 ROI 参数 - **匹配最大边长(match_max_side)**:匹配前会等比缩小到最大边不超过该值。越大越慢、细节更多。 - **ROI 填充像素(roi_pad_px)**:从源有效区域推算出的底图 ROI,会再向外扩展该像素数(底图像素尺度)。 - **掩膜膨胀像素(mask_pad_px)**:仅用于匹配阶段,对源有效掩膜重投影到参考 ROI 后进行膨胀,扩大可匹配区域。 ### 5.6 质量控制(建议从默认值起调) - **最少内点数(min_inliers)**:过滤后 RANSAC 内点数低于该值直接判失败。 - **最少内点比例(min_inlier_ratio)**:\(\text{inliers} / \text{matches}\) 低于阈值判失败。 - **掩膜羽化宽度(feather_px)**:在掩膜边界做平滑过渡,减少硬边界假匹配。 - **边缘带剔除宽度(edge_band_px)**:剔除距离掩膜边界过近的匹配点(小图尺度会按缩放比例换算)。 - **纹理过滤分位阈值(min_grad_quantile)**:在匹配尺寸上计算梯度幅值分位数,低纹理区域的点会被剔除。值越大,保留的区域越“高纹理”。 --- ## 6. 内部处理流程(高层) 单个 `.bip` 的核心流程(简化版): - 读取源图与源有效掩膜(`read_masks`),在源 CRS 下取有效像素包围盒 - 包围盒 bounds 投影到参考 CRS,在参考底图上构建 ROI window,并额外 `roi_pad_px` - 读取源图全图、参考底图 ROI - 将源有效掩膜重投影到参考 ROI,并按 `mask_pad_px` 膨胀 - 对源/参考做掩膜羽化(`feather_px`)后进入匹配 - 下采样到 `match_max_side`,运行 matcher 得到匹配点/内点 - 用“边缘带剔除 + 纹理过滤”对匹配点/内点二次过滤,得到最终内点与质量指标 - 在你选定的多个变换模型中估计并评估,选 p95 误差最小者 - 根据模型类型执行重采样并写出 ENVI BIP - 写统计 CSV,保存可视化图片 --- ## 7. 依赖与可选依赖(缺失时的行为) ### 7.1 必需依赖(脚本直接 import) - `numpy` - `opencv-python`(`cv2`) - `rasterio` - `affine` - `tkinter`(Windows 自带 Python 通常包含) - `vismatch`(脚本依赖它来创建 matcher,并用 `vismatch.viz` 保存可视化图) ### 7.2 可选依赖(缺失会降级/跳过) - **`tif_caijain.py`**:用于“底图掩膜”功能;缺失则 GUI 勾选会报错。 - **`scikit-image`**:用于 `piecewise_affine` / `polynomial` 等变换;缺失会跳过这些方法或走回退逻辑。 - **`matplotlib` + `scipy`(ConvexHull)**:用于点集凸包的“内点判定”,缺失时会退化为矩形内判断(更可能外推导致异常区域)。 - **`SimpleITK` / `pirt` / `scipy.interpolate.Rbf`**:用于 TPS 等更复杂的非线性变换与回退路径;缺失时可能回退到更简单的仿射。 --- ## 8. 常见问题排查 - **报错:参考文件缺少 CRS 信息** - 参考 GeoTIFF 必须有 CRS。用 GIS 软件或 `gdalinfo` 检查并修复投影信息。 - **源 `.bip` 缺少 CRS** - 脚本会“尝试用参考 CRS”,但这通常不可靠;建议为源数据补齐正确 CRS。 - **内点很少 / 内点比例很低** - 优先检查: - 参考底图与航带是否确实有重叠区域 - ROI padding 是否过小(`roi_pad_px`) - 边缘带剔除是否过强(`edge_band_px`) - 纹理过滤是否过强(`min_grad_quantile`) - 其次尝试更鲁棒的 matcher(或改用 GPU)。 - **输出范围不对 / 被裁得太小** - 输出范围由匹配点映射到参考像素后的外接矩形决定;匹配点集中在局部会导致 bbox 偏小。 - 可尝试增大 `roi_pad_px`、降低过滤强度、或换更稳定的 matcher。 - **非线性方法(piecewise/polynomial/tps)经常失败** - 先确保 `scikit-image`、`scipy` 等可用。 - 非线性方法更依赖匹配点覆盖范围与质量;当点分布很局部时更容易外推/数值不稳。 - 生产环境通常建议把 `affine` 作为兜底并放在较高优先级。 --- ## 9. 推荐使用习惯(实操) - **先用少量样本跑通**:把 `BIP_DIR` 里先放 1–3 条航带验证匹配与输出,再批量跑全量。 - **先看 `visualizations/`**:匹配线与关键点能最快判断“是没重叠、还是过滤过强、还是 matcher 不适配”。 - **保留 `stats/`**:后续筛选失败样本、做参数回归/对比很有用。 flowchart TD A[开始处理单个BIP文件] --> B[读取源文件和参考文件] B --> C{检查CRS坐标系统} C -->|源文件无CRS| D[使用参考文件CRS] C -->|源文件有CRS| E[使用源文件CRS] D --> F[计算有效区域ROI] E --> F F --> F1[基于有效掩膜计算包围盒] F1 --> F2[将包围盒转换到参考坐标系] F2 --> F3[扩展窗口ROI_PAD_PX] F3 --> G[读取图像数据] G --> H[将源图掩膜重投影到参考空间] H --> H1[可选: 膨胀掩膜MASK_PAD_PX] H1 --> I[图像预处理] I --> I1[转3通道_float01格式] I1 --> I2[百分位数拉伸归一化] I2 --> J[生成软掩膜] J --> J1[距离变换生成羽化边缘] J1 --> J2[应用掩膜到图像] J2 --> K[降采样用于匹配] K --> K1[等比缩放到MATCH_MAX_SIDE] K1 --> L[特征匹配] L --> L1[调用Matcher获取匹配点] L1 --> M[匹配点过滤] M --> M1[边缘带剔除 EDGE_BAND_PX] M --> M2[纹理过滤 MIN_GRAD_QUANTILE] M1 --> M3[组合掩膜过滤] M2 --> M3 M3 --> N{质量控制检查} N -->|内点数|内点比例|通过检查| P[计算全分辨率坐标] P --> Q[估计多种变换模型] Q --> Q1[similarity] Q --> Q2[affine] Q --> Q3[homography] Q --> Q4[piecewise_affine] Q --> Q5[polynomial] Q1 --> R[评估变换质量] Q2 --> R Q3 --> R Q4 --> R Q5 --> R R --> S[选择最优变换模型] S --> T{变换类型判断} T -->|Affine| U[仿射变换处理] T -->|Homography| V[单应变换处理] T -->|Piecewise/Polynomial| W[非线性变换处理] U --> X[计算最小外接矩形] V --> X W --> X X --> Y[创建输出文件] Y --> Z[逐波段几何重采样] Z --> AA[保存配准结果] AA --> AB[记录统计信息] AB --> AC[结束] O --> AD[记录失败信息] AD --> AC T -->|所有变换失败| AE[仿射回退处理] AE -->|回退成功| AA AE -->|回退失败| O