PLEN:bitとUnitV AI cameraで自撮りロボ製作
PLEN Projectの臼井です。
いつもPLEN Projectのnote記事をご覧いただきありがとうございます。
弊社スタッフがお送りしているnote記事の執筆に、今回初めて参入することになりました!
記念すべき(?)私の第1号記事ではPLEN:bitとunitV AI cameraを使ったAI自撮りカメラのデモと作り方を紹介します。
技術者向けの記事ではありますが、様々な方に雰囲気を楽しんでもらいたく、AIカメラとはなんぞ?unitV?などといった疑問を、なるべく平易に解説していきます!
長いですが最後までどうぞお付き合いください;)
1. 導入
今回作るもの
今回紹介するAIカメラは、AIで人の顔を検知して、その方向にカメラを向けることで常に写真の真ん中に顔が写る、というものです。
カメラを向けるためにPLEN:bitの体を活用するので、知らない人が見たらあたかもPLEN:bitが意思を持ってカメラを向けてくるように感じるはずです!
AIカメラ
AI(人工知能) + カメラ = AIカメラ
今話題のAI(人工知能)とは、人の思考回路をコンピュータで模倣し、かつコンピュータの膨大な計算能力を活用することで、人間では不可能な判断速度を実現したり、判断が難しい事象に対して解を提案するなど、これからの世界を大きく変える可能性に溢れた技術です。
また、カメラは皆さんご存知の通り、心揺さぶる風景や瞬間を色褪せることなく、永く記録してくれる便利な道具です。
これらを融合させたAIカメラは、今まで人が判断して画角を合わせたりシャッターを切っていたカメラの操作を、AIが成り代わって行なってくれるものです。
有名なものとして、笑顔シャッター(人の笑顔を認識したら自動で撮影してくれる機能)などがあります。
PLEN:bit(プレンビット)
PLEN:bitは、弊社が開発した教育用二足歩行ロボットです。
手のひらサイズのボディには、関節の役割をするサーボモータが8個搭載され、歩くことはもちろんサッカーやダンスといった多彩な動きをプログラミングして動かすことができます。
1つ1つのサーボモータを単独で制御することもできるので、カメラを持つ腕を上下左右に動かすことも可能です。
UnitV AI camera
中国の深センにあるベンチャー企業、M5stack社が開発したUnitV AI cameraは、消しゴムサイズの小さなケースに、カメラとAIプロセッサが搭載されています。
Pythonを使ってプログラミングすることで、AIを活用した様々な処理ができます。
※後述するSDカードの相性問題があるため、SDカードセットが良い!という方は3.1[SDカードの準備]を御覧ください
2. システム構成
2.1 必要なもの
・PLEN:bit
・UnitV AI camera(with SDカード)
・PC(要インターネット環境)
・USBケーブル(Type A - Type Cがオススメ)
・Groveケーブル
・ジャンパケーブル
・UnitV AI camera取付け用の材料(レゴブロックなど)
UnitV AI cameraが既にAIカメラとして完成しているため、非常にシンプルな構成です。
今回に至っては、PLEN:bitはUnitV AI cameraに言われたとおり腕を動かすだけですね。それぞれの役割はこうです。
・UnitV AI camera - 顔検出、(顔の位置の)座標計算、写真撮影・保存
・PLEN:bit - 座標を基に腕を制御
2.2 デモ作成の流れ
① UnitV AI cameraのプログラム作成と動作確認
② PLEN:bitの準備と動作確認
③ UnitV AI cameraとPLEN:bitの接続
3. 作業開始
3.1 UnitV AI cameraの準備
目次
・SDカードの準備
・開発環境
・プログラム
・プログラムの説明
・MaixPyで動作確認
・LED表示の説明
[SDカードの準備]
UnitV AI cameraにはSDカードスロットがあるため、SDカードにPythonのプログラムを入れて動かしたり、画像データ等の保存ができます。
今回は、画像を保存するためにSDカードをつかいます。
※UnitV AI cameraと差し込むSDカードには相性問題が報告されており、SDカードを認識しない場合があります。公式が動作確認済のSDカードのリストを公開していますので、もしSDカードを別に調達する場合は、こちらのリストから選ぶ方がトラブル回避できるかも知れません。
Switch Scienceでは動作確認済モデルのSDカードのセットも扱っています。購入はコチラ
[開発環境]
UnitV AI cameraをプログラミングするには、開発環境が必要です。ここではリアルタイムでカメラの映像を確認できる方法として、Sipeed社のMaixPy IDEを使いました。
ダウンロードはこちらから可能です。執筆時の最新バージョンはv0.2.5でした。Windows, mac, linuxに対応していますので、ご使用の環境に合わせて選択してください。
※MaixPy IDEのインストール方法は割愛します
[プログラム]
下記のプログラムをMaixPyの左側(エディタ領域)に貼り付けてください。
#refer to http://blog.sipeed.com/p/675.html
import sensor
import KPU as kpu
import json
from machine import UART
from fpioa_manager import fm
from modules import ws2812
class_ws2812 = ws2812(8, 1)
# シリアル通信の設定
fm.register(34, fm.fpioa.UART1_TX, force=True)
fm.register(35, fm.fpioa.UART1_RX, force=True)
uart = UART(UART.UART1, 115200,8,0,0, timeout=1000, read_buf_len=4096)
# カメラモジュールの準備
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_vflip(True) # 上下反転
# sensor.set_hmirror(True) # 左右反転
sensor.run(1)
# 画像保存の準備
folder_counter = 0
while True:
try:
os.mkdir("/sd/" + str(folder_counter)) # フォルダ名を0から順につけていく
break
except Exception as e:
folder_counter += 1
pass
# YOLOの準備
task = kpu.load(0x300000) # you need put model(face.kfpkg) in flash at address 0x300000
anchor = (1.889, 2.5245, 2.9465, 3.94056, 3.99987, 5.3658, 5.155437, 6.92275, 6.718375, 9.01025)
a = kpu.init_yolo2(task, 0.5, 0.3, 5, anchor)
# 画面解像度 320x240
target_face_position_x = 160 #
target_face_position_y = 120 # 中心:120、顔の位置を高くしたいときは小さくする
focus_counter = 0
picture_counter = 0
while(True):
img = sensor.snapshot()
code = kpu.run_yolo2(task, img)
if code:
for i in code:
data = json.loads(json.dumps(i))
face_center_x = round(data['x'] + data['w'] / 2)
face_center_y = round(data['y'] + data['h'] / 2)
# print(face_center_x, m',', face_center_y)
uart.write(str(face_center_x) + ',' + str(face_center_y)+ '\n') # 座標データをシリアルで送信
if abs(face_center_x - target_face_position_x) >= 20:
focus_counter = 0
if face_center_x > target_face_position_x:
# uart.write('L'+'\n')
b = class_ws2812.set_led(0,(10,0,0)) # 赤 追従中
b = class_ws2812.display()
elif face_center_x < target_face_position_x:
# uart.write('R'+'\n')
b = class_ws2812.set_led(0,(10,0,0)) # 赤 追従中
b = class_ws2812.display()
elif abs(face_center_y - target_face_position_y) >= 20:
if face_center_y > target_face_position_y:
# uart.write('D'+'\n')
b = class_ws2812.set_led(0,(10,10,0)) # 黄 追従中
b = class_ws2812.display()
elif face_center_y < target_face_position_y:
# uart.write('U'+'\n')
b = class_ws2812.set_led(0,(10,10,0)) # 黄 追従中
b = class_ws2812.display()
else:
# uart.write('S'+'\n')
b = class_ws2812.set_led(0,(0,10,0)) #緑 フォーカス時
b = class_ws2812.display()
focus_counter += 1
if focus_counter > 10:
focus_counter = 0
b = class_ws2812.set_led(0,(255,255,255)) #白 撮影
b = class_ws2812.display()
img.save("/sd/" + str(folder_counter) + "/"+ str(picture_counter) + ".jpg", quality=95)
picture_counter += 1
b = class_ws2812.set_led(0,(0,10,0))
b = class_ws2812.display()
a = img.draw_rectangle(i.rect())
a = img.draw_circle(target_face_position_x, target_face_position_y, 10)
a = kpu.deinit(task)
貼り付けた様子
[プログラムの説明]
このプログラムはUnitV AI cameraが人の顔を検出し、その画面のどの位置に写っているかを座標に変換して、シリアル通信で送信するプログラムです。
画面解像度が320x240なので、ちょうど中心の座標は(x, y) = (160, 120)になります。このあたりに顔が写れば、自動的に写真を撮ってSDカードに保存します。
顔を検知するアルゴリズムは、リアルタイムの物体検出で有名なYOLO(You Look Only Once)を使用しました。
YOLOは物体検出のスピードが速く、UnitV AI cameraに搭載のAIプロセッサ”K210”では、QVGA(320x240)サイズで1秒間に10回ほどの検出が可能でした。
MaixPyでAIプロセッサを使う方法はSipeed社のMaixPyドキュメントに詳しく書いてあります。プログラムを修正したい方はこちらを参考にしてください。
※unitV AI cameraには、予め顔認識等のモデルが入っていますが、モデルが入っていなかったり、別のモデルを使用したい場合は、kflash-gui等を用いてモデルをUnitV AI cameraに書き込んでおく必要があります。
※ファームウェア等はこちら
※kflash-guiのダウンロードはこちら(執筆時の最新バージョンはv1.6.5)
[Maix Pyで動作確認]
UnitV AI cameraとPCをUSBケーブルで接続して、MaixPyと連携する手順です。
① MaixPyの左側に上で示したプログラムを貼付ける
② USBケーブルを用いてUnitV AI cameraとPCを接続する。
③ 左下のチェーンを押して、USBのポートを選びます(分からない場合はUSBケーブルを挿す前と挿した後で比較してください)。
④ チェーンの下の再生ボタンを押します。
⑤ 記述したPythonが実行され、UnitV AI cameraが動き出します。同時にカメラが映している映像も右側に表示され、顔を検知すると白い枠で顔を囲みます。
シリアルターミナルでは、検出している顔の座標をシリアル通信で送信している様子を見ることができます(顔が検出できない場合は通信をストップします)。
[LED表示の説明]
UnitV AI cameraのカメラモジュール横にあるLEDが赤色の時は、顔が中心にないことを示し、緑は中心に合ったことを示します。
顔が真ん中にある状態で(LEDは緑)1秒ほど経つと、LEDが白くフラッシュします。これが写真撮影の合図になります。
写真は連番がつけられてフォルダに保存されます。また、電源を入れ直す毎に新しいフォルダを作るようにしました。
3.2 PLEN:bitの準備
目次
・PLEN:bitのプログラム方法
・PLEN:bitの腕制御プログラム
[PLEN:bitのプログラミング方法]
PLEN:bitのプログラミングはMakecode for micro:bitで行います。お腹に搭載しているmicro:bitにプログラムを書けば、その通りにPLEN:bitが動きます。
makecodeでPLEN:bitを動かすまでの手順を説明します。なお、こちらの手順はインターネット環境とWindows, Macいずれも最新のGoogle Chromeが必要です。
① makecodeにアクセスする
② 『新しいプロジェクト』をクリックする
③ プロジェクトの名前を入れて『作成』を押す
④プログラムの作成画面が開く
⑤右上の『⚙』→『拡張機能』を押す
⑥検索スペースに"plen"と入力して検索する
⑦『PLENbit』を押す
⑧ PLEN:bit用ブロックが追加される
⑨USBケーブルを使ってmicro:bitとパソコンを繋ぐ(micro:bitはPLEN:bitに挿した状態でもOK!)
⑩ダウンロードボタン横にある『・・・』を左クリックする
⑪『デバイスを接続する』を左クリックする
⑫ 『デバイスを接続する』ボタンをクリックする
⑬『"BBC micro:bit ********"』を左クリックして『接続』ボタンを押す
⑭ロゴが変化し、ダウンロードボタンを押すとプログラムが書き込まれる
⑮試しに次のプログラムを作成してみましょう。
⑯同様にダウンロードボタンを押して書き込み(書き込み中はmicro:bit裏面の黄色LEDが点滅し、完了すると点灯します)
⑰ボタンを押して動作確認!腕パタパタ〜
[PLEN:bitの腕制御プログラム]
UnitV AI cameraで顔を検出して、その座標をシリアル通信で送ってくれているので、これを使ってPLEN:bit側ではカメラを振って顔を真ん中に写すプログラムを作っていきます。
写っている顔の座標が中心になるよう腕のサーボモータを動かすプログラムです。
ダウンロードはこちらから↓
シリアル通信で入ってきたx, y座標の値を分解し、要素ごとに変数に入れています。その後、ターゲットとなる座標に向くよう腕のサーボモータを制御します。
こちらのプログラムは顔が真ん中からずれていればいるほど早くサーボモータを動かすようにして、速い動きにも対応できるようにしています。
3.3 UnitV AI cameraとPLEN:bitの接続
UnitV AI cameraとPLEN:bitを接続していきます。UnitV AI cameraをPCに接続しているので、ケーブルの接続順に注意が必要となります。
① (実施済み)unitV AI cameraとPCを接続して、Pythonコードを実行しておく
② (実施済み)PLEN:bit用のプログラムをmicro:bitに書き込んでおく
③ unitV AI cameraをPLEN:bitの腕に取り付ける ※現在、ブロック腕はPLEN:bit組立キットに付属していません
④ Groveケーブル(黒・赤・黄・白のケーブルです)の各線をPLEN:bitのお腹端子へ図のように接続する ※ジャンパケーブルを使うと便利です
⑤ PLEN:bitの背中にあるスイッチをONにする(腕を上下左右に動かします)
⑥ UnitV AI cameraにGroveケーブルを挿す
⑦ UnitV AI cameraに顔を認識させて、micro:bitのLED画面の左下が点滅する&PLEN:bitの腕が動き追従していればOK!
⑧ 撮った写真はUnitV AI cameraに挿したSDカードに保存されているので、適宜PCで開いて確認してください
あとがき
今回は腕を振ってカメラを向けるだけでしたが、足を使って旋回するモーションを組み合わせれば、カメラの画角から外れても体の向きを変えてカメラを向けてくれそうです。写真大好きPLEN:bit。
顔認証AI(写った顔から個人を判断)を使えば、家や会社のエントランスのドアと連携して、登録した人だけドアロックを開けてくれるのも可能ですね。
…AIとロボットを組み合わせは、アイデアが止まらなくなりますね。
みなさんのアイデアや、こんなもの作ってみたよ!など、コメントやSNSでどしどし教えて下さい。お待ちしております!
https://www.facebook.com/PLENProjectCommittee
では本日はここまで!最後までお付き合いありがとうございました:)