Loading
BLOG 開発者ブログ

2021年12月17日

ハッカソンでIoT✖️機械学習✖️クラウドなアプリケーションを作ってみた勘所まとめ

Raspberry PiによるIoT、機械学習を使った顔分析を取り入れたアプリを、Azure Functionsを使ってクラウドネイティブに構成しました。
その際の学びを共有します。

こんにちは。
クラウドソリューショングループのkato.shunです。
この記事は アイソルート Advent Calendar 2021 17日目の記事です。
ハッカソン・リーグ2021
こちらのハッカソンでRaspberry PiとFace APIを使ったアプリをクラウドネイティブな構成で作りました。

参加したのは自分を含め4人で、全員同じシェアハウスに住む同年代の男の子です。
二日間という短い作成期間でしたが、詰まった点がいくつもあったのでまとめます。

IoTや機械学習に触れたかったり、クラウドネイティブなアプリを作ってみたい方は参考にしてください。
余談ですが、ハッカソンの結果は優秀賞でした。

目次

  1. アプリの紹介
  2. Cloud Nativeなアプリの作り方
  3. Face APIの使い方
  4. Raspberry Piの使い方
  5. やってよかったこと


アプリの紹介

今回作ったアプリは、「得笑い」です。
基本コンセプトはシェアハウス内の空気を良くした人に得をさせるアプリです。

実際には、カメラで観測し、ある人の周りに笑顔の人がたくさんいることで、
その人にポイントが付与されるという仕組みで実現しました。

もう少し、細かく説明すると
アプリケーションのユーザー登録時に顔写真を5枚送ってもらい、その画像から機械学習を行い顔のモデルを作成します。

その後、自作した定点カメラから定期的に送られてきた画像を認識し、作成したモデルを用いて「誰がいて」「笑顔度がどのくらいか」というデータを取得します。
その結果をもとに、笑顔がたくさん認識された場所にいたユーザーにポイントが発生するという流れです。

すごく簡単にですが構成図を作りました。

ソースコードも公開しているのでよければご覧ください。
https://github.com/d-nakajima/azure-hackathon

デプロイもしました。(現在停止中)
https://tokuwarai.azurewebsites.net/mypage

また実際のデータの流れをシーケンス図にまとめたのでご覧ください。


Cloud Nativeなアプリの作り方

Cloud Native(クラウドネイティブ)とは、単純にオンプレのインフラをクラウドに乗せるだけでなく、クラウドの機能や利点を最大限利用して、
最小コストで柔軟性のあるアプリを作り上げる構成のことです。

色々な実現手段がありますが、今回はAzure Functionsを使ってデータのやり取りを行い、
Azure Static Web Appsを使ってフロントの画面のコードをホスティングしました。

Azure Static Web Appsの方はこちらのチュートリアルで学習した後、
公式のドキュメントを見ながら作成しました。

Azure Functionsの方も公式ドキュメントで基本的な使い方を学べば、VSCodeとAzureの連携が神がかっているのでそこからは意外とすんなり構築できました。

以下参考公式ドキュメント
https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-develop-vs-code?tabs=csharp

ボタンひとつでデプロイができたときにはかなり感動ものでした。

詰まった点

詰まった点としてはローカルのものをデプロイしたときに、初回起動設定の中でpm2コマンドを実行するのを忘れて動かなかったことです。
最終的には以下の記事を参考に解決しました。
https://stackoverflow.com/questions/61377340/react-router-direct-links-not-working-on-azure-web-app-linux


Face APIの使い方

Face APIは機械学習の予備知識なしで、顔の認識やその顔の情報を予測することを可能にしてくれるAzureのサービスです。
AzureのCognitive Servicesの一機能として提供されています。

学習には以下の記事たちを利用しました。
公式チュートリアル
公式ドキュメント

jsですが以下も参考にしました。
Face APIを使った感情分析
今回のハッカソンで最も時間を使ったのがこちらでした。

詰まった点

画像をHTTPリクエストの中に入れるときに、base64に変更する部分に一番時間を使いました。
細かいことは記事に丸投げしますが、簡単に説明すると

画像をHTTPリクエストに入れるときに、バイナリデータのままだと送れないので
base64という文字列型に変換してから送信しなくてはいけませんでした。
最終的には以下の記事達によって解決しました。

https://docs.python.org/ja/3/library/base64.html
https://www.naka-sys.okinawa/python-b64/
https://rikoubou.hatenablog.com/entry/2021/06/29/140911


Raspberry Piの使い方

Raspberry Pi(以降ラズパイ)とは元々、教育利用を想定して作られた
安価なシングルボードコンピューター(剥き出しの基盤の上に必要最低限の部品をくっつけたコンピューター)です。

今回の制作物では定点カメラの作成とそのデータを前述のFunctionsに投げるところまでを担当しました。

基本的な作り方はRaspberry PiにWebカメラを接続し、OpenCVでカメラを認識+撮影
OpenCVとPillowで画像を送信用の形に変換し、HTTPリクエストの形でAzure Functionsにデータを投げます。
その一連の流れをCronを使って定期実行するようにしました。

詰まった点

Cronでの定期実行の時に、pythonのコードを実行できなくて困りました。
問題としては、Cronの実行時に呼び出されている環境変数が、デフォルトのものとは違うことでした。

最終的には以下の記事を参考に解決しました。
cronジョブでの環境変数設定について、と色々cronについて補足
余談ですが、発表の直前にこの問題が出てきてとても焦ったのを覚えています。


やってよかったこと

二日間のアプリ作成時間の中で完成まで持っていくというかなりの無茶なスケジュールだったのですが、
それに不可欠だったのが、最初にシーケンス図を作成したことです。

何をどのように作るか明確にしていくことで、その後の開発効率がかなり向上したという自覚があります。

以下の記事を参考にplantUMLを使って作成しました。
MacでVSCode+PlantUMLを用意する

また、事前勉強期間1ヶ月を設定してみんなでチュートリアルをやり込みました。
この期間も結構時間が取れなくて大変でしたが、やらなかったら絶対に完成しなかったと思います。

以下で本記事は終了です。
今後もハッカソンに出場した際は学びを共有していこうと思います。
前回のハッカソン出場記事はこちら