如何将MNIST数据集的28*28像素图像转换为32*32像素?
将MNIST 28×28像素图像转换为32×32像素的方法
MNIST数据集的CSV格式中,每行除类别列外的784个像素是28×28图像的一维展开值。要转换为32×32像素,核心流程是:将一维像素重塑为28×28二维图像 → 插值缩放至32×32 → 再转回一维格式(如需保存回CSV)。以下是两种常用实现方案:
方法一:使用Pillow(PIL)库
Pillow是Python常用的图像处理库,支持多种插值方式,适合快速实现图像缩放:
import pandas as pd import numpy as np from PIL import Image # 读取MNIST CSV文件 df = pd.read_csv("your_mnist_file.csv") # 分离类别列与像素列 labels = df.iloc[:, 0] pixels = df.iloc[:, 1:] # 定义单行走像素缩放函数 def resize_single_row(pixel_row): # 将一维像素重塑为28×28的灰度图像数组 img_array = np.array(pixel_row).reshape(28, 28).astype(np.uint8) # 转为PIL图像对象 img = Image.fromarray(img_array) # 缩放至32×32,采用LANCZOS插值(高质量缩放,保留细节) img_resized = img.resize((32, 32), Image.LANCZOS) # 将缩放后的图像转回一维数组 return np.array(img_resized).flatten() # 对所有像素行应用缩放 resized_pixels = pixels.apply(resize_single_row, axis=1) # 合并类别列与新像素列,生成新的CSV resized_df = pd.concat([labels, resized_pixels], axis=1) resized_df.to_csv("mnist_32x32.csv", index=False)
方法二:使用OpenCV库
OpenCV的resize函数支持更丰富的插值选项,适合对性能或精度有更高要求的场景:
import pandas as pd import numpy as np import cv2 # 读取MNIST CSV文件 df = pd.read_csv("your_mnist_file.csv") labels = df.iloc[:, 0] pixels = df.iloc[:, 1:] def resize_single_row_cv2(pixel_row): img_array = np.array(pixel_row).reshape(28, 28).astype(np.uint8) # 缩放至32×32,采用INTER_LANCZOS4插值(与PIL的LANCZOS效果一致) img_resized = cv2.resize(img_array, (32, 32), interpolation=cv2.INTER_LANCZOS4) return img_resized.flatten() resized_pixels = pixels.apply(resize_single_row_cv2, axis=1) resized_df = pd.concat([labels, resized_pixels], axis=1) resized_df.to_csv("mnist_32x32_cv2.csv", index=False)
性能优化:批量处理
如果处理70000行数据,逐行apply效率较低,可采用批量处理方式提速:
import pandas as pd import numpy as np from PIL import Image df = pd.read_csv("your_mnist_file.csv") labels = df.iloc[:, 0] pixels = df.iloc[:, 1:] # 将所有像素转为(70000, 28, 28)的三维数组 pixels_batch = pixels.to_numpy().reshape(-1, 28, 28).astype(np.uint8) # 初始化存储缩放后图像的数组 resized_batch = np.zeros((pixels_batch.shape[0], 32, 32), dtype=np.uint8) # 批量处理每一张图像 for idx in range(pixels_batch.shape[0]): img = Image.fromarray(pixels_batch[idx]) resized_batch[idx] = np.array(img.resize((32, 32), Image.LANCZOS)) # 将缩放后的三维数组展平为二维,转为DataFrame resized_pixels = pd.DataFrame(resized_batch.reshape(-1, 32*32)) resized_df = pd.concat([labels, resized_pixels], axis=1) resized_df.to_csv("mnist_32x32_batch.csv", index=False)
关键注意事项
- 插值方式选择:LANCZOS(或INTER_LANCZOS4)是高质量的插值算法,适合图像缩放,能最大程度保留手写数字的细节;若追求速度,也可选择
BILINEAR或NEAREST插值,但精度会略有下降。 - 数据类型:确保像素值转换为
uint8(0-255的整数范围),避免缩放后出现超出范围的异常值。
内容的提问来源于stack exchange,提问作者Yasin Karayanık
相关产品推荐
相关产品推荐

