画像分類における画像の拡大の前処理

Caltechデータセットを用いた画像分類における画像の拡大の前処理

画像分類においてはロバストな分類をするために画像に前処理をすることがあります.
画像の移動や色調変化,拡大など様々な前処理が存在します.
画像の拡大はデータのサイズが大きく異なるときに大きな効果を発揮します.
画像の拡大方法について紹介していきます.

データのリファレンスは以下になります.

Caltech 101
L. Fei-Fei, R. Fergus and P. Perona. One-Shot learning of object categories. IEEE Trans. Pattern Recognition and Machine Intelligence. In press.

Required Libaries

  • matplotlib 2.0.2
  • numpy 1.12.1
In [1]:
from renom.utility.distributor import ImageClassificationDistributor
from renom.utility.distributor.imageloader import ImageLoader
from renom.utility.image import *
import matplotlib.pyplot as plt
import numpy as np
import math
import os

画像分類のためのデータ読み込み

画像分類のためにデータを読み込みます.

In [2]:
def load_for_classification(path):
    class_list = os.listdir(path)
    onehot_vectors = []
    for i in range(len(class_list)):
        temp = [0] * len(class_list)
        temp[i] = 1
        onehot_vectors.append(temp)
    X_list = []
    y_list = []
    for classname in class_list:
        imglist = os.listdir(path + classname)
        for filename in imglist:
            filepath = path + classname + "/" + filename
            X_list.append(filepath)
            onehot = onehot_vectors[class_list.index(classname)]
            y_list.append(onehot)

    return X_list, y_list, class_list

ワンホットからクラス名取得

ワンホットベクトルからクラス名を取得します.

In [3]:
def get_class_from_onehot(onehot_vector, class_list):
    return class_list[onehot_vector.index(1)]

画像の表示

バッチサイズを計算して適切なマップサイズを算出
元のデータと加工されたデータを確認することができます.
In [4]:
def imshow_batch(images):
    n_images = images.shape[0]
    images = images.astype(np.uint8)
    map_width = int(math.ceil(math.sqrt(n_images)))
    map_height = int(math.ceil(n_images / map_width))
    for h in range(map_height):
        for w in range(map_width):
            if (w==0) and (h*map_width+w < n_images):
                temp_concatenated_image = images[h*map_width+w]
            elif h*map_width+w < n_images:
                temp_concatenated_image = np.concatenate(
                      (temp_concatenated_image, images[h*map_width+w]), axis=1)
            elif (w==0) and (h*map_width+w >= n_images):
                temp_concatenated_image = np.zeros(
                      images[0].shape, dtype=images[0].dtype)
            else:
                temp_concatenated_image = np.concatenate((temp_concatenated_image, np.zeros(
                         images[0].shape, dtype=images[0].dtype)), axis=1)
        if h==0:
            concatenated_image = temp_concatenated_image
        else:
            concatenated_image = np.concatenate(
                    (concatenated_image, temp_concatenated_image), axis=0)

    fig, ax = plt.subplots(figsize=(15, 15))
    ax.imshow(concatenated_image)
    plt.axis("off")
    plt.tight_layout()
    plt.show()

データの読み込みとラベルデータの読み込み

ディレクトリ名にしたがってワンホットのラベルデータを作成します.

Zoom(zoom_rate=(1.5)),
上記が画像の拡大を行う箇所になります.
拡大率は1からzoom rateで指定された値までの値からランダムに選ばれます.
In [5]:
path = "101_ObjectCategories/"
X_list, Y_list, class_list = load_for_classification(path)

augmentation = DataAugmentation([\
                 Zoom(zoom_rate=(1.5)),
                 ],
                 random = True)
distributer = ImageClassificationDistributor(image_path_list=X_list,
                                             y_list = Y_list,
                                             class_list = class_list,
                                             imsize=(200, 200),
                                             color="RGB",
                                             augmentation=augmentation)
for (x,y) in distributer.batch(12, shuffle=True):
    for label in y:
        print(get_class_from_onehot(label.tolist(), class_list))
    images = x.transpose((0,2,3,1))
    imshow_batch(x.transpose((0,2,3,1)))
    break
anchor
Motorbikes
wheelchair
ibis
anchor
watch
laptop
umbrella
nautilus
airplanes
grand_piano
bonsai
../../../_images/notebooks_preprocessing_zoom_imageclassification_notebook_10_1.png