我有27GB的2D tiff文件,用于表示3D图像电影的切片。我希望能够将这些数据切片,就像它是一个简单的numpy4d数组一样。看起来dask.array是一个很好的工具,可以在数组作为hdf5文件存储在内存中时干净地操作它。
如果这些文件并非全部适合内存,我怎么能首先将这些文件存储为hdf5文件。我是h5.py和数据库的新手。
感谢。
答案 0 :(得分:4)
dask.array
' imread
功能从dask 0.7.0
开始,您不需要将图像存储在HDF5中。请直接使用imread
功能:
In [1]: from skimage.io import imread
In [2]: im = imread('foo.1.tiff')
In [3]: im.shape
Out[3]: (5, 5, 3)
In [4]: ls foo.*.tiff
foo.1.tiff foo.2.tiff foo.3.tiff foo.4.tiff
In [5]: from dask.array.image import imread
In [6]: im = imread('foo.*.tiff')
In [7]: im.shape
Out[7]: (4, 5, 5, 3)
数据摄取通常是最棘手的问题。 Dask.array没有与图像文件的任何自动集成(尽管如果有足够的兴趣,这是非常可行的。)幸运的是,将数据移动到h5py
很容易,因为h5py
支持numpy切片语法。在下面的示例中,我们将创建一个空的h5py数据集,然后在for循环中将四个微小的tiff文件存储到该数据集中。
首先我们获取图像的文件名(请原谅玩具数据集。我没有任何现实的东西。)
In [1]: from glob import glob
In [2]: filenames = sorted(glob('foo.*.tiff'))
In [3]: filenames
Out[3]: ['foo.1.tiff', 'foo.2.tiff', 'foo.3.tiff', 'foo.4.tiff']
加载并检查样本图像
In [4]: from skimage.io import imread
In [5]: im = imread(filenames[0]) # a sample image
In [6]: im.shape # tiny image
Out[6]: (5, 5, 3)
In [7]: im.dtype
Out[7]: dtype('int8')
现在,我们将在该文件中制作一个名为'/x'
的HDF5文件和HDF5数据集。
In [8]: import h5py
In [9]: f = h5py.File('myfile.hdf5') # make an hdf5 file
In [10]: out = f.require_dataset('/x', shape=(len(filenames), 5, 5, 3), dtype=im.dtype)
太好了,现在我们可以将我们的图像一次插入到HDF5数据集中。
In [11]: for i, fn in enumerate(filenames):
....: im = imread(fn)
....: out[i, :, :, :] = im
此时dask.array
可以愉快地包裹out
In [12]: import dask.array as da
In [13]: x = da.from_array(out, chunks=(1, 5, 5, 3)) # treat each image as a single chunk
In [14]: x[::2, :, :, 0].mean()
Out[14]: dask.array<x_3, shape=(), chunks=(), dtype=float64>
如果您希望看到更多本机支持图像堆栈,那么我建议您raise an issue。在不通过HDF5的情况下直接使用你的tiff文件堆栈dask.array
非常容易。