Search code examples
imagergbfreeimage

FreeImage portable float map (PFM) RGB channel order


I'm currently using FreeImage to load PFMs into a program that otherwise uses IplImages (the old data type for OpenCV). Here's a sample of what I'm doing (ignore the part about img being an array of Mats, that's related to some other code).

FIBITMAP *src;

// Load a PFM file using freeimage
src = FreeImage_Load(FIF_PFM, "test0.pfm", 0);

Mat* img;
img = new Mat[3];

// Create a copy of the image in an OpenCV matrix (using .clone() copies the data)
img[1] = Mat(FreeImage_GetHeight(src), FreeImage_GetWidth(src), CV_32FC3, FreeImage_GetScanLine(src, 0)).clone();

// Flip the image verticall because OpenCV row ordering is reverse of FreeImage
flip(img[1], img[1], 0);

// Save a copy
imwrite("OpenCV_converted_image.jpg", img[1]);

What's strange is that if I use FreeImage to load JPEGs instead by changing FIF_PFM to FIF_JPEG and CV_32FC3 to CV_8U, this works fine, i.e. the copied picture comes out unchanged. This makes me think that OpenCV and FreeImage generally agree on the ordering of RGB channels, and that the problem is related to PFMs specifically and their being a non-standardized format.

The PFMs I'm loading were written with this code (under "Local Histogram Equalization"), which appears to write them in RGB order although I could be wrong about that. It just takes the data from a MATLAB 3D matrix of doubles and dumps it into a file using fwrite. Also, if I modify that code to write PPMs instead, then view them in IrfanView, they look correct.

So, that leaves me thinking FreeImage is taking the file data to be BGR ordered on disk already which it is not, and should not be.

Any thoughts? Is there an error in FreeImage's reading of PFMs, or is there something more subtle going on here? Thanks.


Solution

  • Well, I never really got this one sorted out; long story short, FreeImage and OpenCV agree on color channel order (BGR) when loading most image formats, but not when loading PFMs. I can only assume that the makers of FreeImage have therefore misinterpreted the admittedly not very solidified specs for PFMs. Since I was only using FreeImage to read/write PFMs, and it was proving quite complicated to get data back into a FreeImage structure after processing with OpenCV functions, I wrote my own PFM read/write code which turned out to be very simple.