« IIJが20ギガで1880円のプラン | トップページ | 4つのカメラを取り付け可能にするアダプタ「Raspberry Pi用マルチカメラアダプタ」 »

2021年2月27日 (土)

Raspberry Pi × 画像認識 で「後出しじゃんけん機」作ってみた

久しぶりの、Raspberry Piネタです。

今日は、どちらかというと「教育用」なネタです。

Raspberry Piと画像認識を応用した「後出しじゃんけん機」なるものを作ってみました。

なんじゃそら?という名前ですが、簡単に言うと、

(1) グー、チョキ、パー をラズパイカメラで撮影して記録 (各30枚づつくらい)

(2) 上の写真を用いて深層学習(CNN)を実施

(3) できたモデルを使い、カメラで撮影した「手」を推論する

(4) 推論結果に対し、勝つ手の画像を表示する

……という、Raspberry Piを使った一種のAIです。

これ、要するに、身近なもので画像認識AIを体感しよう!って趣旨の工作&プログラムです。

通常なら、Raspberry PiとPCを組み合わせるところですが、この両者の行き来が煩わしいので、学習用のデータ取りから学習、そして推論までを、すべてRaspberry Pi上でできるようにしてます。

まず、準備ですが、以下の3つのコードをコピペして持って行ってください。

「1_camera.py」


import glob
import time
import os
import io

# for Raspberry Pi
import RPi.GPIO as GPIO
import picamera

GPIO.cleanup()

#for Raspberry Pi
GPIO.setmode(GPIO.BCM)
port1 = 17 # gu
port2 = 27 # choki
port3 = 22 # pa

GPIO.setup(port1, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(port2, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(port3, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

count = 1
flag = 0

# File remove
file_list = glob.glob('./data/0_gu/*')
for file in file_list:
    os.remove(file)
file_list = glob.glob('./1_choki/*')
for file in file_list:
    os.remove(file)
file_list = glob.glob('./data/2_pa/*')
for file in file_list:
    os.remove(file)

print('Ready!')

try:
    while True:
        sc = str(count)
        ssc = sc.zfill(4)
        #GPIOの17,27,22がオンになったら、画像を取り込んで認識を開始
        if GPIO.input(port1):
            label = '0_gu'
            flag = 1
        elif GPIO.input(port2):
            label = '1_choki'
            flag = 1
        elif GPIO.input(port3):
            label = '2_pa'
            flag = 1
            
        if flag ==1 :
            print(ssc + ':' + label)
            with picamera.PiCamera() as camera:
                    camera.resolution = (12896)
                    camera.start_preview()
                    camera.capture('./data/'+label+'/'+label+ssc+'.jpg')
            count +=1
            flag = 0

        time.sleep(0.01)

except KeyboardInterrupt:
    GPIO.cleanup()

「2_train.py」


#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import sys
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt

import keras
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense,Dropout,Flatten
from keras.layers import Conv2D,MaxPooling2D
from keras.preprocessing.image import array_to_img,img_to_array,load_img
from keras import backend as K
from sklearn.model_selection import train_test_split
from keras.models import load_model
from keras.callbacks import ModelCheckpoint

# ======= hypter param =====
batch_size = 10
epochs = 50
# ==========================

path=os.getcwd()+'/data/'

class_count = 0
folder_list=os.listdir(path)

for folder in folder_list:

  class_count = class_count+1

NUM_CLASSES = class_count
IMAGE_SIZE = 28

# Loss
def plot_history_loss(fit):
    # Plot the loss in the history
    axL.plot(fit.history['loss'],label="loss for training")
    axL.plot(fit.history['val_loss'],label="loss for validation")
    axL.set_title('model loss')
    axL.set_xlabel('epoch')
    axL.set_ylabel('loss')
    axL.legend(bbox_to_anchor=(10), loc='lower right'borderaxespad=1fontsize=10)

# Accurascy
def plot_history_acc(fit):
    # Plot the loss in the history
    axR.plot(fit.history['acc'],label="loss for training")
    axR.plot(fit.history['val_acc'],label="loss for validation")
    axR.set_title('model accuracy')
    axR.set_xlabel('epoch')
    axR.set_ylabel('accuracy')
    axR.legend(bbox_to_anchor=(11), loc='upper right'borderaxespad=1fontsize=10)

if __name__ == '__main__':

    count=0
    folder_list = sorted(os.listdir(path))

    train_image = []
    train_label = []
    test_image = []
    test_label = []
    X = []
    Y = []

    label = 'label.txt'
    
    f = open(label, 'w')
    for folder in folder_list:
        subfolder = os.path.join(path,folder)
        file_list = sorted(os.listdir(subfolder))

        filemax = 0

        i = 0

        for file in file_list:

            i = i + 1

            img = img_to_array(load_img('./data/' + folder + '/' + file,target_size=(28,28)))
            X.append(img)
            Y.append(count)
        
        label_name = folder + ' ' + str(count) + '\n'
        f.write(label_name)

        count +=1

    X = np.asarray(X)
    Y = np.asarray(Y)
    X = X.astype('float32')
    X = X / 255.0

    Y = np_utils.to_categorical(Y, NUM_CLASSES)

    train_image, test_image, train_label, test_label = train_test_split(X,Y,test_size=0.20)
    
    f.close()
    print(u'画像読み込み終了')

    input_shape = (IMAGE_SIZE, IMAGE_SIZE, 3)

    model = Sequential()
    model.add(Conv2D(32,kernel_size=(3,3),
                     activation='relu',
                     padding='same'
                     input_shape=input_shape))
    model.add(MaxPooling2D(pool_size=(2,2)))

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

    model.add(Flatten())
    model.add(Dense(512activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(NUM_CLASSES, activation='softmax'))

    model.compile(loss=keras.losses.categorical_crossentropy,
                  optimizer=keras.optimizers.Adadelta(),
                  metrics=['accuracy']
                  )

    chkpt = './model_28.h5'
    cp_cb = ModelCheckpoint(filepath = chkpt, monitor='val_loss'verbose=1
                            save_best_only=Truemode='auto')

    history = model.fit(train_image, train_label,
              batch_size=batch_size,
              epochs=epochs,
              verbose=1,
              validation_data=(test_image, test_label),
              callbacks=[cp_cb],
              )

    model.summary()

    score = model.evaluate(test_image, test_label, verbose=0)

    fig, (axL, axR) = plt.subplots(ncols=2figsize=(10,4))

    plot_history_loss(history)
    plot_history_acc(history)

    fig.savefig('./loss_acc.png')
    plt.close()

「3_atdashi.py」


#!/usr/bin/env python

import os
import sys
import numpy as np
import tensorflow as tf

import keras
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense,Dropout,Flatten
from keras.layers import Conv2D,MaxPooling2D
from keras.preprocessing.image import array_to_img,img_to_array,load_img
from keras import backend as K
from sklearn.model_selection import train_test_split
from keras.models import load_model
import time

import RPi.GPIO as GPIO
import picamera

i = 0
label_name = []

label = 'label.txt'

f = open(FLAGS.label,'r')
for line in f:
  line = line.rstrip()
  l = line.rstrip()
  label_name.append(l)
  i = i + 1

NUM_CLASSES = i
IMAGE_SIZE = 28

if __name__ == '__main__':
    test_image = []
    
    # model read
    model = load_model('./model_28.h5')
    model.summary()
    
    # for Raspberry Pi

    GPIO.cleanup()

    #for Raspberry Pi
    GPIO.setmode(GPIO.BCM)
    port1 = 24 # switch

    GPIO.setup(port1, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

    print('Ready!')
    try:
        while True:
            if GPIO.input(port1):
                with picamera.PiCamera() as camera:
                    camera.resolution = (12896)
                    camera.start_preview()
                    camera.capture('./tmp.jpg')
                
                img = img_to_array(load_img('./tmp.jpg' , target_size=(28,28)))
                test_image.append(img)
                test_image = np.asarray(test_image)
                test_image = test_image.astype('float32')
                test_image = test_image / 255.0
    
                predictions = model.predict_classes(test_image)
    
                print(label_name[predictions[0]], u'です。')
                
                test_image = []
            
            time.sleep(0.01)

    except KeyboardInterrupt:
        GPIO.cleanup()

事前に、TensorFlow、Keras、numpyなどのライブラリをpip3コマンドで取り込んでおいてください。

(なお、TensorFlowは1.14、kerasは2.2.4 を推奨)

で、Raspberry Piの回路図は以下の通り。4つのタクトスイッチを使います。

Atdasi01

ちょっとわかりにくいですが、各タクトスイッチにつながる線で、黒は「GPIO24」、青は「GPIO17」、黄は「GPIO27」、緑は「GPIO22」、そして赤は「3.3V」につながってます。

あ、Raspberry Pi用のカメラも当然、つないでおきます。

で、先の3つのプログラムコードを、一つのフォルダに入れます。

Atdashi02

また、同じフォルダ内に「data」という名前のフォルダを作り

Atdashi03

その下に、上のような「グー」「チョキ」「パー」に当たる3種類のフォルダを作っておきます。

Img_0159

で、我が家のRaspberry Piで組んでみました。

Img_0164

こんな感じに、4つのタクトスイッチとつないでます。

なお、カメラは5インチ液晶の裏に両面テープで張り付けておきました。

これで、準備完了です。

(1) グー、チョキ、パー をラズパイカメラで撮影して記録 (各30枚づつくらい)

まず、自分の手を使って、「グー」「チョキ」「パー」の手を集めます。

Raspberry Pi上でターミナルを開き、

> python3 1_camera.py

と入力し、実行。

ターミナル上に「Ready!」と表示されたら、準備完了です。撮影を開始します。

Raspberry Piのカメラの前で「グー」「チョキ」「パー」の3種類の手を構えて、先の回路図にあるボタン「グー」「チョキ」「パー」で、手にあったものを選んで押します。

Img_0162

すると以下のような感じに、各フォルダ内に画像がたまっていきます。

Atdashi04

各ラベルごとに、20~30枚づつくらい撮影してください。

なお、合計が100枚を超えると、Raspberry Pi 3B+ではメモリーが飛ぶっぽいです(うちは飛びました)。

(2) 上の写真を用いて深層学習(CNN)を実施

(1)で教師データができたので、学習を実行します。同じフォルダ内で、

> python3 2_train.py

と実行します。

デフォルトでは、50エポックほど流れます。大体5分くらいで終わります。

なお、この50エポック内の最良のモデルのみが保存される仕組みになっているため、学習が終わればそのまま(3)へと移行します。

が、その前に、学習の状況を確認しておきましょう。

作業フォルダー中に、「loss_acc.png」という画像ファイルができているはずです。

Loss_acc

その名の通り、Loss(損失)値とAccuracy(精度)値のグラフが出てきます。Loss値は0に近いほど、Accuracyは1に近いほど、高精度なモデルができている目安になります。

が、よく見るとどちらも2色あります。これは、学習用データでの検証値(Train)と、評価用データでの検証値(Val)となります。

簡単に言うと、上の画像のようにLoss、Accuracy共に、この両者がほぼ同じところに収束していれば、学習としてはまずまずです。

これがTrainとValとが離れていると、いわゆる”過学習”と呼ばれる状態になります。その場合は汎用性が落ちているので、パラメータを変更するなり、(1)からやり直すなりして、再学習する必要が出てきます。

(例えば、batchの値を10→20に変えてみる 等)

単純に、何も変えずにもう一度実行するだけでよくなることもあります。何度実行しても改善されないときのみ、パラメータをいじるか、あるいは写真の撮り直しを実行してみてください。

グラフを確かめてから、(3)へ行きます。

(3) できたモデルを使い、カメラで撮影した「手」を推論する

ここでは、「3_atodashi.py」を使います。

> python3 3_atodashi.py

と実行したのち、

Img_0163

こんな感じに、カメラの前で手を構えます。

もし、写真のようにチョキを出しているときに、プロンプト上で

 > 2_choki

と表示されたら、推論成功です。

グーやパーだと勘違いしていたら、学習に失敗している可能性があります。

(1)か、(2)あたりからやり直してください。

あるいは、手が近すぎる or 遠すぎることもあります。何度か実験した経験での話ですが、ちょっと動かしてみると、精度が上がる距離がどこかにあることが多いです。

さて、画像認識としてはここまでで終了ですが、これではまだ「後出しじゃんけん機」ではありませんね。

(4) 推論結果に対し、勝つ手の画像を表示する

Raspberry Piに後出しじゃんけんをさせるために、「3_atodashi.py」を以下のコードに置き換えます。


#!/usr/bin/env python

import os
import sys
import numpy as np
import tensorflow as tf
import cv2

import keras
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense,Dropout,Flatten
from keras.layers import Conv2D,MaxPooling2D
from keras.preprocessing.image import array_to_img,img_to_array,load_img
from keras import backend as K
from sklearn.model_selection import train_test_split
from keras.models import load_model
import time

import RPi.GPIO as GPIO
import picamera

i = 0
label_name = []

label = 'label.txt'

f = open(label,'r')
for line in f:
  line = line.rstrip()
  l = line.rstrip()
  label_name.append(l)
  i = i + 1

NUM_CLASSES = i
IMAGE_SIZE = 28

if __name__ == '__main__':
    test_image = []
    
    # model read
    model = load_model('model_28.h5')
    model.summary()
    
    # for Raspberry Pi

    GPIO.cleanup()

    #for Raspberry Pi
    GPIO.setmode(GPIO.BCM)
    port1 = 24 # switch

    GPIO.setup(port1, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

    print('Ready!')
    try:
        while True:
            if GPIO.input(port1):
                with picamera.PiCamera() as camera:
                    camera.resolution = (12896)
                    camera.start_preview()
                    camera.capture('./tmp.jpg')
                
                img = img_to_array(load_img('./tmp.jpg' , target_size=(28,28)))
                test_image.append(img)
                test_image = np.asarray(test_image)
                test_image = test_image.astype('float32')
                test_image = test_image / 255.0
    
                predictions = model.predict_classes(test_image)
    
                print(label_name[predictions[0]], u'です。')

                #後出し処理
                if predictions[0] == 0# 「グー」だった時
                    reac = "pa.png" # 「パー」を返す
                elif predictions[0] == 1# 「チョキ」だった時
                    reac = "gu.png" # 「グー」を返す
                else# 残り、すなわち「パー」だった時
                    reac = "choki.png" # 「チョキ」を返す

                img = cv2.imread(reac)
                cv2.imshow("reaction",img)
                key = cv2.waitKey(1000
                cv2.destroyAllWindows()
                
                test_image = []
            
            time.sleep(0.01)

    except KeyboardInterrupt:
        GPIO.cleanup()

「#後出し処理」というコメント行がある後ろ当たりに、その後出しじゃんけんの処理が追加されてます。

また、画像表示にはOpenCVを用いてますので、pip3コマンドでOpenCVをインストールしておいてください。

> pip3 install python-opencv

で、このほかに画像が3枚、つまり、グー、チョキ、パーの画像をそろえる必要があります。

私はいらすとやで落としましたが、なんでもいいです。

Atodashi05

こんな感じに「グー」「チョキ」「パー」それぞれ「gu.png」「choki.png」「pa.png」として、Raspberry Pi上のプログラムコードの入った同じフォルダに入れておいてください。

で、この状態で(3)と同様に動かすと、推論の直後に、Raspberry Piが勝つと思う手を表示してきます。

Img_0205

こんな具合です。

(3)でそこそこの精度が出るモデルであれば、正しい「勝ち手」を出してくれるはずですね。

はい、以上が「後出しじゃんけん機」を作るまで、です。

(2)で使う「Train.py」という学習用コードを読めばわかる通り、28×28の画像で学習、推論させてます。この解像度じゃないと、Raspberry Piでは学習できません。

かなり低い解像度ですが、案外この解像度でも、じゃんけんくらいは認識できるようです。

もっとも、一筋縄ではいかないところもありますね。背景に依存しちゃったり、あるいは過学習で現実の手をうまく認識しなかったり……その辺りは、トライアンドエラーで実験してみるのがよいかと思います。

今回入れてませんが、Grad‐Camを使ったりして、モデルの確からしさを調べるのもいいですね。実際、会社にある同じコードでは、Grad-Camを組み込んでます。

どちらかというと、画像認識の理屈よりも、それを実際に使ってみてノウハウっぽいものを学ぶというのが狙いのプログラムコード。やってみると、思ったよりも精度は出ることもあるし、思い通りにいかないこともあります。

もちろん、ここに書いただけでは不十分な話が多いです。パラメータまで含めたら、一介のブログ記事では書ききれないほどいろいろあります。

このほか、精度におけるカメラと手の距離の依存性が高いので、HC-SR04などの距離センサーと組み合わせて撮影させてみるなど、電子工作の題材にもぴったりですね。

とまあ、我ながらうまい仕掛けを作ったものだと思っていたんですが。

これを作り上げた後に、「人気ブロガーからあげ先生のとにかく楽しいAI自作教室」(日経BP)という本にも、同じようにじゃんけんの手を学習させるというコードがあることが判明。

で、Kindle版で購入してみてみたんですが……あちらはRaspberry Pi上ではなく、しかも画像セットはあらかじめ準備されたものを使用、かつ、Google Colab上で動かすというものでした。いやはや、幸いにもこちらのやってることとは、かぶってませんでしたね。

まあ、似たようなことは皆さん、考えるものですね。

ちなみにこの本、画像だけでなく、自然言語など、幅広いカテゴリーの話が載っていたりと、なかなか面白い本です。買って損はありません。

著者のからあげ氏のブログは、Raspberry Pi関係のコードではとてもお世話になってますね。私もよく、参考にさせてもらってます。

以上、「画像認識を体で覚える」仕組みを作ってみた、というお話でした。


人気ブロガーからあげ先生のとにかく楽しいAI自作教室

« IIJが20ギガで1880円のプラン | トップページ | 4つのカメラを取り付け可能にするアダプタ「Raspberry Pi用マルチカメラアダプタ」 »

Raspberry Pi・Arduino・電子工作」カテゴリの記事

数値解析系」カテゴリの記事

コメント

Raspberry Pi 4 で試しています.
2_train.pyで,from sklearn.model_selection import train_test_splitや,Tensorflowでエラーが出ます.Raspberry Pi 4にインストールするべきソフトは,Tensorflow,Keras,Numpyの3つで良いのでしょうか.
よろしければ,教えてください.

> Masaさん

他にscikit-learn、opencv-pythonも必要です。この辺りのインストールは結構難儀しますので、いろいろなサイトを参照された方が良いと思います。なおopencv-pythonは、最新版である必要もないので、pipではなく、apt-getで持ってきてもいいです。

回答ありがとうございます.それぞれのバージョンなどの問題があるようです.少しトライしてみます.

ラズベリーパイ4を使っているものです。Pythonのバージョンは3.9.2から下げなければならないですか?その入れなければならないソフトはなんですか?
初心者なので、細かく教えていただきたいです。お願いします。

> kさん
このプログラムは、3.10でも動いているので、特にダウングレードする必要はありません。必要なライブラリについては、pip3というコマンドでインストールします。例えば、

> pip3 install tensorflow

とすれば、tensorflowが入れられます。
同様に、keras、scikit-learn、numpy、opencv-pythonを入れる必要がありますが、これが結構やり方がかわるものなので、ググって調べることをオススメいたします。特にKerasとtensorflowはバージョンの組み合わせがシビアなのでご注意ください。

回答してくださり、ありがとうございます。参考にさせていただきます!

ラズパイ4を初めて使用しているのですが、
python3 2_train.py のコマンドを打つと、
Traceback (most recent call last):
File "/home/pi/2_train.py", line 8, in <module>
import tensorflow as tf
File "/home/pi/.local/lib/python3.9/site-packages/tensorflow/__init__.py", line 22, in <module>
from tensorflow.python import pywrap_tensorflow # pylint: disable=unused-import
File "/home/pi/.local/lib/python3.9/site-packages/tensorflow/python/__init__.py", line 49, in <module>
from tensorflow.python import pywrap_tensorflow
File "/home/pi/.local/lib/python3.9/site-packages/tensorflow/python/pywrap_tensorflow.py", line 58, in <module>
from tensorflow.python.pywrap_tensorflow_internal import *
File "/home/pi/.local/lib/python3.9/site-packages/tensorflow/python/pywrap_tensorflow_internal.py", line 114
def TFE_ContextOptionsSetAsync(arg1, async):
^
SyntaxError: invalid syntax
と表示されてしまいます。前者の回答をもとにソフトはすべてダウンロードしました。
原因がわからないので、解決策を教えていただけると幸いです。
長文になってしまい、申し訳ありません。

ラズパイ4を初めて使用しているのですが、
python3 2_train.py のコマンドを打つと、
Traceback (most recent call last):
File "/home/pi/2_train.py", line 8, in <module>
import tensorflow as tf
File "/home/pi/.local/lib/python3.9/site-packages/tensorflow/__init__.py", line 22, in <module>
from tensorflow.python import pywrap_tensorflow # pylint: disable=unused-import
File "/home/pi/.local/lib/python3.9/site-packages/tensorflow/python/__init__.py", line 49, in <module>
from tensorflow.python import pywrap_tensorflow
File "/home/pi/.local/lib/python3.9/site-packages/tensorflow/python/pywrap_tensorflow.py", line 58, in <module>
from tensorflow.python.pywrap_tensorflow_internal import *
File "/home/pi/.local/lib/python3.9/site-packages/tensorflow/python/pywrap_tensorflow_internal.py", line 114
def TFE_ContextOptionsSetAsync(arg1, async):
^
SyntaxError: invalid syntax
と表示されてしまいます。前者の回答をもとにソフトはすべてダウンロードしました。
原因がわからないので、解決策を教えていただけると幸いです。
長文になってしまい、申し訳ありません。

> maruさん
このエラーでググってみたのですが、出てきたのは、Python 3.7に、当時としては新しすぎるバージョンのtensorflowを入れていた、というものでした。そこでは、Python 3.6にするのが解決策とされてました。
が、こちらは3.9のようなので、上とは違う原因かと思われます。考えられるのは、tensorflowのバージョンが新しすぎる、ということでしょうか。あるいは、記事通りのtensorflow 1.14を使ってるのであれば、Python 3.9に対応していないのではないかと。
と思って調べて見ると、tensorflow 1.14はPython 3.7までだそうで、もしそれ以降のバージョンのPythonでtensorflow 1.xを使いたい場合は、1.15を使えというものでした。
とりあえず、分かったことはこれくらいでしょうか。

丁寧に説明してくださり、本当にありがとうございます!
参考にさせていただきます!!

画像モデルの作成から学習、推論まで勉強になりました。
 この記事が作られた状況と現在の状況ではうまく動かず、私も動かすまで苦労したので、ここにポイントとなったところを書き残しておきます。
 そのままのコードで動かすなら、OSはbullseyeの前のバージョンであるbusterの32ビット版をセットアップして下さい。使用するカメラはUSBではなく、内蔵インターフェイスのカメラを使います。
 opencvのインストールは数分で終わるものなので、時間がかかる時は中断して少し前のバージョンをインストールして下さい。
 最後にkerasのバージョンを確認してください。何かのインストールで最新版になってる事がありますので(最新版では動きません)、その場合はバージョン指定でバージョンを下げます。
 USBカメラを使いたい場合は、picameraの部分をopen cvを使う形に書き換えれば動くと思います。
 誰かの助けになれば幸いです。
 

> 5kanさん
補足ありがとうございます。仰る通り、古いOS & ライブラリが必要です。本当なら、今どきのtensorflow 2.xで動かせる版に記事を直せればいいのですが。
すいませんが、この記事を参考にされる方は、古い環境で試されるか、kerasを tensorflow.kerasなどで置き換えてみてください。
(ただし、kerasの関数がかなり変わってるので、直すのは結構大変です)

返信有り難うございます。ラズパイが初めての方もいるようなので、もう少しセットアップについても書き足しておきます。
busterをインストールするには下記のくらげさんのページを参照してください。
https://monomonotech.jp/kurage/memo/m211208_raspi_os_install_past.html

インストール後はLXTerminalから下記を実行することで動作環境を構築できます。

sudo apt dist-upgrade -y
sudo apt upgrade -y
sudo apt update -y

sudo apt -y install fcitx-mozc -y
sudo apt -y install libatlas-base-dev libhdf5-dev

sudo pip3 install scikit-learn matplotlib
sudo pip3 install tensorflow==1.14.0 opencv-python==4.7.0.72
sudo pip3 install protobuf==3.18.3 h5py==2.9.0
sudo pip3 install numpy==1.20.3 scipy==1.5.4 keras==2.2.4

ーーーーーーーーーーーーーーーーーーーーーーーーーー
内蔵カメラの設定をする

sudo raspi-config
----------------------------------
3 Interface Options Configure connections to peripherals
P1 Camera Enable/disable connection to the Raspberry Pi Camera
=>Enabled
P5 I2C Enable/disable automatic loading of I2C kernel module
=>Enabled

ソース修正
ーーーーーーーーーーーーーーーーーーーーーーーーーー
1_camera.py 59行目
file_list = glob.glob('./_choki/*') => file_list = glob.glob('./data/1_choki/*')

3_atdashi.py 55行目
f = open(FLAGS.label,'r') => f = open(label,'r')

---------------------------------------
最後の後出しジャンケンは触っていません

コメントを書く

(ウェブ上には掲載しません)

« IIJが20ギガで1880円のプラン | トップページ | 4つのカメラを取り付け可能にするアダプタ「Raspberry Pi用マルチカメラアダプタ」 »