如何为 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'])
我正在尝试将图像数据集合并到 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'])