Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV save CV_32FC1 images

Tags:

c++

file

opencv

A program I am using is reading some bitmaps, and expects 32FC1 images.

I am trying to create these images

cv::Mat M1(255, 255, CV_32FC1, cv::Scalar(0,0,0));
cv::imwrite( "my_bitmap.bmp", M1 );

but when I check the depth - it is always CV_8U

How can I create the files so that they will contain the correct info ?

Update: It makes no difference if I use a different file extension - e.g. tif or png

I am reading it - using code that is already implemented - with cvLoadImage.

I am trying to CREATE the files that the existing code - that checks for the image type - can use.

I cannot convert files in the existing code. The existing code does not try to read random image type and convert it to desired type, but checks that the files are of the type it needs.

I found out - thank you for the answers - that cv::imwrite only writes integer type images.

Is there another way - either using OpenCV or something else - to write the images so that I end up with CV_32F type ?

Update again: The code to read image... if into a cv::Mat:

cv::Mat x = cv::imread(x_files, CV_LOAD_IMAGE_ANYDEPTH|CV_LOAD_IMAGE_ANYCOLOR);

The existing code:

IplImage *I = cvLoadImage(x_files.c_str(), CV_LOAD_IMAGE_ANYDEPTH|CV_LOAD_IMAGE_ANYCOLOR);
like image 783
Thalia Avatar asked Jul 18 '13 23:07

Thalia


1 Answers

cv::imwrite() .bmp encoder assumes 8 bit channels.

If you only need to write .bmp files with OpenCV , you can convert your 32FC1 image to 8UC4, then use cv::imwrite() to write it and you will get a 32bits per pixel .bmp file. I am guessing that your program that reads the file will interpret the 32 bit pixels as a 32FC1. The .bmp format doesn't have an explicit channel structure, just a number of bits per pixel. Therefore you should be able to write 32 bit pixels as 4 channels of 8 bits in OpenCV and read them as single channel 32 bit pixels in another program - if you do this you need to be aware of endianness assumptions by the reader. Someting like the following should work:

cv::Mat m1(rows, cols, CV_32FC1);
...  // fill m1
cv::Mat m2(rows, cols, CV_8UC4, m1.data); // provide different view of m1 data
// depending on endianess of reader, you may need to swap byte order of m2 pixels
cv::imwrite("my_bitmap.bmp", m2);

You will not be able to read properly the files you created in OpenCV because the .bmp decoder in OpenCV assumes the file is 1 or 3 channel of 8 bit data (i.e. it can't read 32 bit pixels).


EDIT

Probably a much better option would be to use the OpenEXR format, for which OpenCV has a codec. I assume you just need to save your files with a .exr extension.

like image 180
Bull Avatar answered Oct 13 '22 18:10

Bull