Posted at

Sipeed M1 Dock(MAiX Dock)でTinyYoloを動かして、人を認識したらSDカードに保存する


はじめに

こんにちは、のんびりエンジニアのたっつーです。

ブログを運営しているのでよろしければ見てください。

今回はこのM1 Dock(MAiX Dock)ボードを使って、超小型なボードを使ってTinyYoloを動作させながら、人間を認識したらSDカードに画像を保存するような動作を実装してみました。

想定される使い道としては監視カメラなどで人をトリガーとして何かを動作させる場合などに使えるのかなと思います。


M1 Dock(MAiX Dock)とは?

Sipeed M1 dock suit ( M1 dock + 2.4 inch LCD + OV2640 ) K210 Dev. Board 1st RV64 AI board for Edge Computing

購入すると以下のセットが届きます。

ボード、ディスプレイ、カメラ付きのオールインワンのセットになっています。これで19ドルほどで購入できるのはすごい安いですね。

ケース(@ksasao) さんのを使わしていただいており、3Dプリンターで出力した物になります。

D6w0jBUUYAAWlLz-768x576.jpg

RISC-Vと言うオープンCPUアーキテクチャを採用している安価なチップを採用しています、それに加えてこのボードでは KPU(Knowldge Processing Unit) を搭載しており、機械学習で必要な演算を高速に実行する事が可能です。

K210のチップベンダーkendryte社のサイトに掲げられている特徴を引用します。


  • Performance


    • CPU: RISC-V Dual Core 64bit, with FPU

    • Image Recognition:QVGA@60fps/VGA@30fps

    • Audio: Microphone array (8 mics)



  • Security


    • Advanced encryption standard (AES) hardware accelerator

    • One time programmable (OTP) ROM

    • SHA256



  • Power Consumption


    • Power consumption of typical application scenarios < 1W

    • Power consumption of chip < 300mW



  • Expansibility


    • OS: FreeRTOS

    • NN Model: TinyYOLOv2 (after pruned)

    • DNN Framework: TensorFlow/Keras/Darknet

    • PeripheralsFPIOA/UART/GPIO/SPI/I²C/I²S/WDT/TIMER/RTC, etc.




ダウンロード

今回使うツールをダウンロードしますが、それぞれの以下のような物になります。

 K-Flash : ROMを書き換えるツール 

 maixpy_20class : TinyYoloのROM・ソースーコード

 uPyLoader : ファイル転送ツール

実際にダウンロードして、ローカルのフォルダに保存しておきましょう。



  1. https://kendryte.com/downloads/ から「K-Flash V0.3.2」をダウンロード


  2. https://bbs.sipeed.com/t/topic/683 から「maixpy_20class.zip」をダウンロード


  3. https://github.com/BetaRavener/uPyLoader/releases から最新版の「uPyLoader-win.exe」をダウンロード

以下のように配置した状態で開始します。

image-88-768x373.png

「uPyLoader-win.exe」「K-Flush」についてはプロパティからセキュリティの「許可する」をオンにしておきましょう。

image-89.png

image-91.png

上記で必要な物のダウンロードが行えましたので、次からは実際にYoloを動かす手順になります。


TinyYoloを動かす


M1 Dock(MAiX Dock)をPCと接続

M1 Docke(MAiX Dock)をPCと接続すると、自動でドライバー(CH340)が認識されます。

認識されたらここのポート番号(今回はCOM3)を覚えておきましょう

image-92.png


K-FlashでROMの書き換え

まず最初のステップでは、TinyYoloを動かすためにM1 Dock(MAiX Dock)のROMを直接書き換えます。


maixpy_20class.bin の書き込み

「COM3」が選択されている事を確認したら、「maixpy_20class.bin」を選択して、「Flush」ボタンでROM書き込みを行いましょう。

image-93-768x374.png


20class.kfpkg の書き込み

次も同じ手順で「20class.kfpkg」を書き込みましょう。

image-94-768x374.png


TinyYoloのPythonコードを転送


boot.pyの作成

次に「20class.py」をコピーして「boot.py」を作成しておきましょう。

image-95-768x726.png


boot.pyの転送

「uPyLoader.exe」を起動してください。

「COM3」を選択して、「Connect」ボタンを押下してデバイスに接続します。

image-96-768x120.png

接続に成功すると以下のようにファイル一覧が表示されます。

image-97-500x250.png

先ほど作成した「boot.py」をデバイスに転送しましょう。

image-98-768x463.png


動作確認

USBケーブルを指しなおしてみましょう。

boot.pyのソースコードが実行され、実際に以下のように人・車などの20分類のTinyYoloが実行できると思います。


※カメラの画像が反転している場合は、sensor.set_vflip(0)の次の行に sensor.set_hmirror(0)を追加する。

https://twitter.com/ksasao/status/1129035637129129985


すごいですね!


SDカードにデータを保存する

次に本記事のメインになります。

実際にTinyYoloを使う場合には、何かを検知して何かアクションを行う必要がありますよね。

ここのでは”人を検知して”、”SDカードに画像として保存”の手順をやってみます。


SDカードのフォーマット

まず、SDカードをWindowsに読み込ませてフォーマットを行いましょう。(ここで小さい容量の物を使うと、FAT16でフォーマットされてしまうため動作しないので気を付けてください。)

image-99.png


boot.pyの書き換え

さきほど、作成したboot.pyを以下のように変更してください。


boot.py

import sensor,image,lcd,time

import KPU as kpu

lcd.init(freq=15000000)
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_hmirror(0)
sensor.run(1)
clock = time.clock()
classes = ['aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog', 'horse', 'motorbike', 'person', 'pottedplant', 'sheep', 'sofa', 'train', 'tvmonitor']
task = kpu.load(0x500000)
anchor = (1.08, 1.19, 3.42, 4.41, 6.63, 11.38, 9.42, 5.11, 16.62, 10.52)
a = kpu.init_yolo2(task, 0.5, 0.3, 5, anchor)
cnt = 1
while(True):
clock.tick()
img = sensor.snapshot()
code = kpu.run_yolo2(task, img)
print(clock.fps())
if code:
person = False
for i in code:
a=img.draw_rectangle(i.rect())
a = lcd.display(img)
for i in code:
lcd.draw_string(i.x(), i.y(), classes[i.classid()], lcd.RED, lcd.WHITE)
lcd.draw_string(i.x(), i.y()+12, '%f1.3'%i.value(), lcd.RED, lcd.WHITE)
if classes[i.classid()] == 'person':
person = True
if person == True:
name = 'person_' + str(cnt) + '.jpg'
img.save(name)
lcd.draw_string(1, 1, 'saved ' + name, lcd.RED, lcd.WHITE)
cnt = cnt + 1
else:
a = lcd.display(img)
a = kpu.deinit(task)



boot.pyの転送

SDカードを M1 Dock(MAiX Dock)にセット、USBケーブルを再接続してください。

※ここで、内部メモリからブートする事があるので、SDカードからブートするまで何度か再接続してください。

「uPyLoader.exe」を起動して再度「COM3」に接続します。

image-96-768x120.png

そうすると以下の警告が表示されます。

これはSDカードからブートしようとしたけど、ファイル転送のPythonコードが存在しないから「uPyLoader.exe」が正常に動かないよ!って意味の内容です。

image-100-768x464.png

なので、「uPyLoader」のメニューから「File > Init Transfer files」を選択して、転送用のPythonコードを初期化しましょう。

image-101-768x463.png

正常に初期化が終わると、「upload.py」/「donwload.py」の2つが転送されています。

image-102-768x463.png

次に作成作成した、「boot.py」をデバイスに転送します。

image-103-768x463.png

お疲れ様です、以上で手順が終わりました。


動作確認

実際にUSBを指しなおして、動作確認してみましょう。

画面の左上に「saved person_128.jpg」などの表示が追加されたと思います、これは SDカード にデータ保存したよ!って意味で画面上にメッセージを追加したのでわかりやすいと思います。

IMG_1841-768x1024.jpg

uPyLoaderで実際に確認してみましたが、保存されている事が確認できますね。

m1-dock-kekka-768x607.png


終わりに

どうでしたか簡単でしたね。

色々とWebの手順などを見ていると、Pythonを使ったやり方がありますが環境構築が手間なのでこの手順のように単体の実行ファイルで関係すると楽だと思いますので、ぜひ皆さんも試してみてください。

よければ ブログ「Unity+AssetStoreおすすめ情報」の方にも色々記載しているのでぜひご参照いただければと思います。