Python高效读取文件夹中所有图片的完整指南

Python读取文件夹中所有图片的完整指南

在图像处理、计算机视觉或数据预处理中,经常需要批量读取文件夹内的图片。Python提供了多种灵活的方式来实现这一需求。本文将系统介绍几种主流方法,并分析各自的适用场景。

准备工作

首先,确保已安装必要的库:pip install pillow opencv-python pathlib(部分为内置模块无需安装)。

方法一:使用os.listdir + PIL

import os
from PIL import Image

def read_images_os(folder_path):
    images = []
    for filename in os.listdir(folder_path):
        if filename.endswith(('.jpg', '.jpeg', '.png', '.bmp')):
            img_path = os.path.join(folder_path, filename)
            img = Image.open(img_path)
            images.append(img)
    return images

优点:简单直观,不依赖额外模块。 缺点:需要手动过滤文件后缀,且不递归子目录。

方法二:使用glob.glob通配符

import glob
from PIL import Image

def read_images_glob(folder_path):
    images = []
    for filepath in glob.glob(folder_path + '/*.jpg') + glob.glob(folder_path + '/*.png'):
        img = Image.open(filepath)
        images.append(img)
    return images

优点:支持一次匹配多种后缀,代码简洁。 缺点:不支持递归,需手动组合模式。

方法三:使用pathlib(推荐)

from pathlib import Path
from PIL import Image

def read_images_pathlib(folder_path):
    path = Path(folder_path)
    images = []
    for ext in ['*.jpg', '*.jpeg', '*.png', '*.bmp']:
        for filepath in path.glob(ext):
            img = Image.open(filepath)
            images.append(img)
    return images

若需要递归子文件夹,使用path.rglob(ext)代替path.glob(ext)

方法四:使用opencv高效加载

import cv2
import os

def read_images_opencv(folder_path):
    images = []
    for fname in os.listdir(folder_path):
        fpath = os.path.join(folder_path, fname)
        if cv2.haveImageReader(fpath):
            img = cv2.imread(fpath)
            if img is not None:
                images.append(img)
    return images

注意:OpenCV读取的图片为numpy数组(BGR格式),且能自动跳过非图片文件。

性能对比与最佳实践

  • 对于小型文件夹(图片数量<1000),所有方法速度相近。
  • 对于大型文件夹,推荐使用pathlib递归或glob,因为其内部使用了os.scandir,比os.listdir更高效。
  • 若需大量处理,建议使用opencv直接获取数组,避免PIL的转换开销。

完整示例:递归读取所有图片并显示尺寸

from pathlib import Path
from PIL import Image

def read_all_images_recursive(root_dir):
    images = []
    for filepath in Path(root_dir).rglob('*'):
        if filepath.suffix.lower() in ['.jpg', '.jpeg', '.png', '.bmp', '.tiff']:
            try:
                img = Image.open(filepath)
                images.append((filepath.name, img.size))
            except Exception as e:
                print(f'Error loading {filepath}: {e}')
    return images

if __name__ == '__main__':
    folder = 'path/to/your/image/folder'
    result = read_all_images_recursive(folder)
    for name, size in result:
        print(f'{name}: {size}')

总结

Python提供了从基础os.listdir到面向对象pathlib的多种图片读取方式。根据项目需求选择合适的方法:简单脚本用os.listdir;需要递归或更多功能用pathlib;追求性能用opencv。掌握这些技巧将极大提升图像批处理的效率。