はじめに
- 最近エッジAIなるものに目覚め、JetsonNanoにDeepStream SDKを入れて遊んだりしている。
- 年末にスイッチサイエンスさんのセールでM5UnitVを購入したので、ちょっといじってみる。
- M5UnitVは、M5StickVから液晶、バッテリ、ジャイロセンサを省いた低価格版のため、M5StickVの文献が参考になる。
- 2020年2月発売当初はあまり文献が無かったみたいだが、先人達が情報を残してくれているおかげで、今はスムーズに進められる。
- microSDカードについては相性問題があるらしいので、ちゃんと使えるものを確保できるかがポイント。
セットアップ
- 開発環境はiMac
- 基本的に、M5UnitV公式の「Quick Start」に沿ってガンガン進める。
- https://docs.m5stack.com/en/quick_start/unitv/maixpy
File | 説明 |
---|---|
kflash_gui_v1.5.2_macOS.dmg | ファーム書込みソフトKflash |
M5StickV_Firmware_v5.1.2.kfpkg | M5UnitVファームウェア |
maixpy-ide-mac-0.2.5_2.dmg | 開発環境 MaixPy IDE |
ファームウェアのダウンロード
- 以下の公式ページのFirmwareリンクをクリックしてダウンロード。
- https://docs.m5stack.com/en/quick_start/unitv/maixpy
- (ちなみに、MacではEasyLoaderはWindows専用なので使わない。)
ファーム書込みソフトKflash
- 続いて、Kflash_GUI をダウンロード。
- ダウンロードしたら、ファイルを開いて Macにインストール。
-
kflash_gui.app
のアイコンをApplicationsフォルダにコピーすればOK.
- 続いてKflashを起動。
- 自分の場合、アイコンをダブルクリックしても起動しなかったので、
open /Applications/kflash_gui.app
で起動。 - M5UnitVをUSBケーブルで繋ぎ、先ほどダウンロードしておいたファームウェアを書き込む。
- Select Fileで、
M5StickV_Firmware_v5.1.2.kfpkg
を指定。 - Boardの種類は、M5StickV。
- PortはUSBケーブルを繋いだシリアルポート。
- しばらく待つと、書き込みが完了する。
これでM5UNitV側の準備はOK。
MaixPy
- 以下のサイトから最新のIDEをダウンロードする。
- http://dl.sipeed.com/shareURL/MAIX/MaixPy/ide/v0.2.5
- 2月に発売された以降、マイナーバージョンが上がってるので、とりあえず最新のをインストール。
- safariだと何故かダウンロードの認証ダイヤログで認証してもダウンロード開始しないので、chrome使ってダウンロードした。
- 回線が細いのか? 100MB程度のダウンロードなのに30分以上かかった・・・。
- ダウンロードできたらファイルをクリック。
- 以下の画面が立ち上がるので、アイコンをApplicationsフォルダにコピー。
動作確認
- MaixPyを起動。
- 外部から入手したアプリケーションはMacOX 上で起動していいか聞かれるので、OKにしておく。
- ボードの設定。
-
ツール -> Select Board
で、M5StickVを選択 - M5UnitVに接続
- 左下のチェーンのアイコンをクリックする。
- シリアルポートを選択できるので、M5UnitVと接続されているシリアルポート名を指定。
- MaixPyのサンプルコード
helloworld_1.py
をそのまま実行。 - 左下の再生ボタンで実行。
- 右上のカメラ映像が表示されれば成功!
- IDE外観
- 真ん中の領域に書いたPythonコードが左下の再生ボタンで実行され、カメラ映像が右上に表示される。
- シリアル通信の入出力は、真ん中の下部の「シリアルターミナル」って部分をクリックすると表示される。
MaixPyのサンプルコードを見てみる。
その1:緑領域認識
- MaixPyページの左側メニューで、
MODULES/LIBS
-->Machine vision
-->image
を開く。 - https://cn.maixpy.sipeed.com/en/libs/machine_vision/image.html
-
1.1. Routine 1: Find green
に記載されているコードで緑領域を認識させてみる。
FindGreen
import sensor
import image
import lcd
import time
lcd.init()
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.run(1)
green_threshold = (0, 80, -70, -10, -0, 30)
while True:
img=sensor.snapshot()
blobs = img.find_blobs([green_threshold])
if blobs:
for b in blobs:
tmp=img.draw_rectangle(b[0:4])
tmp=img.draw_cross(b[5], b[6])
c=img.get_pixel(b[5], b[6])
lcd.display(img)
おお、確かに緑色の部分を認識して、バウンディングボックスを重畳表示してくれる!
その2:QR Code認識
- 続いて、
1.3. Routine 3: Scan QR code
のコードを真ん中のエディタ領域に貼り付けて実行してみる。 - そのままのコードだとclockがインポートできない、ってエラーになるので以下のように修正。
-
import clock
-->import time
-
clock = clock.clock()
-->clock = time.clock()
QR_Code
import sensor
import image
import lcd
#import clock
import time
#clock = clock.clock()
clock = time.clock()
lcd.init()
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_vflip(1)
sensor.run(1)
sensor.skip_frames(30)
while True:
clock.tick()
img = sensor.snapshot()
res = img.find_qrcodes()
fps =clock.fps()
if len(res) > 0:
img.draw_string(2,2, res[0].payload(), color=(0,128,0), scale=2)
print(res[0].payload())
lcd.display(img)
- 認識させるためのQR Codeは以下のサイトを利用。
- https://www.the-qrcode-generator.com
おお、ちゃんと認識されとる!!
上記ページにもあるようにQR Codeなので、URL以外に任意の文字列を認識させることができる。
これを読み取らせてコマンドとしてロボット制御してみても面白そう。
その3: (応用)M5UnitVデバイス制御
- ちょっと応用して、A/Bボタン押下でLEDを光らせてみる。
- 公式ページの
UnitV_boot-v1220.py
を参考に抜き出し。 - Aボタン押下でLEDをGreenに光らせる
- Bボタン押下でLEDをBlueに光らせる
# --------------------------------
# M5UnitV テストコード
# A/Bボタン押下で LEDを光らせます
# --------------------------------
import time
from modules import ws2812
from fpioa_manager import *
from Maix import GPIO
# RGB LED設定
class_ws2812 = ws2812(8,100)
BRIGHTNESS = 0x10
# M5UnitV Aボタン設定(GPIO19)
fm.register(19, fm.fpioa.GPIO1)
but_a=GPIO(GPIO.GPIO1, GPIO.IN, GPIO.PULL_UP)
# M5UnitV Bボタン設定(GPIO18)
fm.register(18, fm.fpioa.GPIO2)
but_b = GPIO(GPIO.GPIO2, GPIO.IN, GPIO.PULL_UP)
but_a_pressed = 0
but_b_pressed = 0
# RGB LEDを光らせる
def RGB_LED(r,g,b):
a = class_ws2812.set_led(0,(r,g,b))
a = class_ws2812.display()
time.sleep(0.2)
a = class_ws2812.set_led(0,(0,0,0))
a = class_ws2812.display()
# ボタンA/B Push検出
while(True):
if but_a.value() == 0 and but_a_pressed == 0:
print("A_push")
but_a_pressed=1
RGB_LED(0, BRIGHTNESS, 0)
if but_a.value() == 1 and but_a_pressed == 1:
print("A_release")
but_a_pressed=0
if but_b.value() == 0 and but_b_pressed == 0:
print("B_push")
but_b_pressed=1
RGB_LED(0, 0, BRIGHTNESS)
if but_b.value() == 1 and but_b_pressed == 1:
print("B_release")
but_b_pressed=0
その4:色領域検出
# orange
target_lab_threshold = (0, 100, 4, 127, 15, 127)
# red
#target_lab_threshold = (0, 100, 31, 127, 19, 127)
# blue
#target_lab_threshold = (0, 100, 35, 127, -128, 127)
その5: boot.pyの作成
- MaixPyで書いて実行したコードはM5UnitV上には残らないため、USBケーブルを抜き、別途M5UnitVに電源を供給してもブートしない。
- 任意コードでブートするようにするには、SDカードのROOTフォルダに
boot.py
と言う名前のファイルを置いておく必要がある。 - https://cn.maixpy.sipeed.com/en/get_started/upload_script.html?h=boot.py
- また、いちいちSDカードにファイルを配置するのはめんどくさいので、MaixPy上でこの作業ができる手段が提供されている。
- シリアル接続した状態で、
ツール
-->Save open script to board(boot.py)
SDカード相性確認
- いよいよ学習データを用意して任意の物体認識をさせる作業に入る前に、microSDカードの相性をチェックする。
- M5StickV, M5UnitVはmicroSDカードの相性がシビアだとされているので、手持ちのカードが使えなかったらこれ以上先に進められない。。。
- (スイッチサイエンスには相性確認済みのmicroSDカード付きのM5UnitVも販売されているが、セール対象になって無かったので茨の道を選択した・・・)
何枚か持ってる手持ちのmicroSDカードを試した結果、、、、
- 以下の結果となった。
- シリコンパワーの16GB(真ん中の白いやつ):OK
- 最近買ったKIOXIAの32GB(右側の青いやつ):NG
よかった〜。
使えるのがあった。(ちょっと古めの奴がいいのかな?)
- 相性チェック方法は、以下のV-Trainingのページにある
Clock to download boot-UnitV
から以下の学習データ撮影用のpythonコード使う。 - https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/UnitV_boot_v1220.py
- 実行すると、右上にカメラ映像が表示されるので、その状態でM5UnitVの
Aボタン
を押すと撮影できる。 - SDカードが認識され、撮影画像がSDカードに書き込めると、以下のシリアルターミナルのような出力が得られる。
- 特にシャッター音はしないので、シリアルターミナルの撮影枚数がインクリメントされるかで確認する。
V-Trainingで機械学習
- UnitVで撮影した画像を学習させ、任意の物体を検出できるようにするまでの手順が以下のV-Trainingページに記載されている。
- https://docs.m5stack.com/#/en/related_documents/v-training
- 自分もこれに沿って作業を進め6種類の物体データを用意し、指定された形式のZipファイルにしてトレーニングサービスにアップロードする所までやってみた。
が、、、
2020/12/30現在、M5Stackのトレーニングサービスがストップしているらしい。。。
(2020/12/24 のタスクがずっと残ってるし・・・)
M5Stack Communityにスレッドを立てて状況を確認してみたが、1日経っても返答なし。。。
年末なのでサーバ管理者もお休みかな?
V-Training Service is active now??
残念。
と言うことで一旦、今年はここでおしまい。
追記(2021/1/1)
M5Stackのエンジニアが対応してくれました。検証再開です。
V-Trainingでエラーを出しまくる。
-
UnitV_boot_v1220.py
を使ってトレーニングデータを撮影。 - Zipファイルにしてデータをアップロードすると何度もエラーで弾かれてしまった。
- 現時点で自分は機械学習の中身は全く理解してないので、学習処理に関するエラーについては後で調べます。
1. Train or Valid folder not found
Online Training Request Failed
------------------------------
Hi!
Sorry for that, there is some error happened during the training process.
We attached the reason below, if you have any questions, welcome to report to us through Twitter, Facebook, or Forum.
Or, check out our docs here: https://docs.m5stack.com/#/en/related_documents/v-training
USERID: XXXXXXXXX
CONTENT: Train or Valid folder not found. If you are using the M5StickV software, make sure you reach enough image counts of 35 per class.
Notice Info:
- 問題
- 学習データが足りない。
- 1クラス(分類)あたりtrainフォルダに35ファイル以上、学習データが必要だが足りない。
- 取得したスクリプトを実行すると、31-35番目のファイルはtrainフォルダでなく、validフォルダに配置されるため、ギリギリだと足りなくなる。
- 修正方法
- 1クラスあたり、50枚くらい撮影しておく。
2. Lake of Enough Valid Dataset
CONTENT: Lake of Enough Valid Dataset, Only 30 pictures found, but you need 35 in total.
-
Lake of Enough Valid Dataset
ってのは多分タイポでLack of Enough Valid Dataset
だろう。 - 問題
- 50枚くらい撮影するとvalidフォルダ配下のClass分類番号フォルダに自動的に5ファイル正解データが配置されるが、それだと足りないみたい。
ex. valid/1/31.jpg, 32.jpg, 33.jpg, 34.jpg, 35.jpg
- 修正方法
- 手動でtrainフォルダから正解ファイルをvalidフォルダに1ファイルだけコピーしてみた。
- 6クラスに分類する構成なので、各クラス5-->6ファイルで、30-->36ファイルにした。