如何将3D图像数组分割为指定形状的Numpy子数组并处理非整除情况
3D图像数组的分块分割解决方案
嘿,我来帮你搞定这个3D数组的分块问题!咱们的目标是把形状为(band × width × height)的NumPy图像数组拆成N个子数组,最终输出(N × band × sub_width × sub_height)的结构,同时还要处理宽高没法被N整除的情况。下面是完整的实现思路和代码:
核心思路拆解
首先得把原数组的宽高调整成能被合理分割的尺寸(保证能拆出N个大小一致的子块),然后把数组分割成N个(band × sub_width × sub_height)的子数组,最后把这些子块堆叠成目标形状的数组。
这里要注意:N最好能拆成两个正整数的乘积(比如N=4拆成2×2,N=6拆成2×3),这样子块的形状会更规整,也符合你给出的示例逻辑。
具体实现步骤
第一步:调整宽高到可分割尺寸
如果原数组的宽或高没法被咱们选定的分割份数整除,先做裁剪(也可以用填充,这里以更常用的裁剪为例),得到能被整除的新尺寸。
比如咱们先确定宽和高的分割份数split_w和split_h(满足split_w × split_h = N),然后计算新的宽高:
import numpy as np # 示例输入:band=4,width=16,height=16 arr = np.random.rand(4, 16, 16) N = 4 # 确定分割份数(N=4时拆成2×2,刚好对应示例) split_w = int(np.sqrt(N)) split_h = int(np.sqrt(N)) # 计算能被分割份数整除的新宽高 new_width = (arr.shape[1] // split_w) * split_w new_height = (arr.shape[2] // split_h) * split_h # 裁剪数组到新尺寸 arr_resized = arr[:, :new_width, :new_height]
第二步:分割数组并堆叠成目标形状
先在宽度维度分割,再对每个宽块在高度维度分割,最后把所有子块堆叠起来:
# 先把数组在宽度维度拆成split_w份 split_width_blocks = np.split(arr_resized, split_w, axis=1) # 遍历每个宽块,再在高度维度拆成split_h份,收集所有子块 sub_arrays = [] for block in split_width_blocks: height_sub_blocks = np.split(block, split_h, axis=2) sub_arrays.extend(height_sub_blocks) # 把收集到的子块堆叠成目标形状(N, band, sub_width, sub_height) output = np.stack(sub_arrays, axis=0)
示例验证(对应题目中的案例)
运行上面的代码后:
- 原数组形状是
(4,16,16),因为16能被2整除,裁剪后还是这个形状 - 分割后得到4个
(4,4,4)的子数组 - 最终输出形状就是
(4,4,4,4),完全符合你的要求!
非平方数N的处理方法
如果N不是平方数(比如N=6),咱们手动指定split_w和split_h就行,只要满足两者乘积是N:
N = 6 split_w = 2 split_h = 3 # 后续步骤和上面一样,假设原width=17、height=16,裁剪后new_width=16、new_height=15,最终输出形状就是(6,4,8,5)
小补充
- 如果你不想裁剪,想用填充来调整尺寸,可以用
np.pad函数把宽高补到最近的可被分割份数整除的数值 - 上面的代码是按连续块分割的,如果需要随机提取子块,可以通过随机索引来实现,但图像分块一般都是用连续分割的方式
内容的提问来源于stack exchange,提问作者Lisa Mathew
相关产品推荐
相关产品推荐

