使用patchify切分不同尺寸图像生成补丁时出现重复补丁问题
问题原因
你遇到的重复补丁问题和patchify库无关,完全是代码逻辑的两处错误导致的:
- 缩进错误:你遍历文件路径列表生成补丁的代码块,错误缩进在了
if name.endswith(".png")的判断分支内部。实际运行逻辑是每扫描到1张png图片加入路径列表,就会立刻遍历当前列表里已经存入的所有图片,重新生成一遍所有补丁。举个例子,如果输入文件夹有图1、图2、图3:扫描到图1加入列表 → 列表只有[图1],处理1次图1生成补丁
扫描到图2加入列表 → 列表有[图1,图2],再处理1次图1、1次图2生成补丁
扫描到图3加入列表 → 列表有[图1,图2,图3],第三次处理图1、图2、图3生成补丁
仅3张图就会重复处理多轮,自然会产生大量重复文件。 - 变量引用错误:内层循环遍历
filename处理每张图时,保存补丁用的文件名是外层循环的name变量(也就是当前刚扫描到的那个文件名),不是当前正在处理的filename对应的真实文件名,会导致不同图片的补丁被错误重命名,进一步出现重复副本。
两种尺寸单独处理时没暴露问题,大概率是你做单尺寸测试时每次只在输入文件夹放1张图,列表每次仅存入1个路径,不会触发多轮重复处理,重复生成的同名补丁也会被直接覆盖,看起来数量正常;混合尺寸时文件夹内同时存在多张不同尺寸的图片,多轮重复处理生成的补丁因为i、j索引组合、文件名的差异没有被完全覆盖,就出现了大量额外的重复副本。
修正后代码
修正缩进、把保存文件名改成对应当前处理文件的真实名称,同时优化路径拼接逻辑避免跨平台路径错误即可:
import numpy as np import cv2 from PIL import Image import os from patchify import patchify # 第一步:先收集所有符合要求的文件路径 file_list = [] source_dir = "C:/.../Input/Images/" destination_dir = "C:/.../Output/Images/" for root, _, files in os.walk(source_dir): for name in files: if name.endswith(".png"): file_list.append(os.path.join(root, name)) # 第二步:所有路径收集完成后,再统一遍历处理 for filepath in file_list: # 提取当前处理文件的真实文件名 filename = os.path.basename(filepath) img_no_ndarray = Image.open(filepath) img = np.array(img_no_ndarray) # 512尺寸patch和步长匹配,横竖图都能正好切分无余数 patches_img = patchify(img, (512, 512, 3), step=512) for i in range(patches_img.shape[0]): for j in range(patches_img.shape[1]): single_patch_img = patches_img[i, j, 0, :, :, :] save_path = os.path.join(destination_dir, f"{i}_{j}_{filename}") if not cv2.imwrite(save_path, single_patch_img): raise Exception("Could not write the image")
补充说明
如果需要进一步避免不同源图生成的补丁因为i、j索引重名被覆盖,可以在保存文件名里加唯一标识,比如源图序号、文件哈希值,上述代码已经把源文件名作为补丁命名的一部分,不会出现跨文件覆盖的问题。
内容的提问来源于stack exchange,提问作者StefanJ
相关产品推荐
相关产品推荐

