如何通过sklearn.datasets.fetch_lfw_people生成ravelled人脸图像
LFW数据集ravelled格式生成与路径遍历优化方案
一、ravelled格式人脸图像生成方法
ravelled格式本质就是将单张二维(高×宽)的人脸像素数组按行优先顺序展平为一维向量,和sklearn官方输出逻辑对齐的生成步骤如下:
- 读取单张人脸图像,统一转灰度图后缩放到指定尺寸(默认尺寸为62×47像素,对应展平后长度2914)
- 将图像转换为
float32类型的numpy数组,单张灰度图维度为(h, w) - 调用numpy的
ravel()方法将二维数组展平为一维向量 - 将所有样本的一维向量堆叠,最终得到形状为
(n_samples, h*w)的ravelled格式数据集
最简实现示例:
import numpy as np from PIL import Image # 单张图像生成ravelled向量 img = Image.open("人脸图像路径").convert("L") img_resized = img.resize((47, 62)) # 宽在前、高在后,和官方默认尺寸对应 img_arr = np.array(img_resized, dtype=np.float32) ravelled_vec = img_arr.ravel() # 输出长度为62*47=2914的一维向量
二、原源码paths生成逻辑说明
你贴出的源码是原生LFW数据集的遍历逻辑,LFW的目录结构为「根目录下每个文件夹对应一个人,文件夹名为人名,内部存放该人的所有人脸图像」,这段代码的执行流程为:
- 遍历LFW根目录下的所有内容,筛选出人名对应的文件夹,跳过非文件夹类型的文件
- 遍历每个人名文件夹下的所有图像文件,手动拼接得到每个图像的完整路径,存入
paths列表 - 过滤掉人脸数量小于
min_faces_per_person阈值的人物,将符合条件的人名和对应图像路径分别存入结果列表
这段逻辑功能正确,但写法偏传统,嵌套层级多,还有优化空间。
三、更优实现方案
推荐用Python内置的pathlib模块重写,代码更简洁,跨平台兼容性更好,同时可以把路径遍历和ravelled格式生成逻辑整合,减少不必要的遍历开销:
from pathlib import Path import numpy as np from PIL import Image def load_lfw_custom(data_root: str, min_faces_per_person: int = 1, target_size: tuple = (62, 47)): h, w = target_size data_root = Path(data_root) person_names = [] file_paths = [] raveled_faces = [] # 遍历所有人名文件夹 for person_dir in sorted(data_root.iterdir()): if not person_dir.is_dir(): continue # 直接获取当前文件夹下所有图像路径 img_paths = sorted(person_dir.glob("*")) if len(img_paths) < min_faces_per_person: continue # 存储人名和路径 person_name = person_dir.name.replace("_", " ") person_names.extend([person_name] * len(img_paths)) file_paths.extend([str(p) for p in img_paths]) # 同步加载图像生成ravelled格式数据 for p in img_paths: img = Image.open(p).convert("L").resize((w, h)) raveled_faces.append(np.array(img, dtype=np.float32).ravel()) # 堆叠为numpy矩阵 faces_data = np.vstack(raveled_faces) return faces_data, person_names, file_paths
优化点:
- 不需要手动处理路径拼接,
pathlib自动适配不同操作系统的路径分隔符 - 内置
glob方法直接筛选文件,无需额外判断文件类型,代码层级更少可读性更高 - 路径遍历和图像加载、格式转换同步完成,减少多轮遍历的性能开销
内容的提问来源于stack exchange,提问作者d2d
相关产品推荐
相关产品推荐

