为何gdal.open(path).ReadAsArray()与tifffile.imread()读取tif结果不同
GDAL与tifffile读取tif导致模型推理结果差异的原因排查
两种读取方式结果不一致,和像素排列顺序直接相关,核心诱因按出现概率排序如下:
- 维度顺序不匹配是最高发原因:
tifffile.imread()默认返回HWC格式数组,维度排列为(影像高度, 影像宽度, 波段数),和绝大多数遥感影像预处理、CV模型输入的默认维度逻辑对齐;而GDAL的ReadAsArray()方法默认返回CHW格式数组,维度排列为(波段数, 影像高度, 影像宽度)。如果预处理流程没有针对GDAL的输出做维度转换,直接送入后续归一化、裁剪、张量转换步骤,会直接把波段维度和空间维度混淆,彻底打乱像素值与波段的对应关系,最终输出完全不符合预期的推理结果,和你贴出的错误结果表现完全一致。 - 像素值默认处理逻辑差异:部分带LZW压缩、附带nodata值/颜色表的tif文件,GDAL读取时默认会自动做nodata值填充、颜色表映射、数值拉伸操作,而tifffile默认直接读取文件内存储的原始DN值,不做任何额外转换。如果你的预处理流程是基于原始DN值做归一化、波段计算,GDAL自动修改的像素值会直接改变输入特征的数值分布,导致推理结果偏移。
- 行扫描顺序差异:GDAL默认按照栅格地理参考的坐标原点从北向南逐行读取像素,若tifffile未识别到文件内的地理参考元数据,会按照文件内部的存储顺序逐行读取,极端情况下会出现影像上下翻转的问题,但这类问题的推理结果一般是整体颠倒,不会出现完全无分类逻辑的噪点状输出,出现概率极低。
快速修复方案
- 先验证维度问题:打印两个读取结果的shape属性,执行命令:
如果GDAL输出的第一维等于影像波段数、tifffile输出的最后一维等于影像波段数,直接对GDAL结果做维度转换即可:print("GDAL输出数组维度:", gdal_arr.shape) print("tifffile输出数组维度:", tif_arr.shape)
转换后再走完全一致的预处理流程,推理结果就会和tifffile读取的结果对齐。# 把CHW格式转为HWC格式,和tifffile输出对齐 gdal_arr = gdal_arr.transpose(1, 2, 0) - 如果维度顺序一致,就随机抽取3-5个相同坐标位置的像素点,比对两个数组同位置的波段数值是否完全相等。如果存在数值偏差,检查GDAL读取时是否误读了影像金字塔层、是否开启了自动拉伸参数,关闭所有自动处理选项读取原始像素值即可。
针对你提到的Colab环境下tifffile读取LZW压缩tif报错的问题,不需要切换GDAL,直接在Colab单元格执行
!pip install imagecodecs安装缺失依赖,就能正常调用tifffile读取文件。
GDAL读取得到的错误推理结果

tifffile读取得到的正确推理结果

内容的提问来源于stack exchange,提问作者NianTang Liu
相关产品推荐
相关产品推荐

