我想了解如何保存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
。我想打开一个写缓冲区,但没有保存任何东西,我无法从文件中读取!
答案 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只是我) 所以这是我的建议:
Radiance RGBE(.hdr) 使用3x8bit mantisa来表示R,G,B和1x8bit指数,它只能提供16位精度。 但是如果你还使用R,G,B而不是用于模拟目的,那么这种格式对你来说并不适用。 (由于所有通道的指数都相同,因此你的精确度很高)
任何HDR格式都不是原生的,因此您需要安装查看器,并且必须为源代码编写读/写函数或使用库
非HDR格式(bmp,jpg,tga,png,pcx ...) 如果您只使用灰度,这是最适合您的解决方案。这些格式通常为每通道8位,因此您可以将24-32位一起用于单一强度。您也可以在大多数操作系统上本地查看/编辑这些图像。有两种方法可以做到这一点。
对于32位图像,您只需将float复制到color =((DWORD *)(&amp; col))[0];其中col是你的浮动像素。这是最简单的,没有精度损失,但如果你查看你的图像,它将不漂亮:)因为浮点数的存储方式与整数类型不同。
使用调色板。从像素颜色的最小可能值到最大可能值创建颜色比例调色板(保存更多颜色的更多颜色)。然后将整个图像绑定到此值。在此之后将浮动值转换为调色板中的索引并将其存储(用于保存)并从颜色(用于加载)调色板中的索引反向浮动,这样图片将可以看到类似于热图像......浮动转换索引/ RGB颜色的值可以线性完成(松散大量精度)或非线性(通过exp,对数函数或任何你想要的非线性)最好的情况下,如果你使用24位像素并具有所有2 ^ 24颜色的刻度调色板,你使用非线性转换比只松动25%的精度(如果你真的使用浮动的整个动态范围,如果不是损失小甚至降到零)
规模提示:
看一下光谱的颜色是一个很好的色阶开始(有很多简单的源代码可以用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,便携式浮点映射