6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

画像コンペのzipファイル内の画像を解凍せずに読み込む

Last updated at Posted at 2021-04-01

データサイエンスの画像コンペでは、画像データがzip形式で圧縮されています。
画像データの数がそんなに多くなければ、zipを解凍して画像を読み込んだりもしますが、大量にある場合はzipのまま、画像データを読み込めればと思い、備忘録的に投稿します。

使うデータはSIGNATEの【練習問題】**画像ラベリング(10種類)**を使います。

【練習問題】画像ラベリング(10種類)

まずは、ライブラリをインポート

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
import zipfile
import io

zipファイル内の画像ファイルを確認

zipファイルのパスを指定して、中身を確認してみます。
with構文を使って**ZipFile()**でzipファイルを読み込み、**infolist()**で読み込んだzipファイル内のすべてのファイル名を取得します。

# zipファイルのパス
zip_path = './data/train_images.zip'

# zipの中身を確認
with zipfile.ZipFile(zip_path, 'r') as zip_file:
    for info in zip_file.infolist():
        print(info)

出力

(......)

<ZipInfo filename='train_images/train_989.jpg' compress_type=deflate external_attr=0x20 file_size=3334 compress_size=3203>
<ZipInfo filename='train_images/train_99.jpg' compress_type=deflate external_attr=0x20 file_size=2873 compress_size=2737>
<ZipInfo filename='train_images/train_990.jpg' compress_type=deflate external_attr=0x20 file_size=2743 compress_size=2606>
<ZipInfo filename='train_images/train_991.jpg' compress_type=deflate external_attr=0x20 file_size=3005 compress_size=2869>
<ZipInfo filename='train_images/train_992.jpg' compress_type=deflate external_attr=0x20 file_size=2031 compress_size=1894>
<ZipInfo filename='train_images/train_993.jpg' compress_type=deflate external_attr=0x20 file_size=3064 compress_size=2910>
<ZipInfo filename='train_images/train_994.jpg' compress_type=deflate external_attr=0x20 file_size=2858 compress_size=2723>
<ZipInfo filename='train_images/train_995.jpg' compress_type=deflate external_attr=0x20 file_size=3016 compress_size=2882>
<ZipInfo filename='train_images/train_996.jpg' compress_type=deflate external_attr=0x20 file_size=2631 compress_size=2495>
<ZipInfo filename='train_images/train_997.jpg' compress_type=deflate external_attr=0x20 file_size=2315 compress_size=2170>
<ZipInfo filename='train_images/train_998.jpg' compress_type=deflate external_attr=0x20 file_size=3012 compress_size=2877>
<ZipInfo filename='train_images/train_999.jpg' compress_type=deflate external_attr=0x20 file_size=2488 compress_size=2348>

zipファイル内の画像ファイルを読み込み

ここで注意したいのは、infolist()をそのままループして読み込むと、ラベルデータのファイル順で読み込むことができません。

(... → train_989 → train_99 → train_990 → train_991 → ...)

必ず画像のラベルデータのファイル順に読み込みます。

というわけでラベルデータを読み込んで中身を確認します。

# ラベルデータの読み込み
train_labels = pd.read_csv('./data/train_master.tsv', sep='\t')
print(train_labels.head())

読み込んだ画像データを格納するリストをあらかじめ作っておき、続いてwith構文を使って**ZipFile()**でzipファイルを読み込みます。

そして、ラベルデータのファイル順にループして読み込み、**zip_file.open()**に対象のファイル名を指定し、img_fileに読み込んでいきます。

対象のファイル名がtrain_images/train_〇〇.jpgとなっているのをすでに確認しているため、train_labels['file_name']の要素(train_〇〇.jpg)をループしてtrain_images/ +iとします。

画像のバイナリデータをIOライブラリの**BytesIO()関数で読み込み、PillowのImage.open()**で開き、Numpy配列に変換したものを格納リストに追加していきます。

# zipの読み込み
with zipfile.ZipFile(zip_path, 'r') as zip_file:
    for i in train_labels['file_name']:
        with zip_file.open('train_images/'+i) as img_file:
            # 画像のバイナリデータを読み込む
            img_bin = io.BytesIO(img_file.read())
            # バイナリデータをPillowで開く
            img = Image.open(img_bin)
            # 画像データを配列化
            img_array = np.array(img)
            # 格納リストに追加
            X_train.append(img_array)

読み込んだ画像データの確認

zipファイルからちゃんと画像データを読み込めたか確認して、さらにラベル名と一致しているか確認していきます。

このデータは画像データのファイル名とラベルIDが対応していて(train_master.tsv)、さらにラベルIDとラベル名が対応(label_master.tsv)しているため、画像データとラベル名を対応させたものを表示させます。

まずはラベルマスタを読み込みます。

# ラベルマスタの読み込み
label_master = pd.read_csv('./data/label_master.tsv', sep='\t')
print(label_master.head())

続いて、ラベルマスタからラベル名を抽出します。

# ラベル名を抽出
labels = label_master['label_name']

以下のコードを実行すると、画像とそれが何を表すのか、40個のサンプルを表示します。

# 画像の確認
plt.figure(figsize=(10,10))
for i in range(0,40):
    plt.subplot(5,8,i+1)
    plt.title(labels[train_labels.iloc[i, 1]]) # train_labelsのラベルID抽出後、IDに対応するラベル名を抽出
    plt.axis('off') # 軸と目盛りをオフ
    plt.imshow(X_train[i])

プログラムを実行すると以下のように表示されます。

image.png

ちゃんと、画像に写っているものと、ラベルが一致しているのが確認できました。

学習に進む場合は、画像を格納したリストをNumpy配列に変換すればOKです。

最終スクリプト

'''
zipファイル内の画像ファイルを確認
'''

# ライブラリのインポート
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
import zipfile
import io

# zipファイルのパス
zip_path = './data/train_images.zip'

# zipの中身を確認
with zipfile.ZipFile(zip_path, 'r') as zip_file:
    for info in zip_file.infolist():
        print(info)

'''
zipファイル内の画像ファイルの読み込み
'''

# ラベルデータの読み込み
train_labels = pd.read_csv('./data/train_master.tsv', sep='\t')
print(train_labels.head())

# 画像データの格納リスト
X_train = [] # 画像のピクセル値とラベルを格納するリストを生成(説明変数)

# zipの読み込み
with zipfile.ZipFile(zip_path, 'r') as zip_file:
    for i in train_labels['file_name']:
        with zip_file.open('train_images/'+i) as img_file:
            # 画像のバイナリデータを読み込む
            img_bin = io.BytesIO(img_file.read())
            # バイナリデータをpillowで開く
            img = Image.open(img_bin)
            # 画像データを配列化
            img_array = np.array(img)
            # 格納リストに追加
            X_train.append(img_array)

# ラベルマスタの読み込み
label_master = pd.read_csv('./data/label_master.tsv', sep='\t')
print(label_master.head())

# ラベル名を抽出
labels = label_master['label_name']

# 画像の確認
plt.figure(figsize=(10,10))
for i in range(0,40):
    plt.subplot(5,8,i+1)
    plt.title(labels[train_labels.iloc[i, 1]]) # train_labelsのラベルID抽出後、IDに対応するラベル名を抽出
    plt.axis('off') # 軸と目盛りをオフ
    plt.imshow(X_train[i])

# np.arrayに変換
X_train = np.array(X_train)
6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?