如何按8x8分块规则将numpy二值掩码数组下采样为16x16尺寸
NumPy向量化实现二值掩码8x8块降采样
核心逻辑
不需要写多层Python循环遍历像素,直接通过数组维度重塑+轴聚合的方式批量处理所有块,判断规则完全匹配需求:
- 对每个8×8子块,若所有元素为0,输出0
- 对每个8×8子块,若所有元素为1,输出1
- 对同时包含0和1的混合子块,随机赋值0或1
- 最终输出形状为
(146, 16, 16)的二值掩码数组
可直接运行的代码
import numpy as np # 输入数组形状 (146, 128, 128),元素仅为0/1 # 替换为你自己的数组加载逻辑即可,例如 ys_big_seg = np.load("seg_array.npy") # 分块参数配置 BLOCK_SIZE = 8 N, H, W = ys_big_seg.shape # 校验输入尺寸是否符合分块要求 assert H % BLOCK_SIZE == 0 and W % BLOCK_SIZE == 0, "输入矩阵长宽必须能被块大小整除" out_h, out_w = H // BLOCK_SIZE, W // BLOCK_SIZE # 1. 把数组重塑为分块结构,维度顺序为:(样本数, 纵向块数, 块高, 横向块数, 块宽) blocks = ys_big_seg.reshape(N, out_h, BLOCK_SIZE, out_w, BLOCK_SIZE) # 2. 统计每个8x8块内值为1的元素总数:全0块和为0,全1块和为64,混合块和在1-63区间 block_sum = blocks.sum(axis=(-1, -3)) # 3. 初始化结果数组 res = np.zeros((N, out_h, out_w), dtype=np.uint8) # 全1块直接赋值1 res[block_sum == BLOCK_SIZE * BLOCK_SIZE] = 1 # 定位所有混合块,随机赋值0/1 mixed_mask = (block_sum > 0) & (block_sum < BLOCK_SIZE * BLOCK_SIZE) res[mixed_mask] = np.random.randint(0, 2, size=mixed_mask.sum(), dtype=np.uint8) # 输出的res即为形状(146,16,16)的目标二值掩码
补充说明
- 全程使用NumPy内置向量化操作,无显式Python层循环,处理速度比逐块像素遍历快2~3个数量级
- 输出采用
uint8类型存储,符合分割掩码的常规数据格式要求 - 混合块默认0、1赋值概率各为50%,如果需要偏向某一类,可以替换随机赋值逻辑,例如要让混合块70%概率赋值1,可改为
np.random.choice([0,1], size=mixed_mask.sum(), p=[0.3,0.7])
内容的提问来源于stack exchange,提问作者Zoltán Orosz
相关产品推荐
相关产品推荐

