2017-06-14 64 views
0

我想保存大量的图像。我想将它们保存为尽可能减少磁盘内存的格式。我已经用python测试过HDF5和cPickle。令人惊讶的是,我发现由PyTables和cPickle生成的数据文件比包含相同数量图像的文件夹大得多。使用HDF5和cPickle保存图像比直接在磁盘中直接存储相同数量的图像文件需要更多的磁盘存储空间?

我的代码是在这里:

import cv2 
import copy 
import cPickle as pickle 
import tables 
import numpy as np 
image = cv2.imread("aloel.jpg") 
images = [] 
for i in xrange(1000): 
    images.append(copy.deepcopy(image)) 
images = np.asarray(images, dtype=np.uint8) 
hdf5_path = "img.hdf5" 
filters = tables.Filters(complevel=5, complib='blosc') 
with tables.open_file(hdf5_path, mode='w', filters=filters) as hdf5_file: 
    data_storage = hdf5_file.create_array(hdf5_file.root, 'data', obj=images) 

with open('img.pickle', 'wb') as f: 
    pickle.dump(images, f, protocol=pickle.HIGHEST_PROTOCOL) 

包含的aloel.jpg 1000个拷贝的文件夹占用61.5 MB,但img.hdf5img.pickle的大小都1.3GB

我想知道为什么会出现这种情况?如果是这样,是否意味着将图像数据直接保存到单个图像文件中而不是将其保存到pickle文件或hdf5文件中会更好?

+1

BLOSC是无损压缩,所以它并不让我感到惊讶,文件的大小更大。因为它存储元数据信息,所以HDF5总是会更大一些。 HDF5的主要优势是存储结构化数据,而不是磁盘空间。 – user1767754

+0

jpg格式已经是一个有损压缩文件。除非你愿意失去更多的信息,否则难以缩小它们的尺寸。 –

+1

您可以将jpeg图像存储为二进制文件,而不是将它们作为表格写入。 – user1767754

回答

0

更新: 你的问题是压缩并没有被应用,因为首先你需要分块,这可以通过将“create_array”替换为“create_carray”来实现。然后,将“zlib”与complevel 5结合使用,您应该已经看到了一些改进。对于这种特殊情况,当然,也可以沿重复的数据轴设置分块,因此如果在create_carray命令中添加类似chunkshape=[100,100,100,3]的东西,则应该看到一个重大更改。

Jpeg是高效的有损压缩算法。 Blosc针对速度进行了优化,默认情况下泡菜根本没有压缩。 HDF5还有其他选择,请看https://support.hdfgroup.org/services/filters.html,我相信你可以找到足够接近原始jpeg的方法。

+0

他仍然可以在HDF5数据树中使用JPEG压缩,但他将它们存储为表并将它们BLOSC'ing。我不认为你可以通过将图像转换成表格并应用基于文本的压缩来实现更好的压缩。 – user1767754