如何使用ImageDataGenerator对读取的图片文件进行正确排序
这个问题是因为ImageDataGenerator默认采用字符串字典序对文件名排序,不会自动解析文件名中的数字做数值排序,所以会出现img(1)排在img(2)前面、但img(10)也排在img(2)前面的情况,你可以通过以下两种方案解决:
方案1:使用flow_from_dataframe手动控制排序(无需修改源文件,最灵活)
你可以先自行读取所有文件路径,按自然数值排序后再喂给生成器,全程可控不需要修改原文件名。
完整代码示例:
import os import re import pandas as pd from tensorflow.keras.preprocessing.image import ImageDataGenerator # 自然排序辅助函数:拆分文件名中的数字和文本,按数值排序数字部分 def natural_sort_key(s): return [int(text) if text.isdigit() else text.lower() for text in re.split(r'(\d+)', s)] # 配置参数 img_folder = "替换为你的图片文件夹路径" img_size = (224, 224) # 替换为你需要的图片尺寸 batch_size = 32 # 读取所有图片文件并按自然序排序 img_list = sorted( [f for f in os.listdir(img_folder) if f.lower().endswith(('.jpg', '.jpeg', '.png'))], key=natural_sort_key ) # 构造DataFrame供flow_from_dataframe使用 img_df = pd.DataFrame({ "filename": img_list, "label": [0]*len(img_list) # 有监督学习场景替换为和排序后文件名对应的真实标签即可 }) # 初始化生成器并加载数据 datagen = ImageDataGenerator(rescale=1./255) # 替换为你需要的预处理规则 data_generator = datagen.flow_from_dataframe( dataframe=img_df, directory=img_folder, x_col="filename", y_col="label", target_size=img_size, batch_size=batch_size, class_mode="raw", # 无标签场景可改为"input",根据自身需求调整 shuffle=False # 需保持排序必须设为False,需要打乱训练时再按需开启 )
方案2:批量补零重命名文件名(一劳永逸,后续无需修改加载逻辑)
如果允许修改源文件名,可以把文件名中的数字补零到相同位数,比如img(1).jpg改为img(001).jpg、img(10).jpg改为img(010).jpg,补零后默认的字典序就和数值序完全一致,直接用原生flow_from_directory也能按预期顺序加载。
批量重命名代码示例:
import os import re img_folder = "替换为你的图片文件夹路径" digit_length = 3 # 按最大文件数调整,比如最多999张设为3,最多9999张设为4 for filename in os.listdir(img_folder): if not filename.lower().endswith(('.jpg', '.jpeg', '.png')): continue # 提取文件名中的数字 match_res = re.search(r'img\((\d+)\)', filename) if not match_res: continue origin_num = match_res.group(1) # 补零构造新文件名 new_num = origin_num.zfill(digit_length) suffix = os.path.splitext(filename)[1] new_filename = f"img({new_num}){suffix}" # 重命名 os.rename( os.path.join(img_folder, filename), os.path.join(img_folder, new_filename) )
重命名完成后直接用原生flow_from_directory加载即可,无需额外修改参数。
内容的提问来源于stack exchange,提问作者Aomsup PANLIMA
相关产品推荐
相关产品推荐

