Purchased an ESP-EYE (ESP32 MCU + 2 MP camera) board and tried face recognition by it.
先日の日記に書いた TensorFlow Lite のほうは現在も勉強中ですが、そちらのほうはお客様への報告義務があったりするので、代わりに ESP-EYE というガジェットを試した報告をさせて頂きます。最近同じく話題の Sipeed M1 のほうは報告がたくさん上がっているのですが、なぜか ESP-EYE のほうは少ないようです。
実は、私が最初に見つけたのは ESP-WHO に関する記事だったのですが、ESP-WHO は現状、Espressif の IDF(IoT Development Framework)と呼ばれるツールのインストールが必要で、Arduino で簡単に遊んでみることはできません。
いえ、実は ESP-WHO のドキュメントを読んで実験してみたのですが、まだうまく動かせておらず、何はともあれ ESP-EYE ボードそのものが正しく動いているか確認したかったので、まずは Arduino 環境で動くサンプルコードを試してみた、というのが実際なところです。
ちょっとキーワードがたくさん出てきたので整理します。
- ESP-WHO: これは世界保健機関とは関係なくて、どうやら WHO は「誰(who)」の意味のようです。ESP32 マイコンで有名な Espressif 社が開発している、ESP32 マイコンのための顔検出 + 顔認識のためのライブラリです。詳細はここを御参照ください。現状は Arduino では動かず、上述の IDF で C, C++ コンパイラを使って開発する必要があるようです。
- ESP-EYE: こちらは、マイコンボードの名称です。ESP32 マイコンボードの上に、8Mバイト の PSRAM 、4Mバイトのフラッシュ ROM、それに加えて 2メガピクセルのカメラ OmniVision OV2640 を搭載しています。価格は US$ 19.90 です。実は、以前から Ai-Thinker 社の ESP32-CAM というものがあったのですが、Espressif 社が発売した同等製品が ESP-EYE らしく、似た機能を持ちますが、おそらく回路は別です。(互換性なし?) ちなみに、ESP32-CAM には USB コネクタが無いそうですが、ESP-EYE には USB コネクタがあるので、Arduino から簡単にプログラムをフラッシュ書き込みできます。
余談: ところで、ESP32-CAM には外部にいくつかピンが出ているので工作が容易そうなのですが、ESP-EYE では SPI しか外部に出ていません。おまけにテストパッドの形になっていて、工作はちょっと面倒そう(こちらの写真右参照)です。(涙)
ESP-EYE お披露目
さて、ESP-EYE とはこんなものです。
右は、サイズ比較のための iPhone 6 Plus です。
その他、いくつか写真です。
ESP-WHO は(簡単には)動かなかった
さて、お約束(?)ですがマニュアルは付属していないので、ネットで情報を探します。前述のように、最初は ESP-WHO を試したのですが、私の試したバージョン(https://github.com/espressif/esp-who.git: 258751b の examples/single_chip/recognition_solution)が良くなかったのか、GCC 5.2.0 でビルドはできたものの、動作が確認できませんでした。ボードを起こすのに中国語で話しかけないといけないというのが最初の難関。私がいくら話しかけても反応せず(泣)、やむを得ず当該部分(話しかけたら次の動作に移る)をコメントアウトしてみたものの、うまくウェブサーバーとお話できませんでした。
Arduino のサンプルプログラムを試す
という訳で、まずは別のサンプルプログラムを試します。ESP32 Arduino 1.0.1 に含まれる CameraWebServer というものです。
こちらを参考に ESP32 用の Arduino をインストールしますが、その際、最新の 1.0.2 ではなく、1.0.1 をインストールしましょう。(Arduino では、複数の異なるバージョン「1.0.1」,「1.0.2」をスイッチすることは難しくないので、御安心ください。) ちなみに、なぜ 1.0.2 ではダメかというと、こんな記事を見つけたから(?)です。将来のバージョンでは解決するかも知れませんが、若干ひと月前の情報なので、おとなしくこれに従います。
Arduino IDE でサンプルプログラムをビルドするときの注意点をいくつかまとめます。
- ターゲットボードの種類としては ESP32 Wrover Module を選びます。
- 正しい COM ポートを選びます。(私の Mac OS では、/dev/tty.SLAB_USBtoUART)
- Partition Scheme には Huge APP (3MB No OTA) を選びます。これは、今回のサンプルプログラムが非常に大きな ROM を使うためです。
次にフラッシュを焼く際の注意ですが、Adafruit の HUZZAH32 – ESP32 Feather 等とは違って、フラッシュ書き込みする際に BOOT ボタンを押す必要があります。タイミングが良く分からない場合のヒントを示します。
1. とりあえず、サンプルプログラムをビルド(コンパイル)しておきます。
2. シリアルターミナル(私の場合は screen /dev/tty.SLAB_USBtoUART 115200)を起動し、ボード上の BOOT ボタンを押しながらリセット(RST)ボタンを押します。すると
rst:0x1 (POWERON_RESET),boot:0x3 (DOWNLOAD_BOOT(UART0/UART1/SDIO_REI_REO_V2)) waiting for download
のような表示が出ますので、シリアルターミナルをクローズ(終了)し、Arduino のメニューから Sketch → Upload します。
たぶんこれで、正しくアップロードできるはずです。何回か試すと、BOOT ボタンを押すタイミングが摑めるはずです。
サンプルプログラムの修正
あ、順序が逆になりましたが、1.0.1版のサンプルプログラムはそのままでは ESP-EYE で動かないので、修正が必要です。詳しくはこちらを参考にして頂きたいと思いますが、変更点を簡単にまとめておきます。
1. どのボードを使うかという define 文を直します。ESP32 Arduino の 1.0.1 版のサンプルコードは、そのままでは ESP-EYE に対応していないので、先頭付近を次のように修正します。
// Select camera model //#define CAMERA_MODEL_WROVER_KIT //#define CAMERA_MODEL_M5STACK_PSRAM //#define CAMERA_MODEL_AI_THINKER #define CAMERA_MODEL_ESP_EYE
2. 続いて、
#else #error "Camera model not selected" #endif
の直前に、
#elif defined(CAMERA_MODEL_ESP_EYE) #define PWDN_GPIO_NUM -1 #define RESET_GPIO_NUM -1 #define XCLK_GPIO_NUM 4 #define SIOD_GPIO_NUM 18 #define SIOC_GPIO_NUM 23 #define Y9_GPIO_NUM 36 #define Y8_GPIO_NUM 37 #define Y7_GPIO_NUM 38 #define Y6_GPIO_NUM 39 #define Y5_GPIO_NUM 35 #define Y4_GPIO_NUM 14 #define Y3_GPIO_NUM 13 #define Y2_GPIO_NUM 34 #define VSYNC_GPIO_NUM 5 #define HREF_GPIO_NUM 27 #define PCLK_GPIO_NUM 25
と追加します。
3. void setup() { という行の直後に
#if defined(CAMERA_MODEL_ESP_EYE) pinMode(13, INPUT_PULLUP); pinMode(14, INPUT_PULLUP); #endif
と追加します。
4. これまたプログラムの先頭付近に戻り、
const char* ssid = "あなたの Wi-Fi AP の SSID"; const char* password = "あなたの Wi-Fi のパスフレーズ";
というように修正します。
実際に動かしてみる
再度シリアルコンソールを接続し、ボードの RST ボタンを押すと、次のような表示が出るはずです。
WiFi connected Starting web server on port: '80' Starting stream server on port: '81' Camera Ready! Use 'http://192.168.100.200' to connect
改行が乱れるかも知れませんが(ターミナルソフトの仕様による)気にせず、パソコンのウェブブラウザで上記 URL(http://192.168.100.200)を開きます。この IP アドレスは、環境によって異なるので、御自分の表示を確認してください。
Start Stream ボタンを押して、こんな画面が出れば、少なくともカメラは動いています。
顔認識と識別をしてみよう
まずは顔認識をしてみましょう。
まず最初に、上記画面のメニューで、Face Detection と Face Recognition をオン(スイッチを右にスライド)します。そして、カメラをある程度、顔から離して覗き込むと、顔の周りに黄色い四角が表示されます。
実際には、あまり認識精度が良くないので、最初はうまくいかないかも知れません。一つ目のヒントは、部屋の照明を明るくすることです。二つ目は、顔を少しカメラから離すことです。(何かのドキュメントによると、30センチ以上は離すと良いようです。)
慣れると認識できるようになります、、、というか、本当はもう少し高い認識精度が欲しいところですね。Espressif 社の今後の改良に期待です。
ちなみにこれは、私の Facebook にある写真です。「あ、増毛駅だ!」とか、あまり気にしないでくださいw
次に顔の識別です。そのためには、画面の Enroll Face というボタンを押します。そして、カメラを眺めていると、画像の上の方に何度か、ID[何番] Sample[何枚目] という表示を繰り返し、顔を覚えてくれます。
その後は、カメラを覗くと何番の顔を認識したか、という結果を表示してくれるようになります。
これはあくまでサンプルプログラムなので、実際にはもう少し工夫して、同じ人物の異なる写真をたくさん用意し、学習させてあげたいところです。
今日の結論
わずか 2,000円強のマイコンで、顔認識結果を Wi-Fi 経由で出力できるとは、はっきり言って驚きです。最近の深層ニューラルネットワークは、既に研究段階を「卒業」して、われわれが身近なマイコンアプリの中に組み込むことができるようになっているわけですね。もちろん、今までもスマートフォンを使えば顔認識はできましたが、これを安価なマイコンで実現し、さらに容易にカスタマイズして応用製品を設計できる、というところがポイントではないでしょうか。
もう一つの結論
顔認識のデモやブログを書くときは、ちゃんと無精ひげくらい剃っておかないとカッコ悪いですね。
というわけで、今日はここまで。