Webカメラで手話をリアルタイム認識させる – ディープラーニング【keras実装】

Python

ディープラーニングでリアルタイム画像認識 – webカメラ

手話数字をWebカメラでリアルタイムで認識させるPythonプログラムです。

ディープラーニングライブラリであるKerasを使いました。中身はTensorFlowで処理されます。

まずは手話数字の画像データをGitからダウンロードしてください。

1~9の手話数字を集めたデータセットです。

手話画像データ: Sign-Language-Digits-Dataset – GitHub

学習モデルの作成 – Keras実装

次にPythonコードを書いていきます。sign_language.pyファイルを作成し、下記のようにニューラルネットワークを記述していきます。

#coding: utf-8
import keras
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers.convolutional import MaxPooling2D
from keras.layers import Activation, Conv2D, Flatten, Dense,Dropout
from sklearn.model_selection import train_test_split
from keras.optimizers import SGD, Adadelta, Adagrad, Adam, Adamax, RMSprop, Nadam
from PIL import Image
import numpy as np
import glob
import matplotlib.pyplot as plt
import time
import os
from sklearn.metrics import confusion_matrix
from keras.preprocessing.image import load_img, img_to_array, ImageDataGenerator

img_size = 100

categories = ['0', '1','2', '3', '4', '5', '6', '7', '8', '9']

dense_size = len(categories)
print(dense_size)
X = []
Y = []

allfiles = []

for index, cat in enumerate(categories):
        #print(index,cat)
        files = glob.glob('Sign-Language-Digits-Dataset-master/Dataset/'+cat+'/*.JPG')
        print(files)
        for f in files:
                img = img_to_array(load_img(f,color_mode='rgb', target_size=(img_size, img_size)))
                
                X.append(img)
                Y.append(index)

X = np.asarray(X)
Y = np.asarray(Y)
X = X.astype('float32')/255.0
Y = np_utils.to_categorical(Y, dense_size)

X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.2, random_state=1)
print(y_test)

model = Sequential()

model.add(Conv2D(100, (3, 3), padding='same',input_shape=X_train.shape[1:]))
model.add(Activation('relu'))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Conv2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(dense_size))
model.add(Activation('softmax'))

model.summary()

epochs = 100
batch_size = 100
model.compile(loss='categorical_crossentropy', optimizer='Adam', metrics=['accuracy'])
history = model.fit(X_train, y_train, batch_size = batch_size, epochs=epochs, validation_data = (X_test, y_test))


plt.subplot(2,1,1)
plt.plot(range(epochs), history.history['acc'], label='acc')
plt.plot(range(epochs), history.history['val_acc'], label='val_acc')
plt.title('model accuracy')
plt.xlabel('epoch')
plt.ylabel('accuracy')
plt.legend(loc='center left', bbox_to_anchor=(1,0.5))

plt.subplot(2,1,2)
plt.plot(range(epochs), history.history['loss'], label='loss')
plt.plot(range(epochs), history.history['val_loss'], label='val_loss')
plt.title('model loss')
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(loc='center left', bbox_to_anchor=(1,0.5))
plt.show()

predict_classes = model.predict_classes(X_test)
prob = model.predict_proba(X_test)

model.save('sign_language.hdf5')

predict_classes = model.predict_classes(X_test, batch_size=5)
true_classes = np.argmax(y_test,1)

print(confusion_matrix(true_classes, predict_classes))

print(model.evaluate(X_test, y_test))

このPythonスクリプトを実行し、model.save(‘sign_language.hdf5’)でフォルダ内にsign_language.hdf5というファイルを作ります。

このファイルにはディープラーニングで手話画像を学習させたときのモデルが保存されています。

実行コマンドです。

python sign_language.py

学習には時間がかかりますが気長に待ちましょう。

Webカメラで撮影、リアルタイム分類

次にパソコンのWebカメラで撮影した映像をリアルタイムで分類します。

camera.pyを作成し、下記のようにpythonコードを記述します。

from keras.preprocessing import image
from keras.applications.inception_v3 import preprocess_input, decode_predictions, InceptionV3
import numpy as np
import cv2
from keras.models import load_model
from PIL import Image
import matplotlib.pyplot as plt
import glob
if __name__ == '__main__':
    model = load_model('sign_language.hdf5')
    categories = ['0', '1','2', '3', '4', '5', '6', '7', '8', '9']
    fig, ax = plt.subplots(2,5)
    files = glob.glob('Sign-Language-Digits-Dataset-master/Examples/*.JPG')
    for i, f in enumerate(files):
        ax = fig.add_subplot(2, 5, i+1)
        pic = Image.open(f)
        ax.imshow(pic)
        ax.set_title(str(i))
    plt.show() 
   
    cam = cv2.VideoCapture(0)
    count = 0
    while True:
        ret, capture = cam.read()
        if not ret:
            print('error')
            break
        cv2.imshow('tensorflow-pi inspector', capture)
        key = cv2.waitKey(33)
        if key == 27:
            break

        count += 1
        if count == 30:
            img = capture.copy()
            img = cv2.resize(img, (100, 100))
            x = image.img_to_array(img)
            x = np.expand_dims(x, axis=0)
            x = np.asarray(x)
            x = x / 255.0

            prob = model.predict_proba(x)
            print('Predicted:')
            print(prob)
            classes = model.predict_classes(x)
            print(classes)
            count = 0

    cam.release()
    cv2.destroyAllWindows()

Webカメラをセットし、下記コマンドで実行します。

python camera.py

パソコンにカメラが複数接続されている場合、どのカメラで撮影するかを選択する必要があります。

cam = cv2.VideoCapture(0)

の箇所を

cam = cv2.VideoCapture(1)

とすることで対応可能です。

ESCキーで終了します。

まとめ

webカメラで手話数字の画像をリアルタイム認識させるpythonプログラムでした。

手話数字の他にも、自分の好きな画像を用意して分類すると楽しいです。

また、ネットワークモデルをカスタマイズすると認識精度が向上するので挑戦してみてください。

ディープラーニングラーニングについて理解を深めたい方はゼロから作るDeep Learningをおすすめします。

コメント

タイトルとURLをコピーしました