OpenCV (C++): how to save a 16bit image?
Asked Answered
E

2

11

I'm working with kinect, and I need to save RAW depth image. This means that I shouldn't save it with a conversion to 8 bit (that is what imwrite is doing!) but save it as 16 bit, without have any bit-depth reducing. I hope that this question will not be too trivial, but I'm new to OpenCV programming. I tried the following, but it doesn't work:

[...]

Mat imageDepth ( 480, 640, CV_16UC1 );
Mat imageRGB;

// Video stream settings
VideoCapture capture;
capture.open( CAP_OPENNI );

if ( !capture.isOpened() ) {
  cerr << "Cannot get video stream!" << endl;
  exit ( EXIT_WITH_ERROR );
}

if ( !capture.grab() ) {
  cerr << "Cannot grab images!" << endl;
  exit ( EXIT_WITH_ERROR );
}

// Getting frames
if ( capture.retrieve( imageDepth, CAP_OPENNI_DISPARITY_MAP ) ) {
  imwrite( fileDepth, imageDepth );
}
if( capture.retrieve( imageRGB, CAP_OPENNI_BGR_IMAGE ) ) {
  imwrite( fileRGB, imageRGB );
}

return EXIT_WITH_SUCCESS;

Thanks in advance.

Ebberta answered 10/11, 2014 at 16:43 Comment(4)
Have you read the documentation? "The function imwrite saves the image to the specified file. The image format is chosen based on the filename extension (see imread() for the list of extensions). Only 8-bit (or 16-bit unsigned (CV_16U) in case of PNG, JPEG 2000, and TIFF) single-channel or 3-channel (with ‘BGR’ channel order) images can be saved using this function."Amphitheater
try to save as png or tiffNomanomad
Indeed, I read the documentation, in fact I've put CV_16UC1 and I saved the image as PNG. But the image is still 8bit! EDIT: could you please tell me what's wrong in this code, assuming that fileDepth has .png as extension? Thank you very muchEbberta
Is there a way to do this with Emgu CV??? I wanna save my image into 16 bit depth tiff. Any help???Oid
E
8

The problem wasn't in the way the image was saved, that was all right (if someone will have the same problem, be sure to save in PNG/TIFF format and specify CV_16UC1 when reading). It wasn't saved as 16bit because of VideoCapture; in fact I did the following:

if ( capture.retrieve( imageDepth, CAP_OPENNI_DISPARITY_MAP ) ) {
   imwrite( fileDepth, imageDepth );
}

But the correct way to do it is:

if ( capture.retrieve( imageDepth, CAP_OPENNI_DEPTH_MAP ) ) {
  imwrite( fileDepth, imageDepth );
}

So it was a silly problem.
Thanks to all the people who tried to help me.

Ebberta answered 11/11, 2014 at 8:12 Comment(0)
F
4

My imwrite in opencv does not seem to support 16-bit image storage. So, I used the OpenCV FileStorage Class.

Next is the relevant code snippet. WRITING:

cv::FileStorage fp("depth_file.xml", cv::FileStorage::WRITE);
fp << "dframe" << dframe;
fp.release();

READING:

cv::FileStorage fs(dframeName, cv::FileStorage::READ);
if( fs.isOpened() == false)
{
    cerr<< "No More....Quitting...!";
    return 0;
}
fs["dframe"] >> dframe;
Flesh answered 20/3, 2015 at 5:12 Comment(1)
This is a very useful feature of OpenCV, but I'm still not quite sure why they don't allow, e.g., saving signed PNGs? It seems to be supported by libpng.Oriana

© 2022 - 2024 — McMap. All rights reserved.