如何修复遍历图片目录时出现的NotADirectoryError: [Errno 20]错误
问题描述
我想展示指定路径中的.png图片,运行了以下Python代码但未能成功:
path = ('/tmp/BDC-main/images') classes = os.listdir(path+'/train') plt.figure(figsize=(30 , 30)) for x in range(10): i = random.randint(0,3) # 获取分类 images = os.listdir(path+'/train'+'/'+classes[i]) j = random.randint(0,600) # 获取图片 image = cv2.imread(path+'/train'+'/'+classes[i]+'/'+images[j]) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) ax = plt.subplot(5, 5, x + 1) plt.imshow(image) plt.title(classes[i]) plt.axis("off") plt.show()
运行后触发如下错误:
--------------------------------------------------------------------------- NotADirectoryError Traceback (most recent call last) <ipython-input-29-02bb2a1a65a2> in <cell line: 4>() 4 for x in range(10): 5 i = random.randint(0,3) # getting the class ----> 6 images = os.listdir(path+'/train'+'/'+classes[i]) 7 j = random.randint(0,600) # getting the image 8 image = cv2.imread(path+'/train'+'/'+classes[i]+'/'+images[j]) NotADirectoryError: [Errno 20] Not a directory: '/tmp/BDC-main/images/train/DataTrain384.png'
出错原因
os.listdir(path+'/train')会列出train目录下的所有内容,包括文件和子目录。你代码默认classes里的每一项都是分类子目录,但实际上train目录里混有.png文件(比如报错里的DataTrain384.png),当你尝试用os.listdir读取这个文件的内容时,就会触发错误——因为文件不是目录,无法被listdir读取。
解决方法
方法1:过滤出train下的子目录作为分类
修改classes的获取逻辑,只保留train目录下的子目录,同时优化路径拼接和索引范围,避免其他潜在错误:
import os import random import cv2 import matplotlib.pyplot as plt path = '/tmp/BDC-main/images/train' # 过滤出train目录下的所有子目录 classes = [item for item in os.listdir(path) if os.path.isdir(os.path.join(path, item))] plt.figure(figsize=(30 , 30)) for x in range(10): if not classes: break # 没有分类目录时直接终止循环 # 随机选取分类,用实际分类数量确定索引范围 i = random.randint(0, len(classes)-1) class_dir = os.path.join(path, classes[i]) # 只保留当前分类下的png图片(忽略大小写) images = [img for img in os.listdir(class_dir) if img.lower().endswith('.png')] if not images: continue # 当前分类下无图片则跳过 # 随机选取图片,用实际图片数量确定索引范围 j = random.randint(0, len(images)-1) image_path = os.path.join(class_dir, images[j]) image = cv2.imread(image_path) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) ax = plt.subplot(5, 5, x + 1) plt.imshow(image) plt.title(classes[i]) plt.axis("off") plt.show()
方法2:整理train目录结构
如果你的预期是train目录下只有分类子目录,没有零散图片,直接把train里的.png文件移到对应的分类子目录中即可。之后原代码可以正常运行,但建议把random.randint(0,3)改成random.randint(0, len(classes)-1),避免因分类数量不足3个导致的索引越界错误。
额外优化提示
- 用
os.path.join()拼接路径,避免手动拼接斜杠可能引发的路径格式错误 - 不要固定随机索引的范围,用实际的目录/文件数量动态计算,防止索引越界
- 过滤
.png后缀的文件(忽略大小写),避免读取非图片文件
内容的提问来源于stack exchange,提问作者Rayhan Nuansa
相关产品推荐
相关产品推荐

