Python遍历多文件夹读取图像批量计算NSS报错排查
问题背景
共有18个文件夹,每个文件夹内含10张图像,其中1张为ground truth真值图(jpg格式),其余为预测结果图(png格式)。需要编写Python程序逐个遍历文件夹,完成每个文件夹内的图像相似度(NSS指标)计算,初始编写代码如下:
for root, dirs, files in os.walk(os.getcwd()): for dirct in dirs: lis_sal_map =[] gt = '' for name in files: (base, ext) = os.path.splitext(name) # split base and extension if ext in ('.jpg'): # check the extension gt = name print("gt old is", gt) if ext in ('.png'): #full_name = os.path.join(root, name) lis_sal_map.append(name) print("list sal map", lis_sal_map) print("gt before file", gt) img_gt = Image.open(gt) numpydata_in = np.array(img_gt).astype('uint8') numpydata_out = list_sal_map[0] nss = nss(numpydata_in, numpydata_out) print("nss is", nss)
程序运行时输出与报错如下:
list sal map [] list sal map [] gt befoe file Traceback (most recent call last): fp.seek(0) AttributeError: 'str' object has no attribute 'seek' During handling of the above exception, another exception occurred: Trace back (most recent call last): File "result_auto.py", line 61, in <module> img_gt = Image.open(gt) File "anaconda3/lib/python3.8/site-packages/PIL/Image.py", line 2897, in open fp = io.BytesIO(fp.read()) AttributeError: 'str' object has no attribute 'read'
核心异常现象:
lis_sal_map列表始终为空gt变量为空值- 执行
Image.open时触发AttributeError属性错误
问题根因
代码存在5处核心错误:
- 缩进完全混乱:
for dirct in dirs:循环下的代码没有正确缩进,遍历文件的逻辑实际没有进入任何子文件夹路径,始终读取的是脚本所在根目录的文件列表,根本无法获取子文件夹内的jpg、png文件,直接导致lis_sal_map为空、gt为空字符串。 - 未拼接完整文件路径:获取到文件名后没有通过
os.path.join(root, name)拼接文件的完整路径,直接传入裸文件名会导致程序无法定位到子文件夹内的文件。 - 变量名拼写不一致:定义的预测图列表名为
lis_sal_map,后续取值时误写为list_sal_map,运行时会触发变量不存在的错误。 - 数据类型不符合要求:
numpydata_out直接赋值为文件名字符串,没有读取图片并转换为numpy数组,传入NSS计算函数时会触发类型错误。 - 逻辑层级错误:图片读取、NSS计算的代码写在了
os.walk循环外部,只会在所有遍历结束后执行一次,无法实现逐个文件夹计算指标的需求;当gt为空字符串时传入Image.open(),PIL会尝试将其作为类文件对象读取,因此触发无seek、read方法的属性报错。
修正后代码
import os import numpy as np from PIL import Image # 替换为你自己实现的NSS指标计算函数 def nss(gt_array, pred_array): # 此处填入你原有的NSS计算逻辑 pass if __name__ == "__main__": for root, dirs, files in os.walk(os.getcwd()): # 跳过脚本所在根目录,只处理存放图片的子文件夹 if root == os.getcwd(): continue sal_map_path_list = [] gt_img_path = "" for file_name in files: # 拼接文件完整路径 file_full_path = os.path.join(root, file_name) file_name_base, file_ext = os.path.splitext(file_name) file_ext = file_ext.lower() # 匹配jpg格式真值图 if file_ext in (".jpg", ".jpeg"): gt_img_path = file_full_path print(f"当前文件夹[{root}] 找到真值图: {file_name}") # 匹配png格式预测图 if file_ext == ".png": sal_map_path_list.append(file_full_path) print(f"当前文件夹[{root}] 找到预测图数量: {len(sal_map_path_list)}") # 校验文件完整性,避免空值报错 if not gt_img_path or len(sal_map_path_list) == 0: print(f"文件夹[{root}] 缺失真值图或预测图,跳过计算") continue # 读取真值图并转为numpy数组,convert参数可根据你的数据格式调整为'RGB'等 gt_img = Image.open(gt_img_path).convert("L") gt_array = np.array(gt_img).astype("uint8") # 逐个计算当前文件夹下所有预测图的NSS值 for pred_path in sal_map_path_list: pred_img = Image.open(pred_path).convert("L") pred_array = np.array(pred_img).astype("uint8") nss_value = nss(gt_array, pred_array) print(f"预测图[{os.path.basename(pred_path)}] NSS值: {nss_value}")
修正说明
- 统一调整代码缩进,确保遍历逻辑正确进入每个子文件夹
- 所有文件操作均使用拼接后的完整路径,避免文件找不到的问题
- 增加文件完整性校验,遇到文件缺失的文件夹直接跳过,避免空值报错
- 修正变量名拼写问题,统一命名规范
- 预测图读取后同样转为numpy数组再传入计算函数,避免类型错误
- 将指标计算逻辑放入遍历循环内,实现逐个文件夹、逐张预测图的自动计算
- 增加后缀名小写兼容,避免大写后缀的文件被漏识别
内容的提问来源于stack exchange,提问作者azee
相关产品推荐
相关产品推荐

