Can we get Image type(16UC1) byte array from the compressed byte array(jpeg compressed)?
Hi,
I am using ROS Sharp to send compressedImages from a ROS Kinetic Ubuntu Xenial workstation with aligned depth to color information. Then, I am using 'OpenCV for Unity' to decode the compressedImage byte array and was hoping to receive 16UC1 data but instead I am receiving 8UC1 data.
So my question is, is it possible to decompress a ROS compressedImage to retrieve back the original Image type byte array? Or will there always be a loss like in my case, i.e. 16UC1 is the original image but the decoded compressedImage is 8UC1 ?
Asked by akcast on 2019-02-23 13:11:51 UTC
Answers
Firstly you should avoid subscribing directly to the compressed topic, and use the image_transport package to deal with any decompression transparently.
The example shown in the image_transport tutorials shows how to set this up. You can request that it uses the compressed topic if possible using a TransportHints object as shown below:
image_transport::Subscriber itSub;
image_transport::ImageTransport it(n);
itSub = it.subscribe("base_img_topic",1,&imgCallback,image_transport::TransportHints("compressed"));
This way you never have to deal with the compression or decompression directly. If you're still getting 8 bit images using this method then there may be a problem with the publishing node, that means it's publishing 8 bit images. But hopefully this will get this working.
Asked by PeteBlackerThe3rd on 2019-02-25 06:26:00 UTC
Comments
Hi, @PeteBlackerThe3rd Thanks for your response!
I would be decompressing the compressedImage topic in Unity and I am using ROS Sharp for this, which I believe at the moment does not have support for the image_transport' package and can only subscribe to regular ROS topics.
Which is why I..
Asked by akcast on 2019-02-25 07:37:01 UTC
...had this question, and wanted to know if it can be done just by subscribing to the compressedImage topic and decoding using OpenCV ? Also, is jpeg compression suitable for retrieving the 16UC1 byte representation or is PNG required for this ? At the moment I am using jpeg.
Asked by akcast on 2019-02-25 07:43:25 UTC
I'm about 80% certain that compressed image transport uses PNG for 16 bit images, I don't believe the JPEG compressor in openCV supports 16 bit. This may be where your problem lies.
Asked by PeteBlackerThe3rd on 2019-02-25 09:34:04 UTC
Comments
This is certainly possible. Compressed image transport supports 16 bit images. How are you producing the compressed image topic initially and how are you converting it to a cv::Mat in the subscriber?
Asked by PeteBlackerThe3rd on 2019-02-23 18:46:50 UTC
Firstly, I subscribe to "/camera/aligned_depth_to_color/image_raw/image raw/compressed" topic (originally 16UC1) which is published from realsense ros node.
Then, using OpenCV for Unity I use: imgcodec.imdecode(new MatOfByte(compressedImageData.data), CV_LOAD_IMAGE_ANYDEPTH)
Asked by akcast on 2019-02-24 15:49:59 UTC
...resulting in a 307200 byte array i.e. 8UC1. The imdecode function I think gives 16-bit values if there is a corresponding depth in the image, else it returns a 8-bit value, when using the CV_LOAD_ANYDEPTH flag. So, if the compressedImage does contain 16-bit values, im not sure why I get 8-bit?
Asked by akcast on 2019-02-24 15:56:52 UTC