如何解决Jupyter Notebook运行图像处理代码时的out of memory内存不足错误
图像分块生成内存溢出(OOM)问题解决方案
问题根因
你当前代码将所有生成的图像块全部缓存在内存中的image_dataset列表中,按参数计算:若使用256×256的分块尺寸,单张5000×5000的3通道图像可切割出约400个分块,全量12.7GB数据集的分块总大小会远超32GB内存上限,最终触发OOM崩溃。
修复方案
- 取消内存全量存储逻辑,生成分块后直接写入本地磁盘,按
原图像名_分块行号_分块列号的规则命名,后续使用时按批次读取即可,完全避免内存长期占用。
可参考修改后的分块存储逻辑:import os import cv2 import numpy as np from PIL import Image from patchify import patchify import gc # 提前创建分块存储目录 patch_save_root = "./image_patches" os.makedirs(patch_save_root, exist_ok=True) patch_size = 256 # 按实际需求修改 root_directory = "./your_dataset_root" # 按实际路径修改 for path, subdirs, files in os.walk(root_directory): dirname = path.split(os.path.sep)[-1] if dirname == 'images': images = os.listdir(path) for i, image_name in enumerate(images): if image_name.endswith(".tif"): # 路径拼接用os.path.join避免跨系统兼容问题 img_path = os.path.join(path, image_name) image = cv2.imread(img_path, 1) SIZE_X = (image.shape[1]//patch_size)*patch_size SIZE_Y = (image.shape[0]//patch_size)*patch_size image = Image.fromarray(image) image = image.crop((0 ,0, SIZE_X, SIZE_Y)) image = np.array(image) print("Now patchifying image:", img_path) patches_img = patchify(image, (patch_size, patch_size, 3), step=patch_size) for i in range(patches_img.shape[0]): for j in range(patches_img.shape[1]): single_patch_img = patches_img[i,j,0,:,:] # 提前去掉多余维度 # 归一化挪到后续训练预处理阶段,此处直接存原始uint8数据,占用空间减少4倍 save_name = f"{os.path.splitext(image_name)[0]}_{i}_{j}.npy" np.save(os.path.join(patch_save_root, save_name), single_patch_img) # 处理完单张图主动释放内存 del image, patches_img gc.collect() - 调整归一化时机:当前对单个分块做
MinMaxScaler归一化的操作无需提前在分块阶段执行,可挪到后续训练的批次预处理步骤,既减少分块时的内存开销,也能避免存储浮点型分块额外占用更多磁盘/内存空间。 - 如果后续流程必须要在内存中加载分块,可改用Python生成器替代列表存储,每次仅返回一个批次的分块数据,不要一次性加载全量数据。
内容的提问来源于stack exchange,提问作者Rameen Rahman
相关产品推荐
相关产品推荐

