ブログ 備忘録

データセットを作成する関数を自作した

自分で撮影した画像を使って簡単にデータセットが作成できる関数を作成しましたので、備忘録として残す意味で記事として書き残しておきたいと思います。

コード全体

プログラムコードを示します。コメントとして使用方法と説明を大まかに記載しました。

# -*- coding: utf-8 -*-

"""
・関数の大まかな説明
画像データを読み込みNumPy配列として格納し、教師信号として数字を割り当てます。
・引数
 画像データが格納されているファイルのpath
 クラスに対応する数値
(例) じゃんけんの画像データセットを作成
1.「じゃんけん」フォルダを作成する。
2.「じゃんけん」フォルダの直下に、「グー」、「チョキ」、「パー」の3つのフォルダを作成する。
3.グー・チョキ・パーの画像を撮影し、対応するフォルダ内部に格納する。
4.3つのクラスの番号を0, 1, 2にしたいので、target = [0, 1, 2]とする。
5.data = make_dataset("「じゃんけん」フォルダのpath", target)
"""

import numpy as np
import glob              #フォルダの中身のリストを得ることができる
from PIL import Image    #画像データを読み込むときに使用する

#globでファイルイストを得るためにpathへ'*'を追加する。
def add_ast(pa):
    if pa[-1] == '/':
        pa += '*'
    elif pa[-1] == '\ ':
        pa += '*'
    elif pa[-1] != '*':
        pa += '/*'
    return(pa)

#データセットの作成をする関数の定義
def make_dataset(pa, ta): #paはpath、taはtarget
    data = []
    target = []
    pa = add_ast(pa)
    folder_list = glob.glob(pa)    #各クラスごとの画像が格納されているフォルダのpathをリストとして取得
    for i in range(len(ta)):
        img_path = glob.glob(add_ast(folder_list[i]))
        for j in range(len(img_path)):
            data.append(np.asarray(Image.open(img_path[0])))    #画像データをndarrayオブジェクトにしてリストに追加
            target.append(ta[i])                                #クラス番号を追加

    #画像データをすべて格納できたらリストをndarrayオブジェクトにする
    data = np.array(data)
    target = np.array(target)
    return(data, target)

これを、make_dataset.pyとして保存することで、

from make_dataset import make_dataset

のように読み込むことができます。

使用方法

ここでは、じゃんけんデータセットを作成する例を使って使用方法を示します。以下のようなディレクトリ構造でフォルダを作成し、自身で撮影したグー、チョキ、パーの画像を適切なフォルダに保存します。

図1 作成したフォルダーの位置関係

ちなみに、上記のようなディレクトリ構造でなくても問題ないですが、作成したいデータセットの名前のフォルダを作成し、その中に、各クラスの名前のフォルダを作成すると理解しやすいでしょう。保存する画像ファイルの名前は以降の作業に全く影響は与えないので、変更する必要はありません。

ここまで準備が整ったら、「じゃんけんデータ」フォルダのpathをコピーします。pathは、\\か/で区切られたものにしてください。図1の例であれば、

C:/Users/User/じゃんけんデータ
C:\\Users\\User\\じゃんけんデータ

です。つぎに、各クラスに与える番号を決めます。今回はグーチョキパーの3種類なので、0, 1, 2と番号を割り当てることにしました。これにより、以下のコード

data, target = make_dataset('C:/Users/User/じゃんけんデータ', [0,1,2]) 

を実行することで、MNISTやCIFAR 10のようなデータセットと同様に扱うことができる形になります。

今回の例では、dataは

array([[[[171, 167, 166],
         [169, 165, 164],
         [178, 174, 175],
         ...,
         [198, 193, 189],
         [199, 194, 190],
         [199, 194, 190]],

        [[ 48,  49,  54],
         [ 46,  47,  52],
         [ 53,  54,  59],
         ...,
         [ 22,  38,  64],
         [ 92, 108, 133],
         [ 21,  39,  61]]],

       [[[ 72,  49,  41],
         [ 83,  63,  56],
         [ 94,  75,  69],
         ...,
         [ 96,  61,  55],
         [ 96,  59,  53],
         [ 95,  56,  51]],

        [[ 48,  49,  54],
         [ 46,  47,  52],
         [ 53,  54,  59],
         ...,
         [ 22,  38,  64],
         [ 92, 108, 133],
         [ 21,  39,  61]]]], dtype=uint8)

targetは

array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2])

になりました。この関数があれば、適切なフォルダを作成し、そこに画像を保存するだけで、上記の例のように学習データセットを得ることができます。

追加

今回のプログラムは教師信号として1次元の数値を使用しましたが、直接OneHot表現を出力するよう改造するとより便利になると思いますので、ぜひ自分の使用ようとにカスタマイズして使用していただければと思います。

  • この記事を書いた人
管理人

管理人

このサイトの管理人です。 人工知能や脳科学、ロボットなど幅広い領域に興味をもっています。 将来の目標は、人間のような高度な身体と知能をもったパーソナルロボットを開発することです。 最近は、ロボット開発と強化学習の勉強に力を入れています(NOW)。

-ブログ, 備忘録

PAGE TOP