はじめに
こんにちは、R&Dチームの加藤です。Raspberry Pi4を買った*1ので、まずは3Dプリンタでケースを作ります。今日はそんなRaspberry Piの話・・・ではなく、AI Markerについて技術寄りに説明したいと思います。
AI Markerとはなんぞや
お時間のある方はこちらのリンクを見ていただくと理解がスムーズです。
とにかく本題に急ぎたい方向けにざっくり紹介するとスマートフォンのカメラを使って二次元バーコードを認識、管理するための製品です。
セールスポイントは以下の通りです。
- スマートフォンと二次元バーコードがあればすぐに開始可能で、運用コストが最小限
- OPTiM AI Cameraなどの自社製品との連携が可能
- 導線分析、顔に依らない個人識別、荷物管理などのシーンで活躍
OPTiM INNOVATION 2019でAI Markerお披露目
2019/10/24-25にOPTiMは初のプラベートショー「OPTiM INNOVATION 2019」を目黒雅叙園にて開催しましたが、AI Markerはこれが初お披露目&初本番投入でした。
会場の様子がこちらになります。赤枠を付けたのがAI Markerの端末です。α版のため今後にご期待ください。
このように、当日はAI Marker検出中の表記がしてありました。
本記事ではこのAI Markerの舞台裏を出血大サービスで紹介します。
必要なスペック
AI Markerに求められるスペックは以下の通りです。
- 必達目標
- カメラはブース上部から取り付ける
- ブースから1メートル程度離れたところにいる人のQRコード*2を読み取りたい
- 約40か所のブースに設置したい(Android端末が運用コスト的に理想)
- 努力目標
- 運用コスト削減のために来場者の参加申込に記載されているQRコードを流用したい
- クラウドでデータを可視化したい
- 来場者にリアルタイムで通知したい(来場ありがとうございますなど)
今回はとにかく時間がない*3かつ本番一発勝負なので、無理せず努力目標は割り切りました。 来場者の参加申込書に記載のQRコードは情報量が多いため、受付で簡易なQRコードを配布することにしました。 それでも、約40か所のブースで来場者が身に着けた小さなQRコードを正確に認識するのは個人的にもかなり挑戦的でした。
技術選定
AI Markerを実現するにあたって、先ほど示したスペックを達成できる技術の選定が必要です。ソフト、ハード両面で課題を解決していきます。
QRコードのライブラリ選定
やはり一番の肝はQRコードの認識精度ですね。今回はいくつかのQRコードのライブラリを候補としてピックアップしました。
- Python
- Java
精度としては、ML Kit>zxing≧pyzbar>OpenCVでした。検出精度が優秀かつAndroidアプリのサンプルコードがあるML Kitを採用しました。
ちなみに、OpenCVのQRコード検出のみ現状でマルチ検出に対応していません。しかし、マルチ検出のプルリクエストが出ているので、気長に待ちましょう*4。
ML Kitは便利
ML Kitを使うことで誰でも簡単にDeep Learningによる物体検出や文字認識が可能になります。
今回は、GitHubにあるquickstart-androidのmlkitを参考にコードをAI Markerを作成しています。
quickstart-android/mlkit紹介
quickstart-androidは非常に多機能ですが、簡単に使用できます。
手元にandroid端末がある方は是非試してみましょう。
インストールは簡単です。
- Android端末は事前に開発者モードにしておく
- quickstart-androidをgit cloneしてくる
- firebaseの設定をして、google-services.jsonをapp直下に配置
- Android Studioでquickstart-android下のmlkitを選択して「OK」
- Android端末をPCに接続し、「
run'app'
」を実行
Android端末にインストールすると言語選択画面が出てきます*5。 流行りはKotlinですが、ここは歴史と実績のあるJavaを選択してみます。
次に画像の取得方法を聞いてくるので、Liveモードにしてみましょう。 カメラが起動します*6。
ここまでくると、好きな検出器を使用できます。 左下の文字をタップすると、色々選べることがわかります。
- Face Contour
- Face Detection
- AutoML Vision Edge
- Object Detection
- Text Detection
- Barcode Detection
- Label Detection
- Classification (quantized)
- Classification (float)
今回は太字の項目を紹介していきます。
まずは顔検出(Face Contour/Face Detector)。
happinessが0.92と高得点ですね(Face Detectorの仕様の詳細はこちら)。
次に物体検出(Object Detection)*7。Foodと正しく認識していますね。
次に文字検出(Text Detection)*8。
個人的にはこの文字検出が一番感動しました。カロリーメイトの「C」が検出できているし、小さい文字も画質が悪くてもそこそこ正確です。
最後に紹介するのはバーコード検出(Barcode Detection)。これです。これが今回使いたい検出器ですね。
OPTiM INNOVATION 2019のAI Markerデモでは、このML Kitのバーコード検出をカスタマイズして使用しています*9。
(おまけ)QRコードの精度向上について
他にも色々試して精度向上を達成していますが、お手軽に精度を向上させる方法を二つ記載しておきます。
一つ目はカメラキャプチャの解像度の変更です。修正箇所は以下の通りです。
--- a/mlkit/app/src/main/java/com/google/firebase/samples/apps/mlkit/common/CameraSource.java +++ b/mlkit/app/src/main/java/com/google/firebase/samples/apps/mlkit/common/CameraSource.java @@ -54,8 +54,8 @@ public class CameraSource { public static final int IMAGE_FORMAT = ImageFormat.NV21; - public static final int DEFAULT_REQUESTED_CAMERA_PREVIEW_WIDTH = 480; - public static final int DEFAULT_REQUESTED_CAMERA_PREVIEW_HEIGHT = 360; + public static final int DEFAULT_REQUESTED_CAMERA_PREVIEW_WIDTH = 1920; + public static final int DEFAULT_REQUESTED_CAMERA_PREVIEW_HEIGHT = 1440;
二つ目は、バーコード検出をQRコードのみに設定しておきます。
--- a/mlkit/app/src/main/java/com/google/firebase/samples/apps/mlkit/java/barcodescanning/BarcodeScanningProcessor.java +++ b/mlkit/app/src/main/java/com/google/firebase/samples/apps/mlkit/java/barcodescanning/BarcodeScanningProcessor.java @@ -22,6 +22,7 @@ import com.google.android.gms.tasks.Task; import com.google.firebase.ml.vision.barcode.FirebaseVisionBarcodeDetector; +import com.google.firebase.ml.vision.barcode.FirebaseVisionBarcodeDetectorOptions; import com.google.firebase.ml.vision.common.FirebaseVisionImage; @@ -46,7 +47,11 @@ public class BarcodeScanningProcessor extends VisionProcessorBase<List<FirebaseV // new FirebaseVisionBarcodeDetectorOptions.Builder() // .setBarcodeFormats(FirebaseVisionBarcode.FORMAT_QR_CODE) // .build(); - detector = FirebaseVision.getInstance().getVisionBarcodeDetector(); + detector = FirebaseVision.getInstance().getVisionBarcodeDetector( + new FirebaseVisionBarcodeDetectorOptions.Builder() + .setBarcodeFormats(FirebaseVisionBarcode.FORMAT_QR_CODE) + .build()); + }
これだけでQRコードの認識精度がある程度向上するので、ぜひ試してみてください。
(番外編)ARマーカーじゃダメなの?
当然ながらQRコードに縛られる必要はありません。ARマーカーのライブラリは現状以下の通りです。
精度としては、ML Kitに並ぶ精度を達成してくれたのですが以下の二つの欠点があり、採用を見送っています。
- Javaで使える商用利用可能な無料のライブラリがない(ライセンス問題)
- 格納できるデータ数が少ない(12bit程度なので、複数のARマーカーを組み合わせたりする必要)
どちらも自作で解決しますが、今回は開発期間の関係で見送りました。
取得したQRコードの管理
当然ながら、QRコードを使って来場者の行動分析が目的なのでQRコードキャプチャを作っただけではダメです。QRコード管理の全体の流れを以下の図に示します。
- QRコードをキャプチャ
- 一定時間ログを確保
- ログを定期書き込み
ここからは私がつまずいたポイントについて、ソースコードを交えつつ紹介します*10。
時刻の取得
SimpleDateFormatを使用して時刻を取得しました。"yyMMdd-HH:mm:ss"は2019年12月23日の12時34分56秒を例にすると、"191223-12:34:56"となります。
public String getTime(){ Calendar c = Calendar.getInstance(); SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd-HH:mm:ss", Locale.JAPAN); return sdf.format(c.getTime()); }
ファイル名の決定
約40台の端末のログを解析する必要があるので、Android IDを利用してそれぞれ固有のファイル名を設定するようにしました。
今回の端末はAndroid Oで40台同じ機種となるので、別々のIDが払い出されることを確認して採用しました。
public String getUniqueID(){ return Settings.Secure.getString(mContext.getContentResolver(), Settings.System.ANDROID_ID); }
Android IDについては色々苦労ポイントがありますが、気になる方は以下を読んでみてください。
ファイルストレージへの書き込み
ファイルに追加書き込みします。CSV形式で書き込みをしています*11。
public boolean write(String start_time, String qr_code, Integer cnt, Integer chk) { OutputStream out_stream; StringBuilder buf = new StringBuilder(); buf.append(getTime()); buf.append(", "); buf.append(qr_code); buf.append(", "); buf.append(cnt.toString()); buf.append("\n"); try { out_stream = new FileOutputStream(new File(file_name), true); PrintWriter writer = new PrintWriter(new OutputStreamWriter(out_stream, "UTF-8")); //追記する writer.append(buf.toString()); writer.close(); } catch (IOException e) { e.printStackTrace(); } return true; }
Android端末を接続した状態でAndroid StudioでDevice File Explorerをクリックすると、図のようにログを見つけられます。 ここから直接PCに取り込むことも可能です。
ハードウェア選定
約40か所のブースに設置するので高価な端末をホイホイ用意したら大赤字です。
今回はFPSも1~3FPS程度あれば十分なので、比較的安価に入手できる AQUOS 702SHを採用しました!
主なスペックは以下の通りです。
- 液晶:5in IGZO IPS液晶(1920×1080)
- OS:Android 8.0
- CPU:MSM8937 1.4GHz/1.1GHz
- メモリ:3 GB
- ストレージ:32 GB
- カメラ:約1310万画素/CMOS
耐久テスト
AI Markerは少なくとも半日安定して動作する必要があるので、耐久テストを実施して問題がないか確認する必要があります。 今回はAI Markerの耐久試験の様子を撮影してみました。
- おもちゃの回転寿司レーン(回転寿司)にQRコードを貼り付けて来場者を模擬
- 会場は様々な光源が予想されるので、(手動で)ライトを点滅させて動作に問題がないか確認
- QRコードが認識されると、赤枠で表示
- 回転寿司の電池が切れるまで(10時間くらい?)動作
さて、耐久テストもバッチリだったのであとは本番を迎えるだけですね。
いざ本番
本番は大きなトラブルなく無事に検出できましたが、いくつかトラブルや課題が発生したので振り返っておきます。
電源抜けでバッテリー切れ
会場の写真や耐久テストにも映り込んでいるのですが、AI Marker(ML Kit)は電池消費が激しいため充電し続ける必要があります。 しかし、とあるブースで充電ケーブルが抜けておりAI Markerが短期間停止しました。バッテリーが少なくなったらアラートを出す仕組みが必要ですね。
QRコードが服に隠れて認識できない
QRコードは2種類用意していて、来場者の方々には以下のルールで付けていただく想定でした。
- 胸ポケットのある方は右の大きいQRコードを胸ポケットに
- 胸ポケットのない方は名刺サイズのQRコードを胸の付近に
これは実際に運用して気が付いたのですが、ジャケットの襟や胸ポケットにQRコードが隠れる事例が散見されました。
QRコードは誤り訂正があるので一部の汚れ等には強いですが、一定の領域が隠れてしまうとダメでした。
これは我々の考慮不足なので、QRコードの余白を大きくするなど製品版では改善していきます。
動作確認が大変
当日は私が1台ずつ設置していたのですが、Android Studioでデバッグしながら動作確認していました。 クラウドにデータをUPしたり、QRコードを認識するとランプが点灯したりも考えたのですが、間に合いませんでした。 当然ながら、製品版では対策が必要になります。
ログデータ解析と成果物
さてさて、本番も無事に終わり大量のログデータが収集できましたが、ここからがAI Markerの本領発揮です。 ということでこのログデータを使用して来場者の方々へお礼メールを送り、さらに各ブースの来場者数の傾向をみていきます。
お礼メール作成
約40台のAI Markerを活用することで、来場者の方がどんなブースにどんな順番でどれくらい滞在したのか分析できます。トラッキングですね。このトラッキング情報をもとに、「こういうのも興味あるんじゃないかな」という予測もしていきたいですね。 OPTiM INNOVATION 2019では、その結果を来場者の方にメールで配信しました*12。 メールはこのような形で送信されました。
オプティム 太郎 様 この度は、OPTiM INNOVATION 2019にご来場いただきありがとうございました。 OPTiM AI Marker により、AIが オプティム 太郎 様 の立ち寄られた展示を分析いたしました。 対象の展示ブースの資料をお送りいたしますのでぜひご覧ください。 お立ち寄りいただいたブース
医療系ソリューション | ||
AMIAS | 2019-10-25 10:41:47から 228秒ご滞在 | [PDF] [Web] | OPTiM Doctor Eye | 2019-10-25 10:45:37から 38秒ご滞在 | [PDF] [Web] |
農業系ソリューション | ||
革新的技術開発事業 | 2019-10-25 10:58:03から 53秒ご滞在 | [PDF] [Web] | 災害支援ソリューション | 2019-10-25 10:59:52から 50秒ご滞在 | [PDF] [Web] | スマート農業 プロフェッショナルサービス | 2019-10-25 11:00:33から 76秒ご滞在 | [PDF] [Web] | DRONE CONNECT | 2019-10-25 11:01:30から 77秒ご滞在 | [PDF] [Web] | SMART AGRI | 2019-10-25 11:02:33から 12秒ご滞在 | [PDF] [Web] |
OPTiM AI Industry | ||
for 銀行(佐賀銀行) | 2019-10-25 10:15:54から 216秒ご滞在 | [PDF] [PDF] | for 駅(TOA株式会社) | 2019-10-25 10:18:57から 176秒ご滞在 | [PDF] [Web] |
AIサービス | ||
OPTiM AI Camera | 2019-10-25 10:14:39から 34秒ご滞在 | [Web] | OPTiM AI Research | 2019-10-25 10:30:19から 216秒ご滞在 | [PDF] [Web] | OPTiM AI Signage | 2019-10-25 10:37:10から 154秒ご滞在 | [PDF] [Web] |
プラットフォーム | ||
OPTiM Cloud IoT OS | 2019-10-25 10:39:59から 48秒ご滞在 | [PDF] [Web] |
このようにして、全自動で来場者の方の一人一人に最適化されたメールを送れるのはAI Markerの強みです。
ブースの分析
AI Marker では、来場者ベースのトラッキングだけでなく、ブース単位での集計も可能です。 OPTiM INNOVATION 2019のブースごとの来場者数はこのようになっています*13。 他にも、時系列でログデータが残っているので各ブースの時系列の来場者推移も可視化できます。
現在はリアルタイム解析まではできていませんが、それができればAI Markerの可能性はさらに広がります。
以上でAI Markerの紹介は終わりますが、みなさんAI Markerの可能性を感じることができたでしょうか?OPTiM INNOVATION 2019での事例はほんの一例です。みなさんのアイデア次第でAI Markerは化けますので、是非一緒にイノベーションを起こしていきましょう!
最後に
OPTiMでは、業種職種問わずチャレンジャーなエンジニアを募集しています。体力系エンジニアの方々は是非一緒に皇居を走りましょう。
*1:Type-Cの不具合は解消されていたので、早速ポチりました
*2:QRコードはデンソーウェーブの登録商標です
*3:イベント当日まで1か月程度しかない
*4:記事公開時(19/12/24)にて確認
*5:AI Marker開発時点では白画面でタイトルもありませんでしたが、最近のバージョンはUIが進化していますね
*6:初めて実行する場合は権限を聞かれるかもしれません
*7:最近クランチにハマっています。サクサク食べられるので食べ過ぎには注意しましょう。
*8:みんな大好きカロリーメイト(チョコレート)ですね。私の朝ごはんです
*9:今後も採用するかどうかは未定です
*10:Java歴1か月なのでお手柔らかにお願いします
*11:本来であれば暗号化等もしっかりやるべきですが、α版なので
*12:データの取得が上手くいった方にはメールが届いていると思います
*13:一部ボカしています