我一直在开发一个C ++应用程序,可以从相机中下载每像素16位灰度图像。
由于我所知道的大多数库不支持每像素16位,因此,为了将图像存储在文件中,我想了解哪种图像格式和库可以使用此功能加载和存储图像。
为此,我希望有一个代码片段,用于将16位图像写入文件。
答案 0 :(得分:2)
支持16位灰度图像的最可能的候选者是:
NetPBM的PGM格式 - 这是一种非常简单的读写格式,并不需要一个库。除了大小之外,它不支持太多的元数据。它不是很节省空间,因为它不支持压缩,但是嘿,存储很便宜!
PNG格式 - 这是一种非常流行,灵活且高效的格式,所有软件包都能理解。
TIFF格式 - 非常流行且非常灵活的格式,几乎所有应用程序都能理解,并且在平台和应用程序之间可以互换。适用于DeepZoom,适用于多图像/多层文件以及存储元数据。
所有上述内容都得到了CImg的支持,这是一个极好的,跨平台的现代C ++工具包(没有 OpenCV 的复杂性),还有 ImageMagick 适用于所有平台和所有格式。还有libtiff
和libpng
用于阅读和编写这些格式。上面提到的所有库都对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
# Create 16-bit TIF filled with random greys
magick -size 300x200 -colorspace gray xc:gray +noise random random.tif
# 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
您还可以在我提到的所有格式之间进行转换:
# 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位灰度图像,使用库解析和转储它是非常简单的 - scanf
和fread
绰绰有余。