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

问题描述 投票:0回答:1

我正在尝试将图像数据集合并为H5文件。到目前为止,我已经设法创建了文件,但是当我追加文件时,它只会覆盖已经存在的文件。我查看了其他答案(例如Adding data to existing h5py file along new axis using h5py),并尝试了其变体,但无济于事。

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 x2048。有人可以告诉我如何修复我的代码吗?

python image numpy h5py
1个回答
1
投票

使用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'])   
© www.soinside.com 2019 - 2024. All rights reserved.