MLTweetこんにちは!忘年会エンジニアのたかぱい(@takapy)です。コネヒトの忘年会は例年気合いが入っており、有志メンバーが運営となり1年の締めくくりを最高のものにすべく、尽力しています。今回は2019年の忘年会を技術で盛り上げるべく、同じく忘年会エンジニアのあぼ氏(@abo)と奮闘したことをご紹介できればと思います。前回(2018年)忘年会時に、弊社エンジニアにより「パシャりんピック」という歓談タイムを盛り上げるコンテンツが爆誕しました。社員同士でツーショット写真を取る社員1人1人に点数が初期設定されており、写真に写る人物によってその写真のスコアが算出される最終的に獲得スコアの一番高い人の勝ち(たくさん撮った人が有利)というものです。(詳しくは下記参照)tech.connehito.comこのコンテンツの評判がとても良かったので、今回はこれをアップデートさせる形で忘年会を盛り上げてやろうと画策しました。今回のコンセプトそもそものコンセプトが明確だったので、今回はこれに「笑顔」要素と順位と写真の見える化をプラスすることで、より盛り上がるコンテンツに仕上げようと決めました。大別して下記2点です。リーダーボードの実装(主にあぼ担当)スコア算出方法のアップデート(主にたかぱい担当)それぞれについて、全体の構成図も交えながら説明していきます。アーキテクチャ以下のようなアーキテクチャを構築しました。システムアーキテクチャ使用した技術は下記です。GCPAzurePythonFirebaseFlutterリーダーボードについて(byあぼ)今回は"人"と"写真"の2つに対して点数がつくので、点数上位の人と写真がリアルタイムで見られるようにリーダーボード(スコアボード)を作りました。リーダーボード使用技術ですが、今回はFlutterをweb上で動かしました。私がFlutterを趣味で使っているので知見があり、好きなので開発するやる気が出る保守性を考えなくても良いアプリケーションである最悪ローカルの環境で特定のブラウザでさえ動けば良いという理由で採用しました。基本的にリーダーボード側はFirestoreから購読した値を画面に表示するだけなので、そこまでやることは多くありません。Firestoreの購読にはStreamBuilderを使って、UIはRowとColumnを駆使して組み立てていきました。リーダーボードのメインのUIとは別に、当日の忘年会進行スライドとの統一感を出すために、画面右上に忘年会のロゴを表示させました。今回はStackという、Widgetを重ねられるWidgetを使って実現しました。Stackを使うことで"ロゴ"表示とメインコンテンツの"スコア"表示部分のレイアウトが分割されるので、個人的にはこっちのほうが好みです。}}Firebaseの機能を使えるようにするそれから、Firebaseの機能を使うのに一工夫必要だったので紹介します。Hostingで動かしました。設定はfirebaseコマンドを使ってサクサクと行えます。firebase.jsonではpublicにbuild/webを指定します。webでweb用のリリースビルドが生成される場所です。packagesからFirebaseパッケージをインストールするのに加えてweb/index.htmlのscriptタグでjsファイルを読み込ませるようにしました。この辺はFirebaseをJavaScriptアプリケーションにインストールするドキュメントを参考にしました。これでFirebaseの機能が使えるようになりました。(byたかぱい)忘年会エンジニア兼・機械学習エンジニアなので、スコア算出に機械学習の要素を取り入れました。「笑顔」という時点で察している方もいらっしゃると思いますが、写真に写る人物の笑顔度合いを数値化してスコア算出を行いました。本来であれば、複数の写真(学習データ)を用意して、笑顔度のアノテーションをして、学習させて・・・というフローが必要なところですが、今のご時世APIを1つ叩くだけでやりたいことができます。APIを使用しました。SDKがあり、普段Pythonを触っている人であれば比較的スムーズに使用できるのではないかと思います。画像をpostしてレスポンスを受け取る場合は下記のように記述します。call_api(image_url)ここから笑顔の値を取得したい場合は下記のように記述します。response.json()[0]['faceAttributes']['smile']これで笑顔度(0〜1)を取得することができます。試しに何枚か写真を撮って笑顔度を算出してみると、ある問題に気付きました。「割と簡単に最高値が取得できてしまう🤔」これでは盛り上がるコンテンツにならないのでは?と思い、とあるロジックを追加しました。それは「写っている人物の鼻端が近ければ近いほど、高得点になる」というもので、これを「仲の良さ」と銘打ってスコア計算に組み込みました。鼻端のx座標、y座標に関しては上記のAPIを使用すれば取得できるので、「近さ」の定義だけ考えました。通常であればユークリッド距離を計算すれば良いのですが、ハックできる要素を含ませた方がコンテンツとして面白いのでは?と思い、x座標の差分の絶対値を「近さ」の定義として計算することにしました。以下が「近さ」を考慮したスコア計算例です。width)このようにすることで、隣り合う2人の距離(鼻端のx座標)が近ければ近いほど高得点が出るようにしました。やってみてどうだったか「笑顔」という条件を提示することで、いろんな人の様々な表情を垣間見ることができました!と同時に、今回はリーダーボードがほぼリアルタイム*1で更新されたので、リーダーボードに映っている、スコアの高い写真を参考にどのように写真を取れば高得点が叩き出せるか試行錯誤するという一味違った体験を提供することができ、大盛況に終わることができたのではないかと思っています!想定外だったことといえば、先にも述べた通り開始10分くらいでハックされたことです(汗)今回はx座標のみスコアに寄与するため、横並びではなく、縦並びで写真を撮るとかなり高いスコアを叩き出すことができます。ohayoukenchan...2021-12-23APIクライアントをAPIKit+RxSwiftからURLSession+Combineにしました(...こんにちわ。Monitoringを活用したパフォーマンス可視化こんにちは。(2)書いたメンバーid:taxa_programid:katsutomu0124id:sasashuuuid:NahomiTakahashiid:toc8id:yoshitaka465id:yanamuraid:ryoutakaya3623id:azuki_mihomihoid:takflifeid:nagaisid:aboy_perryid:laugh_kid:connehito-mkashiwagiid:tommy_kwid:itosho525id:su-kun1899id:ohayoukenchanid:satoshieid:plane25id:connehitoid:fortkleお問い合わせコネヒト株式会社Wantedly引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。