質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
CNN (Convolutional Neural Network)

CNN (Convolutional Neural Network)は、全結合層のみではなく畳み込み層とプーリング層で構成されるニューラルネットワークです。画像認識において優れた性能を持ち、畳み込みニューラルネットワークとも呼ばれています。

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

567閲覧

カメラの映像に対しての学習済みモデルの判定

huton

総合スコア30

CNN (Convolutional Neural Network)

CNN (Convolutional Neural Network)は、全結合層のみではなく畳み込み層とプーリング層で構成されるニューラルネットワークです。画像認識において優れた性能を持ち、畳み込みニューラルネットワークとも呼ばれています。

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/07/13 01:18

編集2020/07/13 02:27

質問内容

私は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() # ウィンドウを消す

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2020/07/13 01:45 編集

取り組まれている問題はいわゆる「Sign_MNIST」でしょうか? もしそうなら その旨を記載し、学習データ「~.csv」の入手元(DLできるURL)も記載すると第三者も再現でき回答得られやすくなるかと思います。 また、カメラ画像だと正確な結果が得られるとは限らないので、まずは訓練画像でpredictした結果で正しく動作しているか検証すべきかと思います。
huton

2020/07/13 02:29

DLできるURLを追加しました。ありがとうございます。 助言いただいたようにまずは画像で確認してみようと思います。
guest

回答1

0

ベストアンサー

元データに書いてある説明によると

The training data (27,455 cases) and test data (7172 cases) are approximately half the size of the standard MNIST but otherwise similar with a header row of label, pixel1,pixel2….pixel784 which represent a single 28x28 pixel image with grayscale values between 0-255.

とのことなので、グレースケールで訓練されたものと考えられます。
したがって、認識時も2値化までする必要はなく、キャプチャをグレイスケール化&補間した状態で予測関数に渡した方が認識精度は高まるように思われます。
(ガウスブラー補間も不要かもしれません)
(下記のコード変更で、比較的認識しやすいと思われる指文字「C」「V」の精度は良くなりました。
ただし他の文字だと、手への光の当たり具合や背景とのコントラストが訓練データと異なったせいか精度がよくありませんでした)

im = frame[h_center-70:h_center+70, w_center-70:w_center+70] # トリミング im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) # グレースケールに変換 th = cv2.GaussianBlur(im, (9, 9), 0) # ガウスブラーをかけて補間 th = cv2.resize(im, (28, 28), cv2.INTER_CUBIC) # 訓練データと同じサイズに整形 th = th.reshape(28, 28, 1)

追記

2値化する場合でも、白黒反転処理をしないだけで認識精度は高まるように思われます。
(元コードの「 th = cv2.bitwise_not(th) # 白黒反転」だけをコメントアウト)

投稿2020/07/26 05:24

編集2020/07/26 05:29
patapi

総合スコア651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

huton

2020/07/28 03:34

実際にやっていただける方が現れるとは思っていなかったのでとてもありがたいです! 本当にありがとうございます! とても助かりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問