Home > Mobile >  fast and power efficient way to convert 8bit values to 4bit values and save 2 4bit values in one byt
fast and power efficient way to convert 8bit values to 4bit values and save 2 4bit values in one byt

Time:03-02

i want to make a video stream program over udp, with opencv, i want to make a compression by converting the 255 color values into 16 color values, because it will save trafic by half and the quality isnt that bad. i know how to convert 255 values to 16 values:

opencvimg = numpy.multiply(opencvimg//16,16)

but i dont know a efficient way to get two values into 1 byte to save traffic. it has to be efficient cause i want it to run on a rpi (full code on github.com/Open-ATS-Github).

CodePudding user response:

There is a solution that involves no explicit arithmetic: you can build a full lookup-table of 256 x 256 entries, giving the packed result for a pair of input bytes.

If such a table seems unreasonably large, think that you are working with images, which are even larger.

Whether it is better to work with a flat vector or with a matrix and if cache effects will not ruin the effort is a matter of experimentation.

CodePudding user response:

I think you mean this:

import numpy as np

# Make synthetic data
x = np.arange(256, dtype=np.uint8)

# Take pairs of elements shifted by 4 bits and OR together
d2by4 = (x[::2] & 0xf0) | (x[1::2] >> 4)

In [16]: d2by4.dtype
Out[16]: dtype('uint8')

In [21]: d2by4
Out[21]: 
array([  0,   0,   0,   0,   0,   0,   0,   0,  17,  17,  17,  17,  17,
        17,  17,  17,  34,  34,  34,  34,  34,  34,  34,  34,  51,  51,
        51,  51,  51,  51,  51,  51,  68,  68,  68,  68,  68,  68,  68,
        68,  85,  85,  85,  85,  85,  85,  85,  85, 102, 102, 102, 102,
       102, 102, 102, 102, 119, 119, 119, 119, 119, 119, 119, 119, 136,
       136, 136, 136, 136, 136, 136, 136, 153, 153, 153, 153, 153, 153,
       153, 153, 170, 170, 170, 170, 170, 170, 170, 170, 187, 187, 187,
       187, 187, 187, 187, 187, 204, 204, 204, 204, 204, 204, 204, 204,
       221, 221, 221, 221, 221, 221, 221, 221, 238, 238, 238, 238, 238,
       238, 238, 238, 255, 255, 255, 255, 255, 255, 255, 255], dtype=uint8)

That says... "take the high nibble of every second element of x starting with the first and OR it together with the upper nibble shifted right by 4 bits of every second element of x starting with the second."

  • Related