12 KiB
12 KiB
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(默认)
在脚本所在目录执行:
python StripStitch.py
GUI 会打开“遥感影像批量配准工具”,在界面里选择:
- 参考底图(GeoTIFF)
- BIP 文件夹
- 输出文件夹
- matcher、设备(CUDA/CPU)
- 变换模型优先级
- 一系列阈值/过滤参数
点击“开始”后批处理运行,日志会实时显示;可点击“停止”中断。
2.2 CLI(无界面批处理)
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/<bip_stem>_registered.bip- 写入使用
rasterio.open(..., driver="ENVI", interleave="bip") - 旁边通常会伴随 ENVI 的头文件(如
.hdr等,取决于rasterio/GDAL行为)
- 写入使用
- 可视化:
OUT_DIR/visualizations/<bip_stem>_matches.png:匹配线可视化<bip_stem>_keypoints_src.png:源图关键点<bip_stem>_keypoints_ref.png:参考 ROI 关键点
- 统计:
OUT_DIR/stats/registration_stats_<YYYYMMDD_HHMMSS>.csv- 列:
timestamp, filename, num_inliers, num_matches, inlier_ratio, selected_method, median_error, p95_error, success
- 列:
- (可选)掩膜后的参考底图:
OUT_DIR/masked_refs/<ref_stem>_masked_<ts>.tif- 仅当 GUI 勾选“启用底图掩膜”且
tif_caijain.py可用时生成
- 仅当 GUI 勾选“启用底图掩膜”且
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 在速度/鲁棒性/显存占用方面差异很大。
- GUI 下拉框内内置了一长串候选(如
- 设备(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)
numpyopencv-python(cv2)rasterioaffinetkinter(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检查并修复投影信息。
- 参考 GeoTIFF 必须有 CRS。用 GIS 软件或
-
源
.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 -->|内点数<MIN_INLIERS| O[配准失败]
N -->|内点比例<MIN_RATIO| O
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