3

Kaggle で CIFAR チャレンジを行っています。

彼らは列車として 5 万枚の写真を含む .7z ファイルを提供しました。解凍するのに 1 時間かかり、すべてのファイルを読み取ってメモリに入れるのにさらに 40 分かかりました。

これがボトルネックであるため、50k ファイルを作成しないようにしています。私は pylzma と他のライブラリをインストールしましたが、ファイルが無効であることがわかります。

bash の 7z は、ファイルを適切に読み取り、ファイルを一覧表示できます。そこでPopen、bash 7z プログラムを使用して、すべてのファイルを解凍し、メモリ内の文字列に配置するために使用しました。

import subprocess
p = subprocess.Popen(["7z", "e", "-so", "awa.7z"], stdout=subprocess.PIPE).communicate()[0]

サイズを確認し、文字列から適切なバイトを取得することで、各ファイルを個別に取得することができました

f1 = p[0][0:2105]

私が今欲しいのは、F1 ファイル ポインターと考えるように Python をトリックすることです。これにより、skimage.io.imread を呼び出すことができ、適切な構造に変換されます。または、メモリ値を skimage に渡すだけで、それが変換されます。

4

3 に答える 3

9

skimage.io.imread のドキュメントには、最初のパラメーターはファイル名の文字列であると書かれていますが、ファイルのようなオブジェクトも受け入れることがわかりました (バージョン 0.10.0 の skimage を使用)。

したがって、次のように画像データをメモリに読み込むことができます。

from StringIO import StringIO

with open(filename) as f:
    img_data = f.read()
decoded_img_data = skimage.io.imread(StringIO(img_data))
print decoded_img_data

>> OUTPUT:
array([[[235, 230, 234],
        [233, 228, 232],
        [231, 226, 230],
        ...,
于 2014-09-05T09:14:11.980 に答える
2

の最初のパラメーターskimage.io.imread()は、読み取るイメージ ファイルの名前であるため、文字列に保持されているイメージ データを使用してそれをだますことはできません。オプション (便宜上):

  • imreadパッケージを直接使用してください - を参照してくださいimread.imread_from_blob()numpy.ndarrayこれは(と同じ) を返しますskimage.io.imread。これは 2 番目の引数として渡す必要があるため、画像ファイルの種類 (jpg、png、gif など) を知る必要があります。

    from imread import imread_from_blob
    img_data = imread_from_blob(f1, 'jpg')
    
    >>> img_data
    array([[[ 23, 123, 149],
    [ 22, 120, 147],
    [ 22, 118, 143],
    ...,
    etc.
    
  • データを一時ファイルに書き込み、その一時ファイルを で開きますimread()imread()URL を処理するときにこれを行います。

  • 名前付きパイプを使用します。で読み取り用にパイプを開き、パイプにimread()データを書き込みます。これを行うには、スレッドまたはマルチプロセッシングが必要になる場合があります。
于 2014-08-30T13:51:33.393 に答える
1

skimage コードを参照すると、別の画像ライブラリである PIL と統合できることがわかりました。そのライブラリには、開いているファイル ポインターから画像情報を直接取得する機能があります。

私の場合、ファイル ポインターは StringIO であるため、データを読み取り、それが何であるかを識別できます。

マーホーク、助けてくれてありがとう。あなたのソリューションもうまくいくように思えますが、画像データ自体を扱いたくありません。

コードを github に入れました (これは単なるスケルトンですが、機能しています)。興味のある方は、ファンシー ページ http://adrianow.github.io/7z_on_array/にアクセスしてください。

ソリューションの短い部分の下:

import numpy as np
from PIL import Image
from StringIO import StringIO

# begin and end of each file
low = 0
up = 0
images = [0] *len(p_f_list)

# get each file from the byte file
for i, f in enumerate(p_f_list):
    up += int(f[0])
    # get bytes from the array
    raw_img = p_f_data.data[low:up]
    low = up

    # Convert rawImage to Mat
    pil_image = Image.open(StringIO(raw_img))
    np_image = np.array(pil_image)
    images[i] = np_image
于 2014-08-31T09:36:41.813 に答える