我正在搜索能够读取图像文件区域(任何格式)的库(使用任何语言),而无需最初读取整个图像文件。
我遇到过一些选项,例如vips,它确实没有将整个图像保留在内存中,但似乎仍然需要完全阅读它才能开始。
我意识到这可能不适用于压缩格式,例如jpeg,但理论上听起来像bmps或tiff应该允许这种类型的读取。
答案 0 :(得分:1)
ITK可以使用某些格式执行此操作。有一种方法CanStreamRead,对于支持流式传输的格式,例如MetaImageIO,它返回true。可以找到一个示例here。您可以在ITK forum上提出更详细的问题。
答案 1 :(得分:1)
如果可以控制文件格式,我建议你使用平铺的TIFF文件。这些通常用于数字病理学整个幻灯片图像,平均大小为100kx30k像素左右。
LibTiff可让您轻松阅读与所选ROI相对应的切片。可以压缩平铺而不会降低读取小区域的效率(不需要解码整个扫描线)。
答案 2 :(得分:1)
libvips会尽可能阅读您需要的部分。例如,如果您从大型PNG的左上角裁剪100x100像素,那就快了:
$ time vips crop wtc.png x.jpg 0 0 100 100
real 0m0.063s
user 0m0.041s
sys 0m0.023s
(四个数字是从wtc.png
裁剪的区域的左侧,顶部,宽度,高度并写入x.jpg
)
但是从底部附近的100x100像素区域相当慢,因为它必须在想要到达文件中正确点的像素之前读取和解压缩像素:
$ time vips crop wtc.png x.jpg 0 9000 100 100
real 0m3.063s
user 0m2.884s
sys 0m0.181s
JPG和剥离TIFF以同样的方式工作,虽然它不那么明显,因为它们的格式要快得多。
某些格式支持真正的随机访问读取。例如,平铺的TIFF在任何地方都很快,因为libvips可以使用libtiff只读取它需要的tile:
$ vips copy wtc.png wtc.tif[tile]
$ time vips crop wtc.tif x.jpg 0 0 100 100
real 0m0.033s
user 0m0.013s
sys 0m0.021s
$ time vips crop wtc.tif x.jpg 0 9000 100 100
real 0m0.037s
user 0m0.021s
sys 0m0.017s
OpenSlide,vips,平铺OpenEXR,FITS,二进制PPM / PGM / PBM,HDR,RAW,Analyze,Matlab以及其他一些都支持这样的真正随机访问。
如果您对更多详细信息感兴趣,那么API文档中有一章描述了libvips如何打开文件:
http://jcupitt.github.io/libvips/API/current/How-it-opens-files.md.html
使用pyvips
在Python中进行裁剪加保存import pyvips
image = pyvips.Image.new_from_file(input_filename, access='sequential')
tile = image.crop(left, top, width, height)
tile.write_to_file(output_filename)
如果底层文件格式不支持随机访问,access=
是一个标志,提示libvips可以流式传输此图像。对于支持随机访问的格式,您不需要这样,例如平铺TIFF。
您不需要写入文件。例如,这将写入stdout
上的MIME类型:
tile.jpegsave_mime(Q=85)
或者这将使包含编码为JPG的文件的缓冲区对象:
buffer = tile.write_to_buffer('.jpg', Q=85)
Q=85
是设置JPG Q因子的可选参数。您可以设置any of the file save options。
答案 3 :(得分:0)
BMP格式(未压缩)非常简单,您可以自己编写该函数。
TIFF有点不太容易,因为有很多子格式。但是TIFF库(TIFFlib)支持一个面向图块的" I / O模式。 http://www.libtiff.org/libtiff.html#Tiles
答案 4 :(得分:0)
我不知道这样的图书馆解决方案 低级文件读取访问是特定于格式的,特别是文件映射是特定于操作系统的。
如果您可以访问原始字节,然后假设您知道宽度,高度,深度和通道数等,那么计算文件偏移量是微不足道的,所以只需滚动自己的。
如果您通过网络传输提取的数据,您可以考虑在提取的ROI in-memory 中压缩它,如果它在通过网络发送之前相对较大。