我试图将图像堆栈写入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);
}
将为堆栈的每个图像调用此函数Tiff_WriterSplit
。第一张图片将PicNum = 0
以w
模式打开tiff文件,以下所有图片都会PicNum > 0
以a
模式打开它。写入此内容的速度约为40 MB / s,随着文件大小的增加而变得越来越慢 - 大约为1 MB / s。如何优化性能?
答案 0 :(得分:1)
编写 tiff 比阅读 tiff 容易得多。 libtiff 的开销对于写入性能可能非常有限。假设您有一个可以用 tiff 标头表示的像素格式的缓冲区,编写 tiff 的步骤,
对于多图像 tiff,我们受到 32 位条目的 4GB tiff 限制。但是,如果您的图像始终具有相同的几何形状(宽度、高度、平面、深度),则可以在写入所有图像数据后写出标签表中的目录条目。您可以随意将该目录放在 tiff 二进制文件的末尾(或开头)。如果最后并且您知道图像的数量,则可以在写入图像之前形成目录条目(就地构建表)。如果 API 不允许您事先知道图像的数量,则必须在写入最终图像后在 IFD 中计算最终文件偏移量。
直接编写 tiff 可以让您使用 fallocate
、mmap
和其他可以加快编写多图像 tiff 的操作系统功能。如果需要转换图像格式,这项工作在计算上会更具挑战性,因为它可能涉及信号处理。
直接写入与 libtiff 相比,单图像平面写入速度可以提高 3 倍以上。如果 libtiff 在 tiff (IFD) 的末尾不断地重新计算和重新定位标签表,那么这将是每个图像的 O(n^2)。
我使用此技术将科学图像传感器数据从 genicam 设备流式传输到磁盘。它允许以更高的 FPS 进行捕获。
寻找感兴趣区域的视觉分析与多 tiff(目录)结构的结合将允许在单个 tiff 中为每个帧保存多个感兴趣区域。
答案 1 :(得分:0)
我遇到过类似的性能问题。看来(从libTiff版本4.0.9开始),TIFFWriteDirectory中存在一个性能问题,导致其运行时间随着多页TIFF文件中已存在的图像数量而缩放。
我认为这与编写TIFF文件规范的方式无关 - 我认为这是libTiff中的性能错误。
我发现保存前80张图像(大约24,000字节)需要21毫秒,但是当我将9,000张图像写入同一文件时,这会线性上升到3秒。 99.5%的时间花在TIFFWriteDirectory上(调用TIFFLinkDirectory,大部分时间花在_tiffReadProc上)。