2017-06-14 11 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メガバイトを消費しますが、img.hdf5img.pickleサイズは両方1.3ギガバイトです。

これはなぜ発生するのでしょうか?この場合、画像データをピクルスファイルまたはhdf5ファイルに保存するのではなく、個々の画像ファイルに直接保存する方がよいでしょうか?

+1

BLOSCは可逆圧縮ですので、ファイルサイズが大きくなっています。 HDF5は、メタデータ情報を格納するので、常に少し大きくなります。 HDF5の主な利点は、必ずしもディスクスペースではなく、構造データを保存することです。 – user1767754

+0

jpg形式は、すでに損失の多い圧縮ファイルです。より多くの情報を失うことがない限り、サイズをさらに減らすことは難しいでしょう。 –

+1

jpegイメージは、テーブルとして書き込むのではなく、バイナリとして保存できます。 – user1767754

答えて

0

更新: 問題は圧縮が全く適用されないことです。まず、チャンクを作成する必要があります。これは、「create_array」を「create_carray」に置き換えることで実現できます。次に、 "zlib"を補完5で適用すると、すでに改善が見られるはずです。この特定のケースでは、もちろん、繰り返されるデータ軸に沿ってチャンクを設定するのが理にかなっているので、chunkshape=[100,100,100,3]のようなものをcreate_carrayコマンドに追加すると大きな変化が見られるはずです。

Jpegは、高効率なロッシー圧縮アルゴリズムです。 Bloscはスピードに最適化されており、デフォルトでピクルスは圧縮されません。 HDF5の他のオプションもあります。https://support.hdfgroup.org/services/filters.htmlをご覧ください。オリジナルのjpegに近い方法が見つかると思います。

+0

彼はまだHDF5データツリー内でJPEG圧縮を使用できますが、テーブルとして保存してBLOSCしています。そして、イメージをテーブルに変換し、テキストベースの圧縮を適用することで、より良い圧縮を実現できるとは思いません。 – user1767754

関連する問題