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

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

ただいまの
回答率

88.91%

pythonでのValueError

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 239

huton

score 22

質問内容

pythonでopencvと学習済みモデルを使ってカメラの映像で画像認識を行いたいと考えていて、以下のサイト(リンク内容)を参考にプログラムを実行してみたのですが、次元に関するエラーが出てきてしまいどこを直せばいいのかよくわかりません。どこをどのように直せばいいのでしょうか?

ソースコード

学習済みモデルのソースコード

import seaborn as sns
from keras import models
from keras import layers
from keras import optimizers
from pandas import Series,DataFrame
from keras.utils import to_categorical
from keras.optimizers import RMSprop
from keras.preprocessing.image import ImageDataGenerator
from sklearn.preprocessing import LabelBinarizer

#csv読み込み
sign_train = pd.read_csv("sign_mnist_train.csv",sep=",")
sign_test = pd.read_csv("sign_mnist_test.csv",sep=",")
lb=LabelBinarizer()

#特訓データ
train_data=sign_train.drop(['label'],axis=1)
train_data = train_data.values.reshape(-1,28,28,1)
train_data=train_data.astype('float32')/255

train_label=sign_train['label']
train_label=lb.fit_transform(train_label)

#テストデータ
test_data=sign_test.drop(['label'],axis=1)
test_data = test_data.values.reshape(-1,28,28,1)
test_data=test_data.astype('float32')/255

test_label=sign_test['label']
test_label=lb.fit_transform(test_label)

#モデル
model=models.Sequential()
model.add(layers.Conv2D(32,(3,3),activation='relu',input_shape=(28,28,1)))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(64,(3,3),activation='relu'))
model.add(layers.MaxPooling2D((2,2)))
model.add(layers.Conv2D(64,(3,3),activation='relu'))

model.add(layers.Flatten())
model.add(layers.Dense(64,activation='relu'))
model.add(layers.Dropout(0.1))
model.add(layers.Dense(64,activation='relu'))
model.add(layers.Dropout(0.1))
model.add(layers.Dense(24,activation='softmax'))

#学習の取り決め
model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['acc'])

#学習
history=model.fit(train_data,train_label,epochs=20,batch_size=200,validation_data=(test_data,test_label))


acc=history.history['acc']

val_acc=history.history['val_acc']
epochs=range(1,len(acc) +1)
plt.plot(epochs,acc,'bo',label='Train accuracy')
plt.plot(epochs,val_acc,'b',label='Test accuracy')
plt.title('Train and Test accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.show()

results=model.evaluate(test_data,test_label)
print(results)

#with open('model.pickle', mode='wb') as f:
 #   pickle.dump(model, f)
model.save("sign.h5")


エラーが発生したソースコード
エラーの発生した行に(*)と書きました。

from keras.models import load_model
import numpy as np
import cv2

# カメラから画像を取得して,リアルタイムに手書き数字を判別させる。
# 動画表示
cap = cv2.VideoCapture(0)

model = load_model("sign.h5") # 学習済みモデルをロード

# 無限ループ
while(True):

    # 判定用データの初期化
    Xt = []
    Yt = []

    ret, frame = cap.read()

    # 画像のサイズを取得,表示。グレースケールの場合,shape[:2]
    h, w, _ = frame.shape[:3]

    # 画像の中心点を計算
    w_center = w//2
    h_center = h//2

    # 画像の真ん中に142×142サイズの四角を描く
    cv2.rectangle(frame, (w_center-71, h_center-71), (w_center+71, h_center+71),(255, 0, 0))

    # カメラ画像の整形
    im = frame[h_center-70:h_center+70, w_center-70:w_center+70] # トリミング
    im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) # グレースケールに変換
    _, th = cv2.threshold(im, 0, 255, cv2.THRESH_OTSU) # 2値化
    th = cv2.bitwise_not(th) # 白黒反転
    th = cv2.GaussianBlur(th,(9,9), 0) # ガウスブラーをかけて補間
    th = cv2.resize(th,(28, 28), cv2.INTER_CUBIC) # 訓練データと同じサイズに整形

    Xt.append(th)
    Xt = np.array(Xt)/255

(*) result = model.predict(Xt, batch_size=1) # 判定,ソート
    for i in range(24):
        r = round(result[0,i], 2)
        Yt.append([i, r])
        Yt = sorted(Yt, key=lambda x:(x[1]))

    # 判定結果を上位3番目まで表示させる
    cv2.putText(frame, "1:"+str(Yt[9]), (10,80), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255,255,255), 1, cv2.LINE_AA)
    cv2.putText(frame, "2:"+str(Yt[8]), (10,110), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255,255,255), 1, cv2.LINE_AA)
    cv2.putText(frame, "3:"+str(Yt[7]), (10,140), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255,255,255), 1, cv2.LINE_AA)

    cv2.imshow("frame",frame) # カメラ画像を表示

    k =  cv2.waitKey(1) & 0xFF # キーが押下されるのを待つ。1秒置き。64ビットマシンの場合,& 0xFFが必要
    prop_val = cv2.getWindowProperty("frame", cv2.WND_PROP_ASPECT_RATIO) # アスペクト比を取得

    if k == ord("q") or (prop_val < 0): # 終了処理
        break

cap.release() # カメラを解放
cv2.destroyAllWindows() # ウィンドウを消す


エラーメッセージ

Traceback (most recent call last):
  File "kamera.py", line41, in <module> 
    result = model.predict(Xt, batch_size=1) # 判定,ソート
  File "C:\Users\(ユーザー名)\anaconda3\lib\site-packages\keras\engine\training.py", line 1441, in predict
    x, _, _ =self._standardize_user_data(x)
  File "C:\Users\(ユーザー名)\anaconda3\lib\site-packages\keras\engine\training.py", line 579, in _standardize_user_data
    exception_prefix='input')
  File "C:\Users\(ユーザー名)\anaconda3\lib\site-packages\keras\engine\training_utils.py", line 135, in standardize_input_data
    'with shape ' + str(data_shape))
ValueError: Error when checking input: expected conv2d_1_input to have 4 dimension, but got array with shape (1,28,28)
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • can110

    2020/07/12 20:24

    エラーが発生するソースコードはどれでしょうか?
    また、エラーには問題解決のヒントとなる情報が含まれていますので全文(Traceback)を記載ください。

    キャンセル

  • huton

    2020/07/12 21:17

    質問内容が曖昧で申し訳ありませんでした。
    変更しました。

    キャンセル

回答 1

checkベストアンサー

+1

参考にされているコードでのモデル作成コードがOpenCV+Kerasで手書き数字認識を試してみる その4 学習モデルのアップグレードに記載されていますが
model.add(Reshape((28,28,1), input_shape=(28,28)))と入力画像のshapeが(28,28)です。
一方提示コードではmodel.add(layers.Conv2D(32,(3,3),activation='relu',input_shape=(28,28,1)))(28,28,1)となっています。

実際に動作は確認できていませんが、入力画像th(28, 28)になっていると思われます。
であるならば提示エラーが発生します。

以上より、th(28, 28, 1)と白黒プレーン(1)を持つようにreshapeすれば動作すると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/12 22:42

    th = cv2.resize(th,(28, 28), cv2.INTER_CUBIC)の下に
    th = th.reshape(28,28,1)を追加したら動きました!
    ありがとうございます!

    キャンセル

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

  • ただいまの回答率 88.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る