質問内容
私はkaggleにあったSign Language MNIST(jとzを除いたa~yの24個のアルファベットの手話のデータセット)をもとに手話の単語を認識するCNNを作成しました。
MNIST学習済みモデルとOpenCVを使ってリアルタイムに手書き数字を認識させるを参考にこの学習済みモデルを使ってカメラの映像に対して画像認識をやりたいと考えているのですが、カメラで写した手話の記号とは異なる結果が表示されてしまいます。
例)
理想 実際
1:[a, 1.0] 1:[k, 1.0]
2:[y, 0.0] ⇒ 2:[y, 0.0]
3:[x, 0.0] 3:[x, 0.0]
以下のソースコードのどこかに間違いがあるのでしょうか?
それとも学習済みモデルがよくないのでしょうか?
ソースコード
学習済みモデル
正解率は90%を超えています。
python
1import keras 2import pickle 3import pandas as pd 4import numpy as np 5import matplotlib.pyplot as plt 6import seaborn as sns 7from keras import models 8from keras import layers 9from keras import optimizers 10from pandas import Series,DataFrame 11from keras.utils import to_categorical 12from keras.optimizers import RMSprop 13from keras.preprocessing.image import ImageDataGenerator 14from sklearn.preprocessing import LabelBinarizer 15 16#csv読み込み 17sign_train = pd.read_csv("sign_mnist_train.csv",sep=",") 18sign_test = pd.read_csv("sign_mnist_test.csv",sep=",") 19lb=LabelBinarizer() 20 21#特訓データ 22train_data=sign_train.drop(['label'],axis=1) 23train_data = train_data.values.reshape(-1,28,28,1) 24train_data=train_data.astype('float32')/255 25 26train_label=sign_train['label'] 27train_label=lb.fit_transform(train_label) 28 29#テストデータ 30test_data=sign_test.drop(['label'],axis=1) 31test_data = test_data.values.reshape(-1,28,28,1) 32test_data=test_data.astype('float32')/255 33 34test_label=sign_test['label'] 35test_label=lb.fit_transform(test_label) 36 37#モデル 38model=models.Sequential() 39model.add(layers.Conv2D(32,(3,3),activation='relu',input_shape=(28,28,1))) 40model.add(layers.MaxPooling2D((2,2))) 41model.add(layers.Conv2D(64,(3,3),activation='relu')) 42model.add(layers.MaxPooling2D((2,2))) 43model.add(layers.Conv2D(64,(3,3),activation='relu')) 44 45model.add(layers.Flatten()) 46model.add(layers.Dense(64,activation='relu')) 47model.add(layers.Dropout(0.1)) 48model.add(layers.Dense(64,activation='relu')) 49model.add(layers.Dropout(0.1)) 50model.add(layers.Dense(24,activation='softmax')) 51 52#学習の取り決め 53model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['acc']) 54 55#学習 56history=model.fit(train_data,train_label,epochs=20,batch_size=200,validation_data=(test_data,test_label)) 57 58#保存 59model.save("sign.h5")
カメラ映像で画像認識を行うプログラム
python
1from keras.models import load_model 2import numpy as np 3import cv2 4 5# カメラから画像を取得して,リアルタイムに手書き数字を判別させる。 6# 動画表示 7cap = cv2.VideoCapture(0) 8 9model = load_model("sign.h5") # 学習済みモデルをロード 10 11# 無限ループ 12while(True): 13 14 # 判定用データの初期化 15 Xt = [] 16 Yt = [] 17 18 ret, frame = cap.read() 19 20 # 画像のサイズを取得,表示。グレースケールの場合,shape[:2] 21 h, w, _ = frame.shape[:3] 22 23 # 画像の中心点を計算 24 w_center = w//2 25 h_center = h//2 26 27 # 画像の真ん中に142×142サイズの四角を描く 28 cv2.rectangle(frame, (w_center-71, h_center-71), (w_center+71, h_center+71),(255, 0, 0)) 29 30 # カメラ画像の整形 31 im = frame[h_center-70:h_center+70, w_center-70:w_center+70] # トリミング 32 im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) # グレースケールに変換 33 _, th = cv2.threshold(im, 0, 255, cv2.THRESH_OTSU) # 2値化 34 th = cv2.bitwise_not(th) # 白黒反転 35 th = cv2.GaussianBlur(th,(9,9), 0) # ガウスブラーをかけて補間 36 th = cv2.resize(th,(28, 28), cv2.INTER_CUBIC) # 訓練データと同じサイズに整形 37 th = th.reshape(28,28,1) 38 39 Xt.append(th) 40 Xt = np.array(Xt)/255 41 42 result = model.predict(Xt, batch_size=1) # 判定,ソート 43 44 ch = ['a','b','c','d','e','f','g','h','i','k','l','m', 45 'n','o','p','q','r','s','t','u','v','w','x','y'] 46 47 for i in range(len(ch)): 48 r = round(result[0,i], 2) 49 Yt.append([ch[i], r]) 50 Yt = sorted(Yt, key=lambda x:(x[1])) 51 52 # 判定結果を上位3番目まで表示させる 53 cv2.putText(frame, "1:"+str(Yt[23]), (10,80), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255,255,0), 1, cv2.LINE_AA) 54 cv2.putText(frame, "2:"+str(Yt[22]), (10,110), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255,0,255), 1, cv2.LINE_AA) 55 cv2.putText(frame, "3:"+str(Yt[21]), (10,140), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0,255,255), 1, cv2.LINE_AA) 56 57 cv2.imshow("frame",frame) # カメラ画像を表示 58 59 k = cv2.waitKey(1) & 0xFF # キーが押下されるのを待つ。1秒置き。64ビットマシンの場合,& 0xFFが必要 60 prop_val = cv2.getWindowProperty("frame", cv2.WND_PROP_ASPECT_RATIO) # アスペクト比を取得 61 62 if k == ord("q") or (prop_val < 0): # 終了処理 63 break 64 65cap.release() # カメラを解放 66cv2.destroyAllWindows() # ウィンドウを消す
回答1件
あなたの回答
tips
プレビュー