Gittb
Gittb

Reputation: 69

Numpy reading 12bit backed bytes from buffer

I have a camera outputting BayerRG12Packed format which means each value is 12bits and they are not padded to 16 bits.

I am trying to find a simple solution to this problem (almost as if I could use a uint12 dtype), I have tried the below code but it does not seem to produce the correct output.

I am at a loss as to understanding this process..

For more info on the datatype here a link to a doc regarding it (it is just a differnt pixel order than a RG filter): BayerGB12Packed format

The data coming in from the buffer is unsigned.

def read_uint12(data_chunk):
    data = np.frombuffer(data_chunk, dtype=np.uint8)
    fst_uint8, mid_uint8, lst_uint8 = np.reshape(data, (data.shape[0] // 3, 3)).astype(np.uint16).T
    fst_uint12 = (fst_uint8 << 4) + (mid_uint8 >> 4)
    snd_uint12 = ((mid_uint8 % 16) << 8) + lst_uint8
    return np.reshape(np.concatenate((fst_uint12[:, None], snd_uint12[:, None]), axis=1), 2 * fst_uint12.shape[0])

Upvotes: 0

Views: 1145

Answers (1)

Gittb
Gittb

Reputation: 69

I actually found the solution on this thread:

https://stackoverflow.com/a/53856347/4717458

"Found @cyrilgaudefroy answer useful. However, initially, it did not work on my 12-bit packed binary image data. Found out that the packing is a bit different in this particular case. The "middle" byte contained the least significant nibbles. Bytes 1 and 3 of the triplet are the most significant 8 bits of the twelve. Hence modified @cyrilgaudefroy answer to:"

def read_uint12(data_chunk):
    data = np.frombuffer(data_chunk, dtype=np.uint8)
    fst_uint8, mid_uint8, lst_uint8 = np.reshape(data, (data.shape[0] // 3, 3)).astype(np.uint16).T
    fst_uint12 = (fst_uint8 << 4) + (mid_uint8 >> 4)
    snd_uint12 = (lst_uint8 << 4) + (np.bitwise_and(15, mid_uint8))
    return np.reshape(np.concatenate((fst_uint12[:, None], snd_uint12[:, None]), axis=1), 2 * fst_uint12.shape[0])

Upvotes: 2

Related Questions