You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

糖尿病视网膜病变图像训练: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:22:51