I’ve just finished a ROS 1 package called cv_image_transport which uses OpenCV imencode
and imdecode
for compressing and decompressing images. It is very similar to the standard compressed_image_transport
.
In fact, if you choose JPEG or PNG formats, the messages from cv_image_transport
are fully compatible with compressed_image_transport
- up to the level that if you remap image/cv
→ image/compressed
, the standard compressed_image_transport
subscriber will understand the messages! (because it uses imdecode
which autodetects the image format). Also, rqt_bag, rviz and rqt_image_view all understand the images compressed by this transport.
cv_image_transport
offers all options understood by imencode
as dynamic_reconfigure parameters, so you can fine-tune the encoding as much as OpenCV allows.
Of course, ROS 1 has been sunsetted already. That’s why you won’t find the package on the buildfarm. You’ll need to build it from source.
ROS 2
I’ve seen that compressed_image_transport
got few more imencode
options in ROS 2 (like support for TIFF format and a few of its options). So it seems to me that generally, compressed_image_transport
in ROS 2 slowly goes the way towards cv_image_transport
.
Therefore, I haven’t created a port of this package into ROS 2. I’d like to hear if people think it would be generally useful to extend compressed_image_transport
to support all OpenCV codecs. What do you think?. The change could be done in an almost backwards and forwards compatible way - all image_transport subscribers would understand even images encoded with the added codecs. It would be just programs decoding the images by other means that could have problems understanding the compressed images (which, unfortunately, also affects cv_bridge).
Motivation
Why did I create cv_image_transport
in the first place? I figured there is no standard way to represent binary image masks in ROS! This kind of surprised me. People mostly use mono8 (or, even worse, bgr8) images for binary masks. But that’s a wasteful waste! A binary mask needs 1 bit per pixel, while mono8 uses 8 bits per pixel. That’s 800% increase in size!
That’s how I found the PBM format supported by OpenCV. Up to a few metadata at the beginning, it is then exactly capable of storing 1BPP images. So the idea is to still use mono8 encoding for the mask, but store the PBM-compressed variant in bag files and also use it for sending over network.