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

如何修复遍历图片目录时出现的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 15:15:42