如何为 H5 配置 maxshape 参数并附加到文件?

How to configure maxshape argument for H5 and append to file?

我正在尝试将图像数据集合并到 H5 文件中。到目前为止,我已经设法创建了文件,但是当我附加到它时,它只是覆盖了已经存在的内容。我查看了其他答案(例如 )并尝试了他们的变体,但无济于事。

for i in range(len(files)):
    if i == 0:
        with h5py.File('input_images.h5', 'w') as f:
            img = np.array(Image.open(files[i]))
            f.create_dataset('/array', data = img, maxshape = (None), chunks = True, dtype = img.dtype)
    else:
        with h5py.File('input_images.h5', 'r+') as f:
            img = np.array(Image.open(files[i]))
            f.require_dataset('/array', data = img, shape = img.shape, dtype = img.dtype)
    print(i)

我尝试将 maxshape 设置为 (None, None, None),但这只会产生错误:ValueError: "maxshape" must have same rank as dataset shape

总共有 1000 张图片,每张图片的形状都是 2048 x 2048。谁能告诉我如何修改我的代码?

使用 maxshape 参数可以修改数据集大小。请注意,maxshape 需要匹配图像数据集的尺寸。您输入了 1 个维度,但所有图像数据(1000、2048、2048)都需要 3 个维度。此外,代码中的初始数据集大小是根据 data=img 数组大小设置的。它将具有形状 (2048,2048)。数据集需要所有图像数据的第三维。
加载所有图像数据的方法有 3 种:
1. 将 shape=(nfiles,a1,a2) 设置为所有图像的初始大小。除非您稍后想添加更多图片,否则无需调整大小。
2. 最初设置 shape=(1,a1,a2)(1 张图像),然后使用 .resize() 来增加图像的大小。随着数据集的增长,此方法效率不高。
3.初始设置shape=(N,a1,a2)(对于N张图片),然后使用.resize() 当数据集已满时,将大小增加 N。 (N 可以是任何数字。我在下面的示例中使用了 10,但您可以在实际应用中使用 100 或 1000)。

所有 3 种方法都在下面的示例中用于 30 张图像,图像尺寸较小。我为图像创建随机整数数据。将文件的 np.random.randint() 替换为 np.array(Image.open(files[i]))

示例演示了该过程。请注意,方法 1 和 2 仅在您创建 HDF5 文件并填充图像数据时有效(因为数据集索引与图像计数器相同)。方法 3 显示了如何增量添加数据。它使用一个属性来计算加载的图像数量。计数器设置添加新图像的位置。它还用于检查当前数据集大小(并根据需要调整大小)。

在生产代码中,您需要额外检查图像大小和形状是否与数据集大小和形状匹配。

import h5py
import numpy as np
nfiles=30
a0 = nfiles  # for number of images
a1= 256 ; a2 = 256 # for image size

with h5py.File('input_images1.h5', 'w') as f:    
    for i in range(nfiles):
        img_arr = np.random.randint(0,254, (a1, a2), int)
        if i == 0:
            img_ds = f.create_dataset('/array', shape=(a0,a1,a2), 
                             maxshape = (None,a1,a2), chunks = True)
        f['/array'][i,:,:]=img_arr
        print(i)

with h5py.File('input_images2.h5', 'w') as f:    
    for i in range(nfiles):
        img_arr = np.random.randint(0,254, (a1, a2), int)
        if i == 0:
            img_ds = f.create_dataset('/array', shape=(1,a1,a2), 
                             maxshape = (None,a1,a2), chunks = True)
        else:
            f['/array'].resize(i+1,axis=0)
        f['/array'][i,:,:]=img_arr
        print(i)        

with h5py.File('input_images3.h5', 'a') as f:
    for i in range(nfiles):
        img_arr = np.random.randint(0,254, (a1, a2), int)
        if 'array' not in f.keys() :
            img_ds = f.create_dataset('/array', shape=(10,a1,a2), 
                             maxshape = (None,a1,a2), chunks = True)
            img_ds.attrs['n_images'] = 0
        else:
            img_ds = f['/array']

        n_images = img_ds.attrs['n_images']
        if n_images == img_ds.shape[0] :
            print ('adding 10 rows to /array')
            img_ds .resize(img_ds.shape[0]+10,axis=0)

        img_ds[n_images,:,:]=img_arr
        img_ds.attrs['n_images'] = n_images+1
        print(img_ds.attrs['n_images'])