Problems with saving unsigned 16 bit image data

23 views (last 30 days)
i am currently trying to use a ROS based software that uses 16 bit unsigned depth images.
I create my "own" dataset. I am saving my files as unsigned 16 bit image as imwrite(Z,fname,'fmt','png','BitDepth',16,'map','gray');
initially, I also tried the simple versions as well like imwrite(Z,fname,'fmt','png',) etc.. but they all don't work in the ROS software.
Is there a particular way i should be saving the depth data? to check if there wasnt some issue with the software i also performed the following step:
I used the depth files provided with the software and successfully obtained the results from it. Then, I read those depth files in matlab and saved them back again using the above call and it immediately fails to work. So i am pretty sure the problem is the way i am saving the data.
edit: I have included the input file: d_test.png and output file: dtect_out.png. I am simply performing 2 steps:
ZZ = imread('D:\Datasets\d_test.png');
imwrite(ZZ,'dtest_out.png','fmt','png','BitDepth',16,'map','gray','Mode','lossless');
The input file is 122kb while output file is 85kb so MATLAb is probably doing something internally that changes the file. infinfo is exactly the same except for date/filesize and othertext.
  2 Comments
Image Analyst
Image Analyst on 21 Dec 2015
Is Z a double, or is it already a uint16? What does this say in the command window?
whos Z
And what is ROS software? Many/most people probably don't know that acronym. acnronymfinder.com lists 69 possible answers but I didn't review them all.
Ramanpreet
Ramanpreet on 21 Dec 2015
ZZ 480x640 614400 uint16
ROS is robotic OS. If you see my edit, you will understand why I think its a MATLAB issue. I am not using the software for anything currently as MATLAB is simply changing something internally when i read and save the data. Perhaps I need to save my depth data in a different way?

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 21 Dec 2015
The bad news first: the problem is with your ROS software which does not decode PNG images properly. Most likely, your software implements its own zlib compression/decompression which is not compliant with the specs.
The details: I've looked at the internal of your two images with a hex decoder. There are only a few things that differ between them:
  1. three text attributes in the matlab output . These are created because matlab doesn't recognise your three options 'fmt', 'map', and 'Mode'. With the png format anything that matlab does not recognise as an option is treated as a text attribute and is stored as such in the file. If you want to get rid of them, simply do not specify these in your imwrite call.
  2. a time attribute in the matlab output. I don't think you can turn that off.
  3. the level of compression in the zlib stream (the compressed image data). Matlab uses a compression level of 2 (which is the default for zlib), whereas your original image has a compression level of 0 (fastest compression at the expense of size). Unfortunately, it doesn't appear you can choose the compression level in matlab. Moreover, any software that purports to handle zlib data must support all 4 possible compression levels, particularly for decoding as it's the same algorithm for all 4.
None of these differences should matter. They are really basic features of the PNG format, so a program that cannot handle them is definitively not PNG compliant. And it's also using its own implementation of png and zlib, which is a bit silly considering that there's a reference implementation (libpng and zlib) that is freely available.
For reference:
The png format documentation. The original file, only has the required IHDR starter chunk, several IDAT chunks (the image data, compressed with zlib) and the required IEND final chunk. The matlab file has the exact same IHDR chunk (which specifies things like image size, bit depth, colour info, etc.), a tIME chunk, three tEXT chunks, the image data in IDAT chunks, and the final IEND chunk.
The zlib format documentation. Both images use the required 87 for the CMF byte (compression method and info) but they differ in the FLGS byte on the compression level. Because of the difference in the compression level, the compressed stream is obviously completely different.
  1 Comment
Ramanpreet
Ramanpreet on 22 Dec 2015
Thanks for your insight! it basically confirmed my trial and error based tests. i cant really use any other data for their software since they used a weird version of png files specifically. I did try using openCV for reading files and it seems to have a similar size as input files. So perhaps openCV tries to retain the same compression level as input file, unlike MATLAB.

Sign in to comment.

More Answers (1)

Walter Roberson
Walter Roberson on 21 Dec 2015
The content of the files are identical except for a minor difference in the header. The error must be elsewhere.
For example if you rename the saved file to the first name, does it start working?
  6 Comments
Image Analyst
Image Analyst on 21 Dec 2015
Good answer by Guillaume (I voted for it). It looks like he used a hex editor, so apparently there is not any nifty user-friendly utility to read and report on the PNG information encoded with it (or at least he didn't use it, or wasn't able to find such a utility).
Guillaume
Guillaume on 21 Dec 2015
Edited: Guillaume on 22 Dec 2015
There's probably a tool to analyse pngs (I think I may even have written one in the past) but having written my own png encoder/decoder in the past, I'm familiar enough with the format that actually looking at the hex content of the file is easier.
The format is very well designed, everything is stored in chunks with easily readable names (IHDR, IDAT, tEXT, IEND, etc.), so you just have to locate these to find what is in the file.
@walter, the compression level used by the zlib stream is in the second byte after in the first IDAT. bit 6 and 7 of that byte is the compression level.
The original file reads: IDAT 78 01 (last two values in hex), the 78 means zlib deflate (only option, with a 32k window), the 01 means compression mode 0, which gives a checksum of 1.
The matlab file reads IDAT 78 9C, same 78, 9C means compression mode of 2 which results in a checksum value of C.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!