2018/08/30
どうも、ディープなクラゲです。
「ゼロから学ぶディープラーニング推論」シリーズの10回目記事です。
このシリーズでは、Neural Compute StickとRaspberryPiの使い方をゼロから徹底的に学び、成果としてディープラーニングの推論アプリケーションが作れるようになることを目指しています。
第10回目はGoogLeNet画像認識のコードを改造して、カメラ映像からリアルタイムに画像認識させ、特定の画像を検出したら音を出力させます
実行するためのソースコードをダウンロードします
Pythonのソースコード demo.pyに加えて、今回は音の出力用に3つの音声ファイルを用意しています。
つまり合計4ファイルをダウンロードします。
ダウンロード方法は2つありますので、やりやすい方でお願いします。
まずGoogLeNetフォルダに移動します
cd /home/pi/workspace/ncsdk/examples/caffe/GoogLeNet
wgetコマンドを使って、下の4つのコマンドを実行します
wgetコマンドは指定したURLにあるファイルをダウンロードするコマンドです
wget https://raw.githubusercontent.com/electricbaka/movidius-ncs/master/GoogLeNet/demo.pywget https://raw.githubusercontent.com/electricbaka/movidius-ncs/master/GoogLeNet/sound1.wavwget https://raw.githubusercontent.com/electricbaka/movidius-ncs/master/GoogLeNet/sound2.wavwget https://raw.githubusercontent.com/electricbaka/movidius-ncs/master/GoogLeNet/sound3.wav
lsコマンドなどで確認して、以下4つのファイルがあればOKです
ターミナルで、適当な場所に移動します
cd /home/pi/ダウンロード
git cloneコマンドを使ってダウンロードします
git cloneコマンドはGitHubから、まとめてソースコードをダウンロードできます(難しく言うと、ローカルにリポジトリをクローン)
git clone https://github.com/electricbaka/movidius-ncs.git
movidius-ncsというフォルダが出来ていると思います。
ファイルマネージャーを2つ開きます
以下の4つのファイルを、"/home/pi/workspace/ncsdk/examples/caffe/GoogLeNet" へコピーすればOKです
USBカメラ接続に加え、今回は音を出力させるため、スピーカーを用意します。ミニジャックをラズパイに接続してください。
なお、HDMIディスプレイに内蔵スピーカーが付いている場合は、それでも構いません。
ターミナルにて、GoogLeNetフォルダに移動します
cd /home/pi/workspace/ncsdk/examples/caffe/GoogLeNet
demo.pyを実行します
python3 demo.py
USBカメラを動かし「エレキギター」「アコースティックギター」「PCキーボード」のどれかを写してみて下さい。音が鳴れば成功です。
家にギターが無いよという人は、インターネットで適当に画像検索してPC画面等にエレキギターやアコースティックギターを表示して、そこにUSBカメラを向けてみて下さい。
もし音が鳴らないという人は、ラズパイ画面の右上のスピーカーアイコンを右クリックして以下のメニュー表示を行い、"Analog"か"HDMI"を選択してください。USBスピーカーから音を出す場合は"Analog"、HDMIディスプレイから音を出す場合は"HDMI"です
それでもまだ音が鳴らない人は、ラズパイ画面の右上のスピーカーアイコンを左クリックして音量を確かめてください。
なお、USBスピーカー自体に音量調整がある場合もありますので、そちらも確かめましょう
それではソースコードの解説です。run.pyから手を加えた箇所を説明します。
全コードはこちらからも閲覧可能です。
https://github.com/electricbaka/movidius-ncs/blob/master/GoogLeNet/demo.py
"detect_counter"と"detect_old"という変数を用意し0を代入しています。別の箇所で使用します
それ以外は「OpenCV」カメラ映像の読み込みと表示 で習ったコードそのままです。リアルタイムにカメラ映像を取得・表示、何らかのキーが押されたら終了します。
# ***************************************************************# video capture# ***************************************************************detect_counter = 0detect_old = 0cap = cv2while True:ret, frame = capcv2key = cv2if key != -1:break
video chaptureで追加したwhileのブロック内に収めて無限ループさせるために、以下の4ブロックは全て先頭にインデント(4つのスペース)を挿入しています
run.pyでは入力画像がエレキギター"nps_electric_guitar.png"のファイルでしたが、そこをコメントアウトして、カメラ映像から取得した画像 frame を代入しています。
#img = cv2.imread(EXAMPLES_BASE_DIR+'data/images/nps_electric_guitar.png')img = frame
新たなブロックを挿入しています。
ここでは、推論結果を元に、以下の特定の画像を認識した場合のみ音を出力しています。
546, 402, 508などの番号は、第8回時に紹介した "synset_words.txt" を見れば分かります。
別のモノで検出したい場合は、番号を書き換えればい良いだけです
例:computer mouseであれば 673
# ***************************************************************# detect and sound# ***************************************************************#detectdetect_new =if detect_new == detect_old:detect_counter = detect_counter + 1else:detect_counter = 0detect_old = detect_new#soundif detect_counter == 2:if detect_new == 546:oselif detect_new == 402:oselif detect_new == 508:os
音の出力は「Python基礎」で習った os.systemを使ったLinuxコマンドを利用しています。
実際にターミナルで以下のコマンドを打ってみて下さい。音が鳴ると思います。
aplay ./sound1.wav
なお、demo.pyで普通にaplayを行うと音声出力中にプログラムが止まってしまいます。その対策としてaplayの最後に "&" を付け、音声出力中にプログラムが止まらないようにしています。
最後にdetect_new、detect_old、detect_counterという変数を使っている理由を説明します。
推論結果は order[0] に入っています。その数値を見て if で単純に分岐させるだけだと、検知中何度も音が鳴りっぱなしになってしまいます。
そこで、counterを設け、2回連続検知したときだけ音を鳴らすようにしています。1回のみや3回以上連続検知では音は鳴りません。その代わり、最後に検知したモノと異なる検知した場合は counterは 0 にリセットするという仕組みです。
「OpenCV」カメラ映像の読み込みと表示 で習ったコードそのままです。
ブロックの終わりに挿入しています
# ***************************************************************# Clean up video capture and windows# ***************************************************************capcv2
次回は性別や年齢を推論するGenderNet/AgeNetの実行を行います!
以上、「GoogLeNetでリアルタイム画像認識&音出力」でした。