Step6 波长读取:spectral 解析失败时增加 .hdr 文本暴力解析兜底,消灭 band_1 fallback
This commit is contained in:
@ -223,6 +223,73 @@ def get_hdr_file_path(file_path):
|
|||||||
return os.path.splitext(file_path)[0] + ".hdr"
|
return os.path.splitext(file_path)[0] + ".hdr"
|
||||||
|
|
||||||
|
|
||||||
|
def load_wavelength_columns(imgpath, num_bands):
|
||||||
|
"""
|
||||||
|
加载 wavelength 列名(鲁棒版:三级回退)
|
||||||
|
|
||||||
|
优先级:
|
||||||
|
1) spectral.envi.read_envi_header(标准库解析,依赖 ENVI 头完整性)
|
||||||
|
2) 纯文本暴力解析 .hdr(兜底,绕过 spectral 对 band names / 波段数一致性的校验)
|
||||||
|
—— 解决 .hdr 中 band names 数量与 bands 不符导致的标准库解析失败问题
|
||||||
|
3) 最后回退:band_1, band_2, ..., band_N
|
||||||
|
|
||||||
|
Args:
|
||||||
|
imgpath: 影像文件路径(.bsq / .bil / .bip 等)
|
||||||
|
num_bands: 影像实际波段数(用于回退列名长度 & 不一致警告)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
spectral_columns: 长度为 num_bands 的字符串列表(与原代码列名格式一致:纯数字字符串)
|
||||||
|
"""
|
||||||
|
hdr_path = get_hdr_file_path(imgpath)
|
||||||
|
|
||||||
|
# 1) 标准库解析
|
||||||
|
try:
|
||||||
|
in_hdr_dict = spectral.envi.read_envi_header(hdr_path)
|
||||||
|
wavelengths = np.array(in_hdr_dict['wavelength']).astype('float64')
|
||||||
|
spectral_columns = [str(wl) for wl in wavelengths]
|
||||||
|
print(f"[wavelength] 标准库解析成功,从 {hdr_path} 提取 {len(spectral_columns)} 个波长")
|
||||||
|
if len(spectral_columns) != num_bands:
|
||||||
|
print(f"[wavelength] 警告: 解析波长数 ({len(spectral_columns)}) 与影像波段数 ({num_bands}) 不一致,将以 num_bands 为准截断/补齐")
|
||||||
|
if len(spectral_columns) > num_bands:
|
||||||
|
spectral_columns = spectral_columns[:num_bands]
|
||||||
|
elif len(spectral_columns) < num_bands:
|
||||||
|
spectral_columns = spectral_columns + [f"band_{j+1}" for j in range(len(spectral_columns), num_bands)]
|
||||||
|
return spectral_columns
|
||||||
|
except Exception as e_std:
|
||||||
|
print(f"[wavelength] 标准库解析失败: {str(e_std)},将尝试文本兜底解析")
|
||||||
|
|
||||||
|
# 2) 兜底:纯文本暴力解析
|
||||||
|
try:
|
||||||
|
if not os.path.isfile(hdr_path):
|
||||||
|
print(f"[wavelength] 文本兜底失败: {hdr_path} 不存在")
|
||||||
|
else:
|
||||||
|
with open(hdr_path, 'r', encoding='utf-8', errors='ignore') as f:
|
||||||
|
hdr_text = f.read()
|
||||||
|
pattern = r'wavelength\s*=\s*\{([^}]+)\}'
|
||||||
|
m = re.search(pattern, hdr_text, flags=re.IGNORECASE | re.DOTALL)
|
||||||
|
if m:
|
||||||
|
inner = m.group(1)
|
||||||
|
tokens = [t.strip() for t in inner.split(',') if t.strip()]
|
||||||
|
if tokens:
|
||||||
|
if len(tokens) != num_bands:
|
||||||
|
print(f"[wavelength] 文本解析波长数 ({len(tokens)}) 与影像波段数 ({num_bands}) 不一致,将以 num_bands 为准截断/补齐")
|
||||||
|
if len(tokens) > num_bands:
|
||||||
|
tokens = tokens[:num_bands]
|
||||||
|
elif len(tokens) < num_bands:
|
||||||
|
tokens = tokens + [f"band_{j+1}" for j in range(len(tokens), num_bands)]
|
||||||
|
print(f"[wavelength] 文本暴力解析成功,从 {hdr_path} 提取 {len(tokens)} 个真实波长")
|
||||||
|
return tokens
|
||||||
|
print(f"[wavelength] 文本兜底: 已匹配到 wavelength = {{ ... }},但内部为空")
|
||||||
|
else:
|
||||||
|
print(f"[wavelength] 文本兜底: 未在 {hdr_path} 中匹配到 wavelength = {{ ... }} 字段")
|
||||||
|
except Exception as e_txt:
|
||||||
|
print(f"[wavelength] 文本兜底解析异常: {str(e_txt)}")
|
||||||
|
|
||||||
|
# 3) 全部失败,最后回退
|
||||||
|
print(f"[wavelength] 所有解析路径均失败,回退到 band_1..band_{num_bands}")
|
||||||
|
return ["band_" + str(j + 1) for j in range(num_bands)]
|
||||||
|
|
||||||
|
|
||||||
def calculate_utm_zone(longitude):
|
def calculate_utm_zone(longitude):
|
||||||
"""
|
"""
|
||||||
根据经度计算UTM分区号
|
根据经度计算UTM分区号
|
||||||
@ -759,17 +826,8 @@ def get_spectral_in_coor(imgpath, coorpath, outpath, radius=0, flare_path=None,
|
|||||||
else:
|
else:
|
||||||
original_columns = []
|
original_columns = []
|
||||||
|
|
||||||
# 读取波长信息,用作光谱列名
|
# 读取波长信息,用作光谱列名(三级回退:spectral 解析 → 文本暴力解析 → band_N 兜底)
|
||||||
wavelengths = None
|
spectral_columns = load_wavelength_columns(imgpath, num_bands)
|
||||||
try:
|
|
||||||
in_hdr_dict = spectral.envi.read_envi_header(get_hdr_file_path(imgpath))
|
|
||||||
wavelengths = np.array(in_hdr_dict['wavelength']).astype('float64')
|
|
||||||
# 将波长值转换为字符串作为列名
|
|
||||||
spectral_columns = [str(wl) for wl in wavelengths]
|
|
||||||
print(f"成功读取波长信息,共 {len(spectral_columns)} 个波段")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"警告: 无法读取波长信息 ({str(e)}),使用默认列名 band_1, band_2, ...")
|
|
||||||
spectral_columns = ["band_" + str(j + 1) for j in range(num_bands)]
|
|
||||||
|
|
||||||
# 构建输出列名(不包含前两列坐标列和UTM列)
|
# 构建输出列名(不包含前两列坐标列和UTM列)
|
||||||
all_columns = original_columns + spectral_columns
|
all_columns = original_columns + spectral_columns
|
||||||
|
|||||||
Reference in New Issue
Block a user