调用ImageOps.fit报TypeError: 'int' object is not subscriptable错误
PIL.ImageOps.fit调用报错:'int' object is not subscriptable
问题场景
基于Teachable Machines官方示例修改代码,使用Keras、PIL.ImageGrab、cv2、tensorflow开发屏幕截取+模型推理的自动驾驶视觉程序,循环截取屏幕指定区域、转换色彩空间后调用ImageOps.fit缩放图像时触发报错。
报错栈信息
Traceback (most recent call last): File "C:\Users\Captey\Downloads\Stuff\Self_driving_cv2\Keras-Neural_net.py", line 23, in <module> image = ImageOps.fit(image, size, Image.ANTIALIAS) File "Z:\Users\Captey\anaconda3\lib\site-packages\PIL\ImageOps.py", line 459, in fit bleed_pixels = (bleed * image.size[0], bleed * image.size[1]) TypeError: 'int' object is not subscriptable
触发问题的原代码
# -*- coding: utf-8 -*- """ Created on Sun Jul 10 23:31:44 2022 @author: Fahim Ferdous Github: FahimFerdou1 Youtube: The_official_pyrite """ from keras.models import load_model from PIL import ImageGrab, ImageOps,Image import numpy as np import cv2 import tensorflow as tf model = load_model('self_driving_model.h5') data = np.ndarray(shape=(1, 224, 224, 3), dtype=np.float32) while True: img = ImageGrab.grab(bbox=(285, 397,689, 812)) img = np.array(img) image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) size = (224, 224) image = ImageOps.fit(image, size, Image.ANTIALIAS) 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) print(prediction) if cv2.waitKey(1) == 27: break cv2.imshow('data',image)
报错原因
ImageOps.fit是PIL库的内置方法,仅接收PIL Image类型的输入参数,不支持直接传入numpy数组。
代码中执行cv2.cvtColor后,image变量已经转换为numpy数组类型:
- PIL Image对象的
.size属性是存储(图像宽度, 图像高度)的二元元组,支持下标索引取值 - numpy数组的
.size属性是返回数组元素总个数的整数值,无法通过下标访问,因此触发类型错误。
修复方法
在两个位置调整代码即可:
- 调用
ImageOps.fit前,将cv2处理后的numpy数组转回PIL Image对象 - 调用
cv2.imshow前,将缩放后的PIL Image转回numpy数组,适配OpenCV的输入要求
修改后核心循环代码如下:
while True: img = ImageGrab.grab(bbox=(285, 397,689, 812)) img = np.array(img) image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 新增:numpy数组转PIL Image image = Image.fromarray(image) size = (224, 224) image = ImageOps.fit(image, size, Image.ANTIALIAS) 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) print(prediction) if cv2.waitKey(1) == 27: break # 修改:传入numpy数组给cv2.imshow cv2.imshow('data', image_array)
补充说明:高版本Pillow(9.1.0及以上)中
Image.ANTIALIAS已经被标记为弃用,运行时如果出现相关告警,可以替换为Image.Resampling.LANCZOS,缩放效果完全一致。
内容的提问来源于stack exchange,提问作者Capt.Pyrite
相关产品推荐
相关产品推荐

