如何将大尺寸3D numpy数组切分为无畸变的子数组后转换为2D格式
3D numpy数组无畸变切块解决方案
问题根源
你遇到的子块畸变是因为numpy的reshape仅按照内存存储顺序调整数组维度,不会自动按空间区域切分。默认C序存储的numpy数组优先遍历最后一个维度,直接调用reshape会把跨空间块的连续内存强行合并到同一个子数组里,自然会出现内容错乱。
正确实现代码
适配你给出的示例,修改后的处理逻辑如下:
import numpy as np import matplotlib.pyplot as plt # 生成测试用坐标数组 big_image = np.zeros([100,100,100]) for i in range(big_image.shape[0]): for j in range(big_image.shape[1]): for k in range(big_image.shape[2]): big_image[i,j,k] = int(f"{i}{j}{k}") dims_orig = np.shape(big_image) block_size = 32 # 裁剪为各轴都是块大小的整数倍 dims_crop = np.array( [dims_orig[0]//block_size*block_size, dims_orig[1]//block_size*block_size, dims_orig[2]//block_size*block_size], dtype=np.int32 ) crop_image = big_image[:dims_crop[0],:dims_crop[1],:dims_crop[2]] # ------------------- 核心无畸变切块逻辑 ------------------- # 计算各轴的切块数量 n0, n1, n2 = dims_crop // block_size # 第一步:将每个空间轴拆分为 块数*块大小 维度 reshaped = crop_image.reshape(n0, block_size, n1, block_size, n2, block_size) # 第二步:调整轴顺序,把所有块维度放在前面,空间维度放在后面 transposed = reshaped.transpose(0, 2, 4, 1, 3, 5) # 第三步:合并块维度,得到 (总块数, 块x, 块y, 块z) 结构的无畸变子块数组 blocks = transposed.reshape(-1, block_size, block_size, block_size) # 第四步:按需求展平为 (总块数, 块x, 块y*块z) 的2D结构 flattened_blocks = blocks.reshape(blocks.shape[0], block_size, -1) # ---------------------------------------------------------- # 验证结果:第一个子块的第0层和原图左上角的32x32区域完全一致 print(np.array_equal(blocks[0, 0, :, :], crop_image[0, :block_size, :block_size])) # 输出为True即表示切块无畸变
效果验证
运行代码后验证返回值为True,就说明切出来的子块和原图像对应区域完全一致,没有畸变,可以直接用于后续模型训练。
内容的提问来源于stack exchange,提问作者Masoud
相关产品推荐
相关产品推荐

