糖尿病视网膜病变图像训练:Keras自定义预处理函数类型错误求助
问题根源分析
你遇到的这个类型错误,核心原因是对Keras ImageDataGenerator 的 preprocessing_function 参数理解有误——这个函数接收的不是图像文件路径,而是已经被Keras加载并预处理后的numpy数组,所以你在函数里调用 cv2.imread(im, 1) 时,传入的是数组而非字符串路径,自然会触发类型错误。
修正后的预处理函数
我们需要调整函数逻辑,直接对传入的numpy数组进行处理,而不是尝试重新读取文件。另外还要注意Keras传入的图像维度(比如你指定了color_mode='grayscale',所以输入数组是(300,300,1)的形状),修正后的代码如下:
import cv2 import numpy as np def preprocess(im): # 因为color_mode='grayscale',im的形状是(300,300,1),先去掉最后一维转成(300,300) im = np.squeeze(im, axis=-1) # 自适应阈值处理(注意输入必须是单通道灰度图) block_size = 73 constant = 2 thr2 = cv2.adaptiveThreshold(im, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, block_size, constant) # 处理完后要恢复Keras需要的(300,300,1)维度 thr2 = np.expand_dims(thr2, axis=-1) return thr2
额外注意事项
- 当你用
flow_from_dataframe并指定color_mode='grayscale'时,Keras会自动把图像加载为(target_size[0], target_size[1], 1)的numpy数组,所以不需要再手动调用cv2.resize或者im.resize,这些操作flow_from_dataframe已经帮你完成了。 - 你的原始函数里的
im.resize(300, 300, 1)是错误的用法,numpy数组的resize方法并非如此调用,应该用np.expand_dims来增加通道维度。 - 自适应阈值函数
cv2.adaptiveThreshold要求输入必须是8位单通道图像,所以我们先通过np.squeeze去掉多余的通道维度,处理完再恢复。
验证修正后的流程
调整完预处理函数后,你的ImageDataGenerator和生成器代码不需要修改,直接运行model.fit(更推荐这个,fit_generator已被弃用)就可以正常工作了,既不用提前预处理保存所有图像,也能继续尝试解决欠拟合问题。
内容的提问来源于stack exchange,提问作者Victor E. Irekponor
相关产品推荐
相关产品推荐

