如何用Python从BSQ格式uint16高光谱二进制数据生成图像?
解决BSQ格式高光谱数据转图像的问题
问题根源分析
你的代码生成乱序图像,大概率是两个核心原因:
- 字节序不匹配:多数高光谱相机的原始uint16数据采用大端字节序(Big-Endian),而NumPy默认按小端(Little-Endian)读取,导致数值解析完全错误。
- 存储顺序错误:BSQ格式是按波段连续存储,但部分相机单波段像素采用**列优先(Fortran顺序)**存储,而非默认的行优先(C顺序)。
修正后的代码
from PIL import Image import numpy as np # 1. 指定大端字节序读取数据(关键修正) with open('Sequence 1_000021.dat', 'rb') as f: # 使用'>u2'表示大端字节序的uint16,若相机是小端则替换为'<u2' myarray = np.fromfile(f, dtype='>u2') # 2. 验证数组长度是否符合预期:24*1024*1024 = 24576512 print(f"数组长度:{len(myarray)},预期长度:{24*1024*1024}") # 3. 按BSQ格式重构高光谱立方体 # 先尝试列优先('F'),若结果仍乱序则换为行优先('C') con_array = np.reshape(myarray, (24, 1024, 1024), order='F') # 4. 提取第2个波段(索引从0开始)并保存 single_band = con_array[1, :, :] # 可选:若查看器不支持16位TIFF,启用下方代码将数据缩放到0-255转8位 # single_band_8bit = ((single_band - single_band.min()) / (single_band.max() - single_band.min()) * 255).astype(np.uint8) # naPIL = Image.fromarray(single_band_8bit) # 直接保存16位TIFF naPIL = Image.fromarray(single_band) naPIL.save('naPIL.tiff')
调试提示
- 若换
order='F'后仍乱序,改回order='C'尝试,不同厂商的BSQ实现可能存在差异。 - 用
print(con_array[1, :5, :5])打印局部像素值,对比相机提供的参考数据(若有),确认数值解析是否正确。 - 若16位TIFF无法正常显示,启用代码中的8位缩放逻辑,将数据映射到常规图像的亮度范围。
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

