fix: BIP 格式兼容 — 鲁棒 HDR 查找 + find_band_number GDAL 回退

问题: 用户导入 3ref.bip 文件,step2 报 FileNotFoundError: 3ref.hdr 不存在。

根本原因: get_hdr_file_path() 只用 os.path.splitext()[0]+.hdr,
对于 3ref.bip 只查找 3ref.hdr,不兼容 3ref.bip.hdr 等其他命名规范。

修复内容:

**util.py (核心):**
- get_hdr_file_path(): 改为多候选路径查找(按优先级):
  3ref.hdr → 3ref.bip.hdr → 3ref.HDR → 3ref.bip.HDR
- find_band_number(): 三级回退 —
  1) ENVI .hdr 文件 → spectral 解析
  2) GDAL 元数据域 (ENVI/wavelength, WAVELENGTH_1..N)
  3) 线性估算 (假设 400-1000nm 或 400-2500nm)
- 新增 _read_wavelengths_from_gdal() 辅助函数

**同模式修复 (4 处):**
- get_spectral.py: get_hdr_file_path() 多候选
- get_spectral-test.py: 同上
- waterindex_inversion/__init__.py: 两处 hdr 构造均改为多候选
- sampling.py: 波长读取的 hdr 查找改为多候选
This commit is contained in:
duxin
2026-07-07 10:32:02 +08:00
parent 1f6c81158b
commit 2b5c77131e
5 changed files with 204 additions and 40 deletions

View File

@ -205,13 +205,18 @@ class WaterIndexProcessor:
except Exception:
pass
# 2. HDR 补充波长信息
# 2. HDR 补充波长信息(多命名规范兼容 .bsq/.bil/.bip/.dat)
if hdr_path is None:
hdr_path = os.path.splitext(bsq_path)[0] + '.hdr'
if not os.path.isfile(hdr_path):
hdr_path_alt = os.path.splitext(bsq_path)[0] + '.HDR'
if os.path.isfile(hdr_path_alt):
hdr_path = hdr_path_alt
hdr_candidates = [
os.path.splitext(bsq_path)[0] + '.hdr', # 3ref.hdr
bsq_path + '.hdr', # 3ref.bip.hdr
os.path.splitext(bsq_path)[0] + '.HDR', # 3ref.HDR
bsq_path + '.HDR', # 3ref.bip.HDR
]
for candidate in hdr_candidates:
if os.path.isfile(candidate):
hdr_path = candidate
break
if os.path.isfile(hdr_path):
wl = self._parse_wavelengths_from_hdr(hdr_path)
@ -365,13 +370,18 @@ class WaterIndexProcessor:
dict
{公式名: 输出 GeoTIFF 路径}
"""
# ── 自动构造 HDR 路径 ────────────────────────────────────────────
# ── 自动构造 HDR 路径(多命名规范兼容) ────────────────────────
if hdr_path is None:
hdr_path = os.path.splitext(bsq_path)[0] + '.hdr'
if not os.path.isfile(hdr_path):
hdr_path_alt = os.path.splitext(bsq_path)[0] + '.HDR'
if os.path.isfile(hdr_path_alt):
hdr_path = hdr_path_alt
hdr_candidates = [
os.path.splitext(bsq_path)[0] + '.hdr',
bsq_path + '.hdr',
os.path.splitext(bsq_path)[0] + '.HDR',
bsq_path + '.HDR',
]
for candidate in hdr_candidates:
if os.path.isfile(candidate):
hdr_path = candidate
break
# ── 自动构造输出目录 ────────────────────────────────────────────
if output_dir is None:
@ -605,11 +615,17 @@ class WaterIndexProcessor:
notify("开始水色指数反演", 0)
bsq_path = deglint_img_path
hdr_path = os.path.splitext(bsq_path)[0] + '.hdr'
if not os.path.isfile(hdr_path):
hdr_path_alt = os.path.splitext(bsq_path)[0] + '.HDR'
if os.path.isfile(hdr_path_alt):
hdr_path = hdr_path_alt
hdr_candidates = [
os.path.splitext(bsq_path)[0] + '.hdr',
bsq_path + '.hdr',
os.path.splitext(bsq_path)[0] + '.HDR',
bsq_path + '.HDR',
]
hdr_path = None
for candidate in hdr_candidates:
if os.path.isfile(candidate):
hdr_path = candidate
break
output_dir = os.path.join(work_dir, "10_WaterIndex_Images")

View File

@ -330,15 +330,18 @@ def load_mask_file(mask_path):
def get_hdr_file_path(file_path):
"""
获取HDR文件路径
Args:
file_path: 影像文件路径
Returns:
HDR文件路径
获取 ENVI 头文件路径(鲁棒版:多命名规范兼容)
"""
return os.path.splitext(file_path)[0] + ".hdr"
candidates = [
os.path.splitext(file_path)[0] + ".hdr",
file_path + ".hdr",
os.path.splitext(file_path)[0] + ".HDR",
file_path + ".HDR",
]
for path in candidates:
if os.path.isfile(path):
return path
return candidates[0]
def calculate_utm_zone(longitude):

View File

@ -212,15 +212,26 @@ def load_mask_file(mask_path):
def get_hdr_file_path(file_path):
"""
获取HDR文件路径
获取 ENVI 头文件路径(鲁棒版:多命名规范兼容)
支持 .bsq / .bil / .bip / .dat 等格式的多种 .hdr 命名规范。
Args:
file_path: 影像文件路径
Returns:
HDR文件路径
存在的 .hdr 文件路径;若都不存在,返回标准命名路径
"""
return os.path.splitext(file_path)[0] + ".hdr"
candidates = [
os.path.splitext(file_path)[0] + ".hdr", # 3ref.hdr
file_path + ".hdr", # 3ref.bip.hdr
os.path.splitext(file_path)[0] + ".HDR", # 3ref.HDR
file_path + ".HDR", # 3ref.bip.HDR
]
for path in candidates:
if os.path.isfile(path):
return path
return candidates[0]
def load_wavelength_columns(imgpath, num_bands):