将包含 jpeg 图像的文件夹转换为 hdf5
Posted
技术标签:
【中文标题】将包含 jpeg 图像的文件夹转换为 hdf5【英文标题】:Convert a folder comprising jpeg images to hdf5 【发布时间】:2021-07-23 12:03:33 【问题描述】:有没有办法在 Python 中将包含 .jpeg 图像的文件夹转换为 hdf5?我正在尝试建立一个用于图像分类的神经网络模型。谢谢!
【问题讨论】:
简短回答:是的。您必须将图像转换为 NumPy 数组数据(使用 opencv 或其他工具)。你知道怎么做吗? 如果您能提出建议,那就太好了。本质上,如果我可以将文件夹中的每个图像都转换为一个 numpy 数组,那就太好了! 【参考方案1】:有很多方法可以处理和保存图像数据。这是读取 1 个文件夹中的所有图像文件并加载到 HDF5 文件中的方法的 2 种变体。这个过程的概要:
-
计算图像数量(用于确定数据集的大小)。
创建 HDF5 文件(前缀:
1ds_
)
创建具有适当形状和类型(整数)的空数据集
使用glob.iglob()
循环图像。然后做:
阅读cv2.imread()
使用cv2.resize()
调整大小
复制到数据集img_ds[cnt:cnt+1:,:,:]
这是一种方法。需要考虑的其他事项:
-
我在 1 个数据集中加载了所有图像。如果您有不同大小的图像,则必须调整图像大小。如果您不想调整大小,则需要将每个图像保存在不同的数据集中(相同的过程,但在循环内创建一个新数据集)。查看第二个
with/as:
并循环将数据保存到第二个 HDF5(前缀:nds_
)
我没有尝试捕获图像名称。您可以使用 1 个数据集上的属性来执行此操作,或者作为具有多个数据集的数据集名称。
我的图片是.ppm
文件,所以需要修改glob函数为
使用*.jpg
。
以下更简单的版本(2021 年 3 月 16 日添加): 假设所有文件都在当前文件夹中,并将所有调整大小的图像加载到一个数据集(名为“图像”)。第二种方法在不调整大小的情况下将每个图像加载到单独的数据集中,请参见前面的代码。
import sys
import glob
import h5py
import cv2
IMG_WIDTH = 30
IMG_HEIGHT = 30
h5file = 'import_images.h5'
nfiles = len(glob.glob('./*.ppm'))
print(f'count of image files nfiles=nfiles')
# resize all images and load into a single dataset
with h5py.File(h5file,'w') as h5f:
img_ds = h5f.create_dataset('images',shape=(nfiles, IMG_WIDTH, IMG_HEIGHT,3), dtype=int)
for cnt, ifile in enumerate(glob.iglob('./*.ppm')) :
img = cv2.imread(ifile, cv2.IMREAD_COLOR)
# or use cv2.IMREAD_GRAYSCALE, cv2.IMREAD_UNCHANGED
img_resize = cv2.resize( img, (IMG_WIDTH, IMG_HEIGHT) )
img_ds[cnt:cnt+1:,:,:] = img_resize
以下之前的代码(从 2021 年 3 月 15 日起):
import sys
import glob
import h5py
import cv2
IMG_WIDTH = 30
IMG_HEIGHT = 30
# Check command-line arguments
if len(sys.argv) != 3:
sys.exit("Usage: python load_images_to_hdf5.py data_directory model.h5")
print ('data_dir =', sys.argv[1])
data_dir = sys.argv[1]
print ('Save model to:', sys.argv[2])
h5file = sys.argv[2]
nfiles = len(glob.glob(data_dir + '/*.ppm'))
print(f'Reading dir: data_dir; nfiles=nfiles')
# resize all images and load into a single dataset
with h5py.File('1ds_'+h5file,'w') as h5f:
img_ds = h5f.create_dataset('images',shape=(nfiles, IMG_WIDTH, IMG_HEIGHT,3), dtype=int)
for cnt, ifile in enumerate(glob.iglob(data_dir + '/*.ppm')) :
img = cv2.imread(ifile, cv2.IMREAD_COLOR)
# or use cv2.IMREAD_GRAYSCALE, cv2.IMREAD_UNCHANGED
img_resize = cv2.resize( img, (IMG_WIDTH, IMG_HEIGHT) )
img_ds[cnt:cnt+1:,:,:] = img_resize
# load each image into a separate dataset (image NOT resized)
with h5py.File('nds_'+h5file,'w') as h5f:
for cnt, ifile in enumerate(glob.iglob(data_dir + '/*.ppm')) :
img = cv2.imread(ifile, cv2.IMREAD_COLOR)
# or use cv2.IMREAD_GRAYSCALE, cv2.IMREAD_UNCHANGED
img_ds = h5f.create_dataset('images_'+f'cnt+1:03', data=img)
【讨论】:
非常感谢!我想调整所有图像的大小并加载到单个数据集中。不过,我有几个问题。我在哪里/如何包含我的文件夹所在的路径?我不是 Python 效率(还),所以很抱歉我的问题很愚蠢。 我重用了一些使用命令行参数的代码。第一个参数是文件所在的文件夹,第二个参数是 HDF5 文件名。这样您就可以从任何目录读取图像并分配 HDF5 文件名和位置。我修改了我的帖子以简化代码并仅加载调整大小的图像。最终你会想让它更通用。【参考方案2】:您可以通过在 Python 中使用 HDFql 执行以下操作来解决您的问题(HDFql 还支持 C、C++、Java、C#、R 和 Fortran):
import HDFql
cursor = HDFql.Cursor()
folder = "/home/dummy/images/"
HDFql.execute("create and use file images.h5")
HDFql.execute("show file \"%s\"" % folder)
while HDFql.cursor_next() == HDFql.SUCCESS:
file = HDFql.cursor_get_char()
print("File found: \"%s\"" % file)
HDFql.cursor_use(cursor)
HDFql.execute("show file size \"%s%s\"" % (folder, file))
HDFql.cursor_next()
size = HDFql.cursor_get_bigint()
HDFql.cursor_use_default()
HDFql.execute("create dataset \"%s\" as opaque(%d) values from binary file \"%s%s\"" % (file, size, (folder, file)))
HDFql.execute("close file")
有关更多信息,请查看说明 HDFql 功能的 reference manual 和 examples。
【讨论】:
以上是关于将包含 jpeg 图像的文件夹转换为 hdf5的主要内容,如果未能解决你的问题,请参考以下文章
如何将画布图像“data:image/jpeg;base64,..”转换为普通图像文件 - javascript
将大量 MP3 文件转换为 YouTube 视频,每个都使用相同的 JPEG 图像