用C ++保存float *图像

时间:2013-08-04 06:47:54

标签: c++ serialization floating-point cimg

我想了解如何保存float类型的图片:

float * image;

以这种方式分配:

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

我尝试使用CImg库,但不直接接受float。事实上,我只使用它来捕捉图像浮动,因为我只需要浮动图像。

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

如何将此图片从float.jpg保存为.bmp。我想打开一个写缓冲区,但没有保存任何东西,我无法从文件中读取!

5 个答案:

答案 0 :(得分:0)

嗯,你需要的是首先要意识到你要做的事情。 你正在创建一个浮点数组的指针

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

然后你正在做

float * image =image.data();

这是image的双重使用,如果可能的话,会导致编译器错误和坏事。

现在您应该阅读CImg here并看到Data()返回指向图像第一个像素的指针。

现在我们建立了所有这些让我们去解决方案: 如果要将float数组保存到文件,请使用此示例

#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;
    }
}

答案 1 :(得分:0)

由于JPEG图像格式仅支持8位颜色分量(实际上标准允许12位,但我没有看到它的实现),你不能用JPEG做到这一点。

您可以使用.bmp文件执行此操作。查看我的answer to a question,了解如何使用OpenCV库执行此操作。对于其他一些库,使用.bmp文件可能很容易,因为OpenCV假设有8位颜色通道,即使我知道,.bmp格式也没有规定。

你需要压缩吗?如果不只是编写二进制文件,或以yml格式存储文件等

如果您需要压缩OpenEXR,可以选择考虑。可能Image Magick对您来说是最好的实现,因为它与CImg很好地集成。由于CImg本身不支持.jpg,我怀疑你可能已经有了Image Magick。

答案 2 :(得分:0)

我可以从你的代码中看到你只使用32位浮点灰度(没有R,G,B只是我) 所以这是我的建议:

  1. Radiance RGBE(.hdr) 使用3x8bit mantisa来表示R,G,B和1x8bit指数,它只能提供16位精度。 但是如果你还使用R,G,B而不是用于模拟目的,那么这种格式对你来说并不适用。 (由于所有通道的指数都相同,因此你的精确度很高)

  2. 任何HDR格式都不是原生的,因此您需要安装查看器,并且必须为源代码编写读/写函数或使用库

  3. 非HDR格式(bmp,jpg,tga,png,pcx ...) 如果您只使用灰度,这是最适合您的解决方案。这些格式通常为每通道8位,因此您可以将24-32位一起用于单一强度。您也可以在大多数操作系统上本地查看/编辑这些图像。有两种方法可以做到这一点。

    • 对于32位图像,您只需将float复制到color =((DWORD *)(&amp; col))[0];其中col是你的浮动像素。这是最简单的,没有精度损失,但如果你查看你的图像,它将不漂亮:)因为浮点数的存储方式与整数类型不同。

    • 使用调色板。从像素颜色的最小可能值到最大可能值创建颜​​色比例调色板(保存更多颜色的更多颜色)。然后将整个图像绑定到此值。在此之后将浮动值转换为调色板中的索引并将其存储(用于保存)并从颜色(用于加载)调色板中的索引反向浮动,这样图片将可以看到类似于热图像......浮动转换索引/ RGB颜色的值可以线性完成(松散大量精度)或非线性(通过exp,对数函数或任何你想要的非线性)最好的情况下,如果你使用24位像素并具有所有2 ^ 24颜色的刻度调色板,你使用非线性转换比只松动25%的精度(如果你真的使用浮动的整个动态范围,如果不是损失小甚至降到零)

  4. 规模提示:

    • 看一下光谱的颜色是一个很好的色阶开始(有很多简单的源代码可以用google创建这个),你也可以使用任何颜色的渐变图案。

      < / LI>
    • 非线性函数应该在浮点范围内变化较小,您需要保持精度(大多数像素可以在的范围)并且在精度不重要的地方(+/- NaN)变化很大。我通常使用exp,ln或tan,但你必须将它们缩放到你的色阶调色板的范围。

答案 3 :(得分:0)

BMP文件格式非常简单: https://en.m.wikipedia.org/wiki/BMP_file_format

读取标题以确定高度,宽度,bpp和数据起始索引。然后通过将像素通道值转换为float(从标头中指定的索引开始),跨越宽度来开始填充float数组。当您到达模块指定的宽度时,请转到数组中的下一行。

JPG解码更复杂。我建议不要自己去做。

答案 4 :(得分:0)

如果要保存浮点值,则需要使用支持它们的格式 - 不是JPEG而不是BMP。最可能的选择是:

  • TIFF - 需要一个库来编写

  • FITS - 主要用于天文数据,并不难写

  • PFM(Portable Float Format),它是一种最小公分母格式,与NetPBM format的格式相同,并且描述为here

好消息是 CImg 支持PFM开箱即用,无需额外的库。所以你的问题的答案很简单:

#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");
}

如果您想稍后查看图片, ImageMagick 会理解以上所有格式,并可将其中的任何格式转换为其他格式:

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

关键字:CImg,C ++,C,浮点,浮点,图像,图像处理,保存为浮点数,实数,另存为实数,32位,PFM,便携式浮点映射