Extracting a region of interest from an image file without reading the entire image

末鹿安然 提交于 2019-12-20 05:47:25

问题


I am searching for a library (in any language) that is capable of reading a region of an image file (any format) without having to initially read that entire image file.

I have come across a few options such as vips, which does indeed not keep the entire image in memory, but still seems to need to read it entirely to begin with.

I realize this may not be available for compressed formats such as jpegs, but in theory it sounds like bmps or tiffs should allow for this type of reading.


回答1:


libvips will read just the part you need, when it can. For example, if you crop 100x100 pixels from the top-left of a large PNG, it's fast:

$ time vips crop wtc.png x.jpg 0 0 100 100
real    0m0.063s
user    0m0.041s
sys 0m0.023s

(the four numbers are left, top, width, height of the area to be cropped from wtc.png and written to x.jpg)

But a 100x100 pixel region from near the bottom is rather slow, since it has to read and decompress the pixels before the pixels you want to get to the right point in the file:

$ time vips crop wtc.png x.jpg 0 9000 100 100
real    0m3.063s
user    0m2.884s
sys 0m0.181s

JPG and strip TIFF work in the same way, though it's less obvious since they are much faster formats.

Some formats support true random-access read. For example, tiled TIFF is fast everywhere, since libvips can use libtiff to read only the tiles it needs:

$ 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, tiled OpenEXR, FITS, binary PPM/PGM/PBM, HDR, RAW, Analyze, Matlab and probably some others all support true random access like this.

If you're interested in more detail, there's a chapter in the API docs describing how libvips opens a file:

http://jcupitt.github.io/libvips/API/current/How-it-opens-files.md.html

Here's crop plus save in Python using pyvips:

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)

The access= is a flag that hints to libvips that it's OK to stream this image, in case the underlying file format does not support random access. You don't need this for formats that do support random access, like tiled TIFF.

You don't need to write to a file. For example, this will write to a MIME type on stdout:

tile.jpegsave_mime(Q=85)

Or this will make a buffer object containing the file encoded as a JPG:

buffer = tile.write_to_buffer('.jpg', Q=85)

The Q=85 is an optional argument to set the JPG Q factor. You can set any of the file save options.




回答2:


ITK can do it with some formats. There is a method CanStreamRead which returns true for formats which support streaming, such as MetaImageIO. An example can be found here. You can ask more detailed questions on ITK's forum.




回答3:


If have control over the file format, I would suggest you use tiled TIFF files. These are typically used in digital pathology whole slide images, with average sizes of 100kx30k pixels or so.

LibTiff makes it easy to read the tiles corresponding to a selected ROI. Tiles can be compressed without making it less efficient to read a small region (no need to decode whole scan lines).




回答4:


The BMP format (uncompressed) is simple enough that you can write the function yourself.

TIFF is a little less easy, as there are so many subformats. But the TIFF library (TIFFlib) supports a "tile-oriented" I/O mode. http://www.libtiff.org/libtiff.html#Tiles




回答5:


I don't know of such a library solution.
Low level, file-read access is format specific and in particular, file mapping is OS specific.

If you have access to the raw bytes then assuming you know the width, height, depth and number of channels etc. then calculating file offsets is trivial so just roll your own.

If you're transferring the extracted data over a network you might consider compressing the extracted ROI in-memory if it's relatively big before sending it over the network.



来源:https://stackoverflow.com/questions/48281086/extracting-a-region-of-interest-from-an-image-file-without-reading-the-entire-im

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!