C 加快写入多图像TIFF?

C 加快写入多图像TIFF?,c,file-io,tiff,genicam,C,File Io,Tiff,Genicam,我正在尝试将图像堆栈写入TIFF文件。图像大小为256*256像素,每个堆栈包含1000个图像。编写其中一个文件大约需要4分钟——所以我的代码很可能有问题 以下是我正在做的: void Tiff_WriterSplit(float data[], int PicNum, int WIDTH, int LENGTH, char PATH[]) { int i; int rows = LENGTH, columns = WIDTH; TIFF* tif; i

我正在尝试将图像堆栈写入TIFF文件。图像大小为256*256像素,每个堆栈包含1000个图像。编写其中一个文件大约需要4分钟——所以我的代码很可能有问题

以下是我正在做的:

void Tiff_WriterSplit(float data[], int PicNum, int WIDTH, int LENGTH, char PATH[]) {
     int i;
     int rows = LENGTH, columns = WIDTH;
     TIFF* tif;

     if (PicNum == 0)
         tif = TIFFOpen(PATH, "w");
     else
         tif = TIFFOpen(PATH, "a");

     TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, columns);
     TIFFSetField(tif, TIFFTAG_IMAGELENGTH, rows);
     TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
     TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32);
     TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);

     for (i = 0; i < rows; i++)
         TIFFWriteScanline(tif, &data[i * columns], i, 0);

     TIFFWriteDirectory(tif);
     TIFFClose(tif);
}
void Tiff_WriterSplit(浮点数据[],int PicNum,int WIDTH,int LENGTH,char PATH[]){
int i;
int行=长度,列=宽度;
TIFF*tif;
if(PicNum==0)
tif=TIFFOpen(路径“w”);
其他的
tif=TIFFOpen(路径“a”);
TIFFSetField(tif、TIFFTAG_图像宽度、列);
TIFF设置字段(tif,TIFF标签长度,行);
TIFFSetField(tif,TIFFTAG_采样每像素,1);
TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE,32);
TIFFSetField(tif、TIFFTAG_样本格式、样本格式_IEEEFP);
对于(i=0;i

将为堆栈的每个图像调用此函数
Tiff\u WriterSplit
。第一个图像将具有
PicNum=0
w
模式打开tiff文件,以下所有图像将具有
PicNum>0
a
模式打开tiff文件。写这篇文章的速度大约从40 MB/s开始,随着文件大小的增加,速度越来越慢,降到1 MB/s左右。如何优化性能?

我遇到过类似的性能问题。似乎(从libTiff版本4.0.9开始)TIFFWriteDirectory中存在性能问题,导致其运行时间与多页TIFF文件中已存在的图像数量成比例

我认为这与TIFF文件规范的编写方式无关——我认为这是libTiff中的一个性能缺陷


我发现保存前80个图像(大约24000字节)需要21ms,但当我将9000个图像写入同一个文件时,这会线性上升到3秒。99.5%的时间花在TIFFWriteDirectory(通过TIFFLinkDirectory调用,大部分时间花在_tiffReadProc)上。

写TIFF比读TIFF容易得多。libtiff的开销对于写性能来说是非常有限的。假设您有一个可以由tiff头表示的像素格式的缓冲区,那么写tiff的步骤

  • 写入tiff头
  • 写入图像数据
  • 写入目录(标记表)
  • 对于多图像tiff,我们受到4GB tiff限制32位条目的限制。但是,如果图像始终具有相同的几何图形(宽度、高度、平面、深度),则在写入所有图像数据后,可以写出标记表中的目录项。您可以自由地将目录放置在tiff二进制文件的末尾(或开头)。如果在最后,您知道图像的数量,则可以在写入图像之前形成目录条目(就地构造表)。如果API不允许您事先知道图像的数量,那么在写入最终图像后,必须在IFD中计算最终文件偏移量

    直接编写tiff可以让您使用
    fallocate
    mmap
    和其他操作系统功能,这些功能可以加速编写多图像tiff。如果需要翻译图像格式,这项工作在计算上更具挑战性,因为它可能涉及信号处理

    直接写入与libtiff相比,单图像平面写入速度快3倍以上。如果libtiff不断地在tiff(IFD)末尾重新计算和重新定位标记表,则每个图像的值为O(n^2)

    我使用这种技术将科学图像传感器数据从一台设备传输到磁盘。它允许以更高的FPS进行捕获

    将视觉分析与多tiff(目录)结构相结合以查找感兴趣的区域将允许在单个tiff中为每个帧保存多个感兴趣的区域

    参考文献

    您在什么设备上编写?我在一个特定的“工作马”上运行此程序,它从服务器(通过10 Gbit以太网)获取数据并将其写回服务器。我还以大约100 MB/s的速度将原始数据以二进制格式写入服务器。所以,硬件不应该是这里的问题…@thomas谢谢你的建议!这确实是服务器的一个问题——在本地存储文件需要花费大量时间