2

I wanted to understand how I can save an image of type float:

float * image;

Allocated in this way:

int size = width * height;
image = (float *)malloc(size * sizeof(float));

I tried using the CImg library, but does not accept float directly. Infact, i only use it to capture image to float, because I need only float images.

CImg<float> image("image.jpg");
int width = image.width(); 
int height = image.height();
int size = width*height
float * image = image.data();

How do I save this picture to float from .jpg or .bmp readable. I thought to open a write buffer but not save me anything and I can not read from a file!

icktoofay
  • 126,289
  • 21
  • 250
  • 231
user2485282
  • 21
  • 1
  • 3
  • Where are these images from? What is the floating point range? I'm almost certain you will need to normalize the format to a integer value first. – Mats Petersson Aug 04 '13 at 07:09

5 Answers5

0

well, what you need is first of all to realize what you are tying to do. you are creating a pointer to float array

image=(float *)malloc(size* sizeof(float));

and then you're doing

float * image =image.data();

which is double use of image that will cause a compiler error and a bad thing to do also if you could.

now you should read on CImg here and see that Data() returns a pointer to the first pixel of the image.

now that we established all of that let's go to the solution: if you want to save the float array to a file use this example

#include <fstream.h>

void saveArray(float* array, int length);

int main()
{
    float image[] = { 15.25, 15.2516, 84.168, 84356};
    saveArray(floatArray, sizeof(image)/ sizeof(image[0]));

    return 0;
}

void saveArray(float* array, int length)
{
    ofstream output("output.txt");

    for(int i=0;i<length;i++)
    {
        output<<array[i]<<endl;
    }
}
No Idea For Name
  • 11,411
  • 10
  • 42
  • 70
  • Hello, thank you for answer. It is clear to all except for one thing: why output.txt is txt and not bmp or jpg? – user2485282 Aug 04 '13 at 07:16
  • because i still don't know your purpose... you start with a .jpg, so i don't know why will you open it and then save is again... if you want to just copy it there are simpler ways – No Idea For Name Aug 04 '13 at 07:28
  • ok I'll tell you, I want to open an image, pass it to float apply an algorithm made ​​by me and then save this float in my destination folder in a readable format ;-) – user2485282 Aug 04 '13 at 07:31
  • i'm not sure about the format of bmp/jpg files, but i'm quite sure you can find all the information you need in a simple google search. i'm saying that because i don't have the time at the moment to check it, but if you want to wait maybe in several hours i'll have the time. – No Idea For Name Aug 04 '13 at 07:40
0

Since the JPEG image format only supports 8 bit color components (actually the standard allows for 12 bit, but I have nver seen an implementation of that), you cannot do this with JPEG.

You may be able to do this with a .bmp file. See my answer to a question with a possible way to do this with the OpenCV library. With some other library it may be easy with .bmp files because OpenCV assumes 8 bit color channels even though, as fas I know, the .bmp format doesn't dictate that.

Do you need compression? If not just write a binary file, or store the file in yml format, etc.

If you need compression OpenEXR would be option to consider. Probably Image Magick would be the best implementation for you as it integrates well with CImg. Since CImg doesn't natively support .jpg, I suspect that you may already have Image Magick.

Community
  • 1
  • 1
Bull
  • 11,771
  • 9
  • 42
  • 53
  • The BMP file format (which they're okay with) doesn't have compression, so they probably don't need compression. – icktoofay Aug 04 '13 at 07:16
  • Hi,actually I did not want to use OpenCv in this application because according to my point of view is too heavy lib :-( – user2485282 Aug 04 '13 at 07:21
  • @user2485282 I not sure what you see as wrong with OpenCV - in my experience it is really fast. And if for some reason you do not want to install the whole library you can always copy just the source for the .bmp codec. – Bull Aug 04 '13 at 07:27
  • you're probably right, but I can not find any library except OpenCv me to do this thing! I would like to actually understand the code to do this rather than use a library – user2485282 Aug 04 '13 at 07:27
0

Well I can see from your code that you are using only 32bit float grayscale (no R,G,B just I) so this are my suggestions:

  1. Radiance RGBE (.hdr) use 3x8bit mantisa for R,G,B and 1x8bit exponent which gives you only 16bit precision. But if you use also R,G,B than for simulation purposes this format is not siutable for you. (you loose to much precision because of that the exponent is the same for all channels)

  2. any HDR format is not native so you need to install viewers and must code read/write functions for your source code or use of libs

  3. non HDR formats (bmp,jpg,tga,png,pcx...) If you use grayscale only than this is the best solution for you. These formats are usualy 8bit per channel so you can use 24-32bits together for your single intensity. Also you can view/edit these images natively on most OS. there are 2 ways to do this.

    • for 32bit images you can simply copy float to color =((DWORD*)(&col))[0]; where col is your float pixel. This is simplest without precision loss but if you view your image it will be not pretty :) because floats are stored in different way than integer types.

    • use of color palette. Create color scale palette from min to max possible value of your pixel colors (more colors it has more precision is saved). then bound whole image to this values. after this convert float value to index in your palette and store it (for save) and reverse get float from index in palette from color (for load) in this way the picture will be viewable similar to thermal images ... the conversion from float value to index/RGB color can be done linearly (loose lots of precision) or nonlinearly (by exp,log functions or any nonlinear you want) In best case if you use 24bit pixels and have scale palette from all 2^24 colors and you use nonlinear conversion than you loose only 25% of precision (if you really use whole dynamic range of float, if not than the loss is smaller even down to zero)

tips for scale:

  • look at the light spectrum colors its a good color scale for start (there are many simple source codes that create this with some fors just google), you can also use any color gradient patterns.

  • nonlinear function should be changing less on float range where you need to keep precision (range where most of your pixels can be) and changing much where precision is not important (+/- NaN). I usualy use exp,ln or tan, but you must scale them to range of your color scale palette.

Spektre
  • 49,595
  • 11
  • 110
  • 380
0

The BMP file format is pretty simple: https://en.m.wikipedia.org/wiki/BMP_file_format

Read the header to determine height, width, bpp, and data start index. And then just start filling in your float array by casting the pixel channel values to float (starting from the index specified in header), going across the width. When you reach module the specified width, go to next row in array.

JPG decoding is more complex. I would advise against rying to do it yourself.

Hashman
  • 367
  • 1
  • 10
0

If you want to save float values, you need to use a format that supports them - which is not JPEG and not BMP. The most likely options are:

  • TIFF - which requires a library to write

  • FITS - which is mainly used for Astronomy data, and is not too hard to write

  • PFM (Portable Float Format) which is a least common denominator format, in the same vein as NetPBM format and which is described here.

The good news is that CImg supports PFM out-of-the-box with no additional libraries required. So the answer to your question is very simple:

#include "CImg.h"
using namespace cimg_library;
int main() {
   CImg<float> image("image.png");
   image.normalize(0.0,1.0);
   image.save_pfm("result.pfm");
}

If you want to view your image later, ImageMagick understands all the above formats and can convert any of them to anything else:

convert result.pfm image.jpg       # convert PFM to JPG
convert result.pfm image.png       # convert PFM to PNG
convert result.tif image.bmp       # convert TIF to BMP

Keywords: CImg, C++, C, float, floating point, image, image processing, save as float, real, save as real, 32-bit, PFM, Portable Float Map

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432