I have a video coming from a stationary camera. Both the resolution and the FPS are quite high. The data I get is in Bayer format and uses 10 bit per pixel. As there's no 10 bit data type on my platform, the original data is stored in memory using 16-bit words. I want to implement some kind of loseless compression of the data before transmitting it over a network.
- The camera does not move, so big parts of consecutive frames are
nearly identical - but still not completely, due to the inevitable
noise (denoising is not an option, as it is supposed to be loseless
and shouldn't "lose" even the noise).
- Because of high FPS, even the parts that change don't change much
between any two consecutive frames.
- However, it looks like the camera also shakes a little. Very little, but still, even the stationary objects are not completely so in the image space.
- The compression has to be done on the fly, so I can not gather a lot
of frames and compress them all together, but I can look 1 frame back
and use it as a reference.
Based on the above, my first thought was to bit-pack the data, so that those 6 redundant bits are not wasted on every word. However, I thought that if I use some entropy coding (e. g. Huffman etc.), that redundancy would be automatically taken into account, so no extra packing is necessary. So I've done the following:
- Took binary difference between two consecutive frames. The original
data range was 0~1023 (e. g. unsigned 10 bits). Difference data
becomes signed and the range increases to -1023~1023, but the data
variation (or what's the correct mathematical term) becomes much less
than in the original data, in fact, most of the values are, not
surprisingly, close to zero.
- Applied Rice coding to the difference. From what I understand, it
looks like a good choice for data sets of mostly small numerical
values.
This gives me about 60% reduction in size for 1280x720 frames, and my test system (Linux in VirtualBox on a single core) can do ~40 such compressions per second (without much optimization). Not that great, but reasonable, I guess (or is it?).
Are there better ways? Any common mistakes I made? Any general steps I missed? Higher resolution frames may be used later - should I expect better compression rates for bigger frame sizes?