如何将图像分割为规则块并打乱重组?patchify的unpatchify报错排查
问题分析与解决
核心报错原因
np.random.shuffle()是原地打乱数组,执行后返回None,因此shuffled_patches实际为None,调用unpatchify时自然触发'NoneType' object has no attribute 'shape'错误。
此外还有两个潜在问题:
- 原图像尺寸需是patch大小的整数倍,否则
patchify会自动截断边缘像素,后续unpatchify无法还原到原图像尺寸 patchify返回的patch数组维度需要调整后才能正确打乱
修正后的完整代码
import numpy as np from PIL import Image from patchify import patchify, unpatchify import matplotlib.pyplot as plt import requests import torchvision.transforms as transforms # 预处理:统一图像尺寸为可被patch大小整除的数值(示例用200x200,对应100x100的patch) transform = transforms.Compose( [transforms.Resize((200, 200)), transforms.ToTensor()]) url = 'https://hips.hearstapps.com/hmg-prod/images/bright-forget-me-nots-royalty-free-image-1677788394.jpg' image = Image.open(requests.get(url, stream=True).raw) # 转换为numpy数组(HWC格式) img_np = np.array(transform(image).permute(1,2,0)) # 分割图像为100x100的patch patch_size = (100, 100, 3) patched_image = patchify(img_np, patch_size, step=100) # patched_image形状为(2, 2, 1, 100, 100, 3) # 调整维度,将patch展平为一维列表方便打乱 num_patches_h, num_patches_w = patched_image.shape[0], patched_image.shape[1] patches_flat = patched_image.reshape(-1, *patch_size) # 形状变为(4, 100, 100, 3) # 生成打乱索引,避免原地修改导致的None问题 shuffled_indices = np.random.permutation(len(patches_flat)) shuffled_patches_flat = patches_flat[shuffled_indices] # 恢复patch数组的原始维度结构 shuffled_patched = shuffled_patches_flat.reshape(num_patches_h, num_patches_w, 1, *patch_size) # 拼接回完整图像 output_image = unpatchify(shuffled_patched, img_np.shape) # 可视化对比 plt.figure(figsize=(12,6)) plt.subplot(121) plt.title('Original Image') plt.imshow(img_np) plt.subplot(122) plt.title('Shuffled Patches Image') plt.imshow(output_image) plt.show()
关键修正点说明
- 解决
NoneType问题:使用np.random.permutation()生成打乱索引,替代原地修改的shuffle(),确保得到有效数组 - 适配patch尺寸:将图像resize为
200x200(100的整数倍),避免patchify截断边缘,保证unpatchify能准确还原到原尺寸 - 维度调整:先将
patchify返回的多维度数组展平为一维patch列表,打乱后再恢复原patch数组的维度结构,满足unpatchify的输入格式要求
内容的提问来源于stack exchange,提问作者Rainbow
相关产品推荐
相关产品推荐

