如何在文件中存储每通道16位图像?

时间:2018-05-04 18:48:56

标签: c++ image file c++11

我一直在开发一个C ++应用程序,可以从相机中下载每像素16位灰度图像。

由于我所知道的大多数库不支持每像素16位,因此,为了将图像存储在文件中,我想了解哪种图像格式和库可以使用此功能加载和存储图像。

为此,我希望有一个代码片段,用于将16位图像写入文件。

3 个答案:

答案 0 :(得分:2)

支持16位灰度图像的最可能的候选者是:

  • NetPBM的PGM格式 - 这是一种非常简单的读写格式,并不需要一个库。除了大小之外,它不支持太多的元数据。它不是很节省空间,因为它不支持压缩,但是嘿,存储很便宜!

  • PNG格式 - 这是一种非常流行,灵活且高效的格式,所有软件包都能理解。

  • TIFF格式 - 非常流行且非常灵活的格式,几乎所有应用程序都能理解,并且在平台和应用程序之间可以互换。适用于DeepZoom,适用于多图像/多层文件以及存储元数据。

所有上述内容都得到了CImg的支持,这是一个极好的,跨平台的现代C ++工具包(没有 OpenCV 的复杂性),还有 ImageMagick 适用于所有平台和所有格式。还有libtifflibpng用于阅读和编写这些格式。上面提到的所有库都对16位图像感到满意。如果您需要不惜一切代价获得最高的处理速度,那么您几乎需要OpenCV。

我的经验通常表示,如果您正沿着这条路走下去,Python对16位图像的支持有点困难。

如果您打算使用 ImageMagick ,请务必安装具有16位量化的Q16版本。然后,您将能够在命令行中为您的算法生成示例16位图像:

# Create 16-bit black-to-white gradient image as PNG
magick -size 300x200 gradient: -depth 16 gradient.png

# Create solid black, 16-bit PGM in P5/binary mode
magick -size 300x200 xc:black black.pgm

# Create solid, dark-grey 16-bit PGM, in P2/ASCII mode
magick -size 300x200 xc:gray10 -compress none darkgrey.pgm

# Create 16-bit, black to white gradient as TIF
magick -size 300x200 gradient: -depth 16 gradient.tif

enter image description here

# Create 16-bit TIF filled with random greys
magick -size 300x200 -colorspace gray xc:gray +noise random random.tif

enter image description here

# Create some shapes as 16-bit PGM
magick -size 300x200 xc:black                   \
   -fill white  -draw "rectangle 20,10 120,110" \
   -fill gray40 -draw "circle 180,100 180,130"  shapes.pgm

enter image description here

您还可以在我提到的所有格式之间进行转换:

# Convert TIF to PGM
magick input.tif output.pgm

# Convert PNG to TIF
magick input.png output.tif

答案 1 :(得分:1)

TIFF文件格式支持以每像素16位的速度存储图像, ImageJ 等应用程序能够读取这些文件。

我开发了一个示例应用程序,它从文件中读取原始缓冲区,并使用 libtiff 以TIFF格式存储此缓冲区。

以下是代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <tiffio.h>

int main(int argc, char** argv)
{
    FILE* file = fopen("input.data", "rb");
    fseek(file, 0, SEEK_END);
    long fsize = ftell(file);
    fseek(file, 0, SEEK_SET);

    uint8_t* buffer = (uint8_t*)malloc(fsize);
    fread(buffer, fsize, 1, file);
    fclose(file);

    int imgWidth = 640;
    int imgHeight = 512;

    TIFF* tiff = TIFFOpen("output.tif", "w");

    TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, imgWidth);
    TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, imgHeight);
    TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1);
    TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 16);

    for(int i = 0; i < imgHeight; i++)
    {
        TIFFWriteScanline(tiff, &buffer[i*imgWidth*2], i);
    }

    TIFFClose(tiff);

    return 0;
}

要在Linux上编译:

g++ -std=c++11 main.cpp -ltiff

答案 2 :(得分:0)

通常PGM format支持16位灰度图像,使用库解析和转储它是非常简单的 - scanffread绰绰有余。