きっかけ
M5StickVで画像認識のチュートリアルとしてこれやったら面白そうなのでやります https://t.co/DZagC2Ibak
— 爆さん@意識他界系 (@HogePiyo33_4) November 25, 2019
本題に入る前に
これに従って最新版ファームウェアをM5StickVに焼いておいてください.
制作過程
MotoJapan's Tech-Memo
さんを参考に作ります.
1. bootファイルをSDカードに展開
https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/VTraining-Client-VerA02B01.zip
をダウンロードし,SDカードに展開する.
元記事でも言われてますがSDの直下に置かないとだめらしいです.
2. 学習用データの収集
M5StickVにSDカード差し込んで電源を入れてちょっとするとこんな画面が出てくるので正面のボタンで撮影,SDスロットの反対側のボタンで学習対象を変えられます.
こんな感じでパシャパシャ取っていきます.
学習用データ収集中 pic.twitter.com/NXrHo3fss4
— 爆さん@意識他界系 (@HogePiyo33_4) November 26, 2019
3. V-Training(モデル生成サイト)にデータをアップロード
http://v-training.m5stack.com/
にSDカードにあるtrain
とvalid
をupload.zip
にしてアップロードします.
このとき気をつけるのが解凍したときにuploadディレクトリの直下にtrain
とvalid
ができないとエラー(メールで来る)を吐かれます.
アップロードに成功して数分するとメールでモデルのダウンロードリンクと学習結果のグラフが送られてきます.
4. M5StickVで認識テスト
先程送られてきたリンクのモデルをダウンロードし,そのままM5StickV用のSDカードに解凍します(元々SDにあったファイルは念の為,消しました).
その後,SDカードをM5StickVに前と同じように差し込み,起動!
3種類の判別に成功! pic.twitter.com/MXDhx9MXGs
— 爆さん@意識他界系 (@HogePiyo33_4) November 26, 2019
5. デェェェェンを流すプログラムを書く
https://github.com/sipeed/MaixPy_scripts/blob/master/multimedia/audio/play_wav.py
を参考にboot.py
を改造していきます.
最終的にはこうなりました.
import image
import lcd
import sensor
import sys
import time
import KPU as kpu
from fpioa_manager import *
import audio
from fpioa_manager import fm
from Maix import I2S, GPIO
wav_dev = I2S(I2S.DEVICE_0)
def setup():
lcd.init()
lcd.rotation(2)
try:
from pmu import axp192
pmu = axp192()
pmu.enablePMICSleepMode(True)
except:
pass
try:
img = image.Image("/sd/startup.jpg")
lcd.display(img)
except:
lcd.draw_string(lcd.width()//2-100,lcd.height()//2-4, "Error: Cannot find start.jpg", lcd.WHITE, lcd.RED)
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_windowing((224, 224))
sensor.run(1)
lcd.clear()
flag = False
def play_sound(fname):
global flag
flag = False
if flag == False:
flag = True
try:
player = audio.Audio(path = fname)
player.volume(100)
wav_info = player.play_process(wav_dev)
wav_dev.channel_config(wav_dev.CHANNEL_1, I2S.TRANSMITTER,resolution = I2S.RESOLUTION_16_BIT, align_mode = I2S.STANDARD_MODE)
wav_dev.set_sample_rate(wav_info[1])
while True:
ret = player.play()
if ret == None:
break
elif ret==0:
break
player.finish()
except:
print("error")
flag = False
else:
pass
def main():
setup()
fm.register(board_info.SPK_SD, fm.fpioa.GPIO0)
spk_sd=GPIO(GPIO.GPIO0, GPIO.OUT)
spk_sd.value(1) #Enable the SPK output
fm.register(board_info.SPK_DIN,fm.fpioa.I2S0_OUT_D1)
fm.register(board_info.SPK_BCLK,fm.fpioa.I2S0_SCLK)
fm.register(board_info.SPK_LRCLK,fm.fpioa.I2S0_WS)
task = kpu.load("/sd/21c4fa151bed20a9_mbnet10_quant.kmodel")
labels=["USSR","USA","GB"] #You can check the numbers here to real names.
while(True):
img = sensor.snapshot()
fmap = kpu.forward(task, img)
plist=fmap[:]
pmax=max(plist)
max_index=plist.index(pmax)
a = lcd.display(img)
fname = None
if pmax > 0.95:
lcd.draw_string(40, 60, "Accu:%.2f Type:%s"%(pmax, labels[max_index].strip()))
if labels[max_index] == "USSR":
fname = "/sd/USSR.wav"
elif labels[max_index] == "USA":
fname = "/sd/USA.wav"
elif labels[max_index] == "GB":
fname = "/sd/GB.wav"
play_sound(fname)
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_windowing((224, 224))
sensor.run(1)
lcd.clear()
a = kpu.deinit(task)
main()
できたー pic.twitter.com/AkfWvrYPl1
— 爆さん@意識他界系 (@HogePiyo33_4) November 27, 2019
音はWikipediaから国歌を取ってきて加工しました.
一回対象を認識するとカメラがフリーズするので,その度にリセット噛ませたほうがいいです.
このプログラムの問題としては,音楽再生中にディスプレイの更新が止まること.
マルチスレッドにしてないから仕方ないけどチョット不便です.
#感想
完走した感想としては,M5StickVとk210には文句はないですが,IDEのUIによるストレスがあったのでVSCodeベースになってほしいです(宗教).
#参考にさせてもらったところ
https://qiita.com/nnn112358/items/6f4934f8b81902b8e98c
https://qiita.com/manontroppo1974/items/43105469a8d560bfead8
https://qiita.com/KatsuShun89/items/72b918c6ec8314380b77
https://qiita.com/iwaoka1986/items/fcf48cb3ae3fd8f88a33