我正在处理大约20000 x 20000像素的1gb大tiff图像 . 我需要在随机位置从图像中提取几个图块(大约300x300像素) .
我尝试了以下解决方案:
-
Libtiff(我能找到的唯一低级库)提供TIFFReadline(),但这意味着读取大约19700个不必要的像素 .
-
我实现了自己的tiff阅读器,它可以从图像中提取出一块图块,而无需读取不必要的像素 . 我预计它会更快,但对瓷砖的每一行进行搜索会使它变得非常慢 . 我也尝试读取包含我的磁贴的文件的所有行的缓冲区,然后从缓冲区中提取磁贴,但结果或多或少相同 .
我想收到改善我的瓷砖提取工具的建议!
一切都是受欢迎的,也许你可以提出一个我可以使用的更高效的库,一些关于C / C I / O的技巧,一些针对我需求的更高级别的策略等等 .
问候,胡安
5 回答
感谢大家的回复 .
实际上需要更改tile的方式,允许我以顺序的方式从硬盘中的文件中提取tile,而不是随机的方式 . 这允许我将文件的一部分加载到ram中,并从那里提取切片 .
效率提升很大 . 否则,如果您需要随机访问文件,mmap是一个很好的协议 .
问候,胡安
我做了类似的事情来处理一个任意大的TARGA(TGA)格式文件 . 使这种文件变得简单的事情是图像不被压缩 . 您可以计算图像中任意像素的位置,并通过简单的搜索找到它 . 如果您可以选择指定图像编码,则可以考虑使用targa格式 .
如果没有,有很多种TIFF格式 . 如果他们已经经历了支持所有不同格式的痛苦,你可能想要使用一个库 .
您收到特定的错误消息了吗?根据您使用该命令行的方式,您可能已经踩到了自己的文件 .
如果这不是问题,请尝试使用imagemagick而不是vips,如果它是一个选项 .
[主要编辑1月14日10日]
当tiff没有平铺时,我提到瓷砖时有点困惑 .
我使用平铺/金字塔TIFF图像 . 我用VIPS创造了那些
我想你可以这样做:
您可能想要尝试平铺尺寸 . 然后你可以使用TIFFReadEncodedTile阅读 .
如果您需要放大/缩小,使用金字塔tiff的多分辨率存储会快得多 . 您可能还希望使用此图像几乎紧接着有一个粗略的图像,然后是详细的图片 .
切换到(适当大小)平铺存储(这将为您带来随机访问的大量性能改进!),您的瓶颈将是磁盘io . 如果按顺序读取,文件读取会快得多 . 这里的mmapping可能是解决方案 .
一些有用的链接:
VIPS IIPImage LibTiff.NET stackoverflow VIPS是一个图像处理库,它可以做的不仅仅是读/写 . 它有自己的,非常有效的内部格式 . 它有很好的算法文档 . 首先,它将处理与文件系统分离,从而允许缓存切片 .
IIPImage是一个多缩放的Web服务器/浏览器库 . 我发现文档是关于多分辨率成像(如谷歌 Map )的非常好的信息来源
此页面上的另一个解决方案,使用mmap,仅对“小”文件有效 . 我经常遇到32位边界 . 通常,在32位操作系统(安装了4 GB内存)上分配1 GByte内存块会失败,因为即使虚拟内存在一次或两次应用程序运行后也会被激活 . 仍然有足够的内存来缓存部分或整个图像 . 更多内存=更多性能 .
只需mmap你的文件 .
http://www.kernel.org/doc/man-pages/online/pages/man2/mmap.2.html