简体   繁体   中英

How to compress a numpy array of type bool to uint8 with 1/8 of the size

I want to 'compress' a large array of booleans of size (Ny, Nx). What is the fastest way to I convert them into a uint8 array of size (Ny, Nx//8) where every boolean plane is stored in the next bit of a uint8?

So far I made this implementation:


import numpy as np

def compressImage(imdata):

    imdatashape = imdata.shape
    imdata_4d = imdata

    imdata_4d.shape = *imdatashape[:-1], imdatashape[-1]//8,8
    compressed_image = np.zeros(imdata_4d.shape[:-1], np.uint8)
    # take every image and add it with the right bit shift to the final image
    for i in range(8):
        compressed_image += imdata_4d[...,i] << i
    return compressed_image


imdata = np.random.randint(0,1, (500, 1600,2560), dtype=np.uint8)
imcompressed = compressImage(imdata)

Now, this is not particularly fast, on my PC it takes about 77 ms to convert eight images of size 1600x2560 (and I want to convert ~25000 images). I imagine it would be a very simple operation so there should be a lightning-fast implementation for this, right? I figured probably the best way would be to use a numpy view but numpy boolean type is also stored as a byte so that won't work.

Context: I'm using a digital micromirror device, which is some kind of fast display with only binary levels [0,1]. You have to upload all the patterns you want to display in advance. To save memory on your PC and on the device, the device supports uploading 'compressed' images. In this case, you upload a uint8 array, but it will use every bit inside every uint8 byte to figure out the levels for the next eight mirrors instead of just one.

Use np.packbits :

np.packbits(imdata,axis=-1,bitorder="little")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM