Google Colab添加Image.open().convert('RGB')报PngImageFile无read错误
报错原因
触发'PngImageFile' object has no attribute 'read'错误的核心原因是Image.open()调用逻辑错误:
传入分类函数的img参数本身已经是PIL加载完成的PngImageFile实例,并非本地文件路径或支持read()方法的文件流。此时对该实例执行Image.open(img).convert('RGB')时,Image.open()会尝试调用传入对象的read()方法读取文件内容,但PngImageFile实例没有对应可调用的read属性,直接抛出属性错误。
原有代码还存在一个隐藏问题:没有强制统一图像为3通道RGB格式,遇到带透明通道的4通道PNG、单通道灰度图时,转换得到的numpy数组维度和模型输入要求不匹配,会触发shape相关报错。
修复方案
- 按输入类型分支处理图像加载:仅当
img为文件路径/文件流时,才调用Image.open()加载;如果传入的是已打开的PIL图像对象,直接调用.convert('RGB')统一通道即可,禁止重复嵌套Image.open() - 所有输入图像强制转为3通道RGB格式,对齐模型输入要求
- 兼容新旧版本Pillow的缩放重采样参数:
Image.ANTIALIAS在Pillow 9.1.0及以上版本已被弃用,替换为Image.Resampling.LANCZOS,避免Colab预装新版Pillow时出现属性错误 - 模型推理时添加
verbose=0参数,关闭每次推理自动打印的进度条冗余日志
修正后完整代码
import keras from PIL import Image, ImageOps import numpy as np def teachable_machine_classification(img, weights_file): # 加载训练好的模型 model = keras.models.load_model(weights_file) # 初始化符合模型输入维度的数组 data = np.ndarray(shape=(1, 224, 224, 3), dtype=np.float32) # 兼容两种输入格式:路径/文件流、已打开的PIL图像对象 if isinstance(img, str): image = Image.open(img).convert('RGB') else: image = img.convert('RGB') # 适配新旧版本Pillow的重采样方法 resample = Image.Resampling.LANCZOS if hasattr(Image, 'Resampling') else Image.ANTIALIAS size = (224, 224) image = ImageOps.fit(image, size, resample) # 数组转换与归一化,对齐Teachable Machine默认预处理逻辑 image_array = np.asarray(image) normalized_image_array = (image_array.astype(np.float32) / 127.0) - 1 # 执行推理 data[0] = normalized_image_array prediction = model.predict(data, verbose=0) return np.argmax(prediction)
内容的提问来源于stack exchange,提问作者raiyan rohit
相关产品推荐
相关产品推荐

