numpy不支持每个元素1位的数组,我怀疑memmap没有这样的功能。但是,可以使用packbits进行简单的解决。
由于您的情况不需要比特随机访问,因此可以将其读取为每个元素1字节的数组。
full_size_mask = np.random.randint(0, 2, size=[1920, 1080], dtype=np.uint8)
packed_mask = np.packbits(full_size_mask, axis=0)
buffer = np.memmap("./temp.bin", mode='w+',
dtype=packed_mask.dtype, shape=packed_mask.shape)
buffer[:] = packed_mask
buffer.flush()
del buffer
packed_mask = np.memmap("./temp.bin", mode='r',
dtype=packed_mask.dtype, shape=packed_mask.shape)
top = 555
left = 777
width = 256
height = 256
packed_top = top // 8
packed_bottom = (top + height) // 8 + 1
packed_patch = packed_mask[packed_top:packed_bottom, left:left + width]
patch_top = top - packed_top * 8
patch_mask = np.unpackbits(packed_patch, axis=0)[patch_top:patch_top + height]
print(np.all(patch_mask == full_size_mask[top:top + height, left:left + width]))
请注意,这种解决方案可能会读取额外的位数(很可能会发生)。
具体来说,在两端最多为7位。
在您的情况下,它将是7x2x256位,但这只占补丁的约5%,因此我认为可以忽略不计。
顺便说一句,这不是您问题的答案,但当您处理二进制掩码(例如图像分割的标签)时,使用zip压缩可以大大减小文件大小。
它可能被减少到每个图像不到8 KB(而不是每个补丁)。
您可能还想考虑此选项。