使用DenseNet121预训练权重测试时报UnidentifiedImageError如何解决?
问题原因
核心报错UnidentifiedImageError是Keras内置图像加载工具依赖的PIL/Pillow库无法识别读取.tif格式图像导致,常见触发原因:
- 安装的Pillow库未编译libtiff依赖,原生不支持tif格式读取
- 数据集中存在损坏的tif文件,或是多页tif格式,不符合PIL默认读取逻辑
- Keras的
ImageDataGenerator默认仅适配jpg、png等常见图像格式,对tif格式兼容性差
定位方法
- 单文件验证:运行以下代码测试单张tif能否被PIL正常读取:
from PIL import Image # 替换为数据集内实际tif文件路径 test_path = "./data/Messidor_Classes/0/img_1.tif" img = Image.open(test_path) print(img.size)
如果运行报错,即可确认是Pillow兼容问题或文件本身损坏。
2. 全数据集扫描:遍历所有文件定位损坏/不兼容的tif:
import os from PIL import Image test_dir = './data/Messidor_Classes/' bad_files = [] for root, _, files in os.walk(test_dir): for f in files: if f.endswith('.tif'): fp = os.path.join(root, f) try: img = Image.open(fp) img.verify() except Exception: bad_files.append(fp) print(f"无法读取的文件数量:{len(bad_files)},路径列表:{bad_files}")
修复方案
方案1:升级Pillow补全tif依赖
先卸载现有Pillow,重新安装带libtiff支持的版本:
# pip环境 pip uninstall -y pillow pip install --upgrade pillow # conda环境 conda install libtiff pillow
安装完成后重新运行定位代码验证,大部分兼容问题可直接解决。
方案2:自定义tif数据加载逻辑
如果升级Pillow后仍有问题,可使用专门的tif读取库tifffile替换默认加载逻辑:
- 先安装依赖:
pip install tifffile
- 自定义数据生成器替换原有
ImageDataGenerator:
import tifffile as tiff from tensorflow.keras.utils import Sequence import numpy as np class TifDataGenerator(Sequence): def __init__(self, file_paths, batch_size, img_size): self.file_paths = file_paths self.batch_size = batch_size self.img_size = img_size def __len__(self): return int(np.ceil(len(self.file_paths) / self.batch_size)) def __getitem__(self, idx): batch_files = self.file_paths[idx*self.batch_size : (idx+1)*self.batch_size] batch_imgs = [] for fp in batch_files: img = tiff.imread(fp) # 此处可添加resize、归一化等预处理逻辑 batch_imgs.append(img) return np.array(batch_imgs)
修改原有测试代码的循环逻辑,遍历每个类别读取所有tif路径传入自定义生成器即可。
方案3:批量转换图像格式
如果不想修改加载逻辑,可提前将所有tif转为png格式:
from PIL import Image import os import tifffile as tiff src_root = './data/Messidor_Classes/' dst_root = './data/Messidor_Classes_png/' os.makedirs(dst_root, exist_ok=True) for cls_id in range(4): src_cls_dir = os.path.join(src_root, str(cls_id)) dst_cls_dir = os.path.join(dst_root, str(cls_id)) os.makedirs(dst_cls_dir, exist_ok=True) for f in os.listdir(src_cls_dir): if f.endswith('.tif'): src_fp = os.path.join(src_cls_dir, f) dst_fp = os.path.join(dst_cls_dir, f.replace('.tif', '.png')) img = tiff.imread(src_fp) Image.fromarray(img).save(dst_fp)
转换完成后将测试代码中的test_dir替换为新的png数据集路径即可正常使用原有ImageDataGenerator逻辑。
方案4:清理损坏文件
如果定位步骤发现仅个别文件损坏,直接删除对应bad_files列表中的文件即可。
内容的提问来源于stack exchange,提问作者arvind okram
相关产品推荐
相关产品推荐

