ジェイソン・ステイサムに「死にたくないなら手を挙げろ!」と言われるのが夢だったので、自分でそんなアプリを作りました。


こんにちは!Qiita内で「ジェイソン・ステイサム」というタグを着々と育てているたわちゃんです♪
今回も、ステイサム関連のWebアプリを作ったので、ご紹介いたします!

アプリを作ろうとした背景

ブラウザで機械学習が利用できるml5を勉強中。
何かアウトプットできないかなぁと思ったときに、このツイートを発見!

私も大好きなマクロスF!!!ぶちあがるぅぅぅ!!!

やはり自分が好きなものをテーマにするのが勉強するにもやる気が出る!と思い、
大好きなジェイソン・ステイサムをテーマにすることに決定!

上の作品のように、ポーズを検出して反応するようなものを作りたいなと考えました。

そこで、私はいつかステイサムに銃を向けられて「手を挙げろ!」と言われるか、
手榴弾を投げられた後に「伏せろーーー!!!」と言われることが夢だったので、
前者の夢をアプリで叶えることにしました。

作り方

Teachable Machineで手を挙げている状態を学習させる

Teachable Machineとは、自分で学習モデルを本当に簡単に作れるもので、
画像・音声・ポーズの3種類のプロジェクトがあります。
https://teachablemachine.withgoogle.com/

こちらを使って、手を挙げているポーズを学習させようとトライしました!

足をつりながら作成を頑張ったのですが、完成したところでポーズはml5に未対応ということが判明・・・。

画像プロジェクトで代用することにしました。

上記のように、2つ以上のClassを作成してトレーニングボタンを押すだけ!超簡単!

私は、以下のようにClassを作成しました。
▶Hands Up・・・手を挙げている状態
▶none・・・何もしてない、あるいは片手だけ挙げている状態

モデルのトレーニングが終わったら、エクスポートボタンを押して、アップロードするだけでリンクが発行されます!

初心者の私でも簡単に学習モデルを作ることができました!

ml5で学習モデルを読み込む

次に、作った学習モデルをml5で利用できるようにします。

    <script>
      // Teachable Machineで作ったModelのURL
      const imageModelURL = 'https://teachablemachine.withgoogle.com/models/id9DYiz3Y/';

      async function main() {
        // カメラからの映像取得
        const stream = await navigator.mediaDevices.getUserMedia({
          audio: false,
          video: true,
        });
        // html内のidがvideoのdomを取得
        const video = document.getElementById('video');
        // videoにカメラ映像を適用
        video.srcObject = stream;

        // 自作モデルのロード
        const classifier = ml5.imageClassifier(
          imageModelURL + 'model.json',
          video,
          modelLoaded
        );
        // モデルのロード完了時に実行される
        function modelLoaded() {
          console.log('Model Loaded!');
        }

これでTeachable Machineで作ったモデルを読み込み、
ブラウザ上でリアルタイムに映像を処理できるようになりました!

手を挙げていないときに銃声が鳴るようにする

「死にたくないなら手を挙げろ」なので、手を挙げていないと撃たれるようにしましょう。

まず、音源は https://soundeffect-lab.info/sound/battle/battle2.html から実際の銃声を録音した効果音をいただきました!
色々な効果音素材を聴き比べたのですが、こちらのサイトはリアルな銃声がそろってて興奮しました・・・!!!

音を鳴らす方法は、下記を参考にしました。
https://syncer.jp/html5-javascript-hello-button

先述した通り、手を挙げていない状態のlabelは「none」なので、
「none」が出たときに音が鳴るようにします。

 if (results[0].label === 'none') {
   // [FIX] sound 関数実行
    sound();   
}

仕上げにUIを整える

いつもライブラリを使ってズルしちゃうのですが、今回は自力でCSS書いてみました。

全体像はこの後に載せているデモをご覧いただきたいのですが、
デンジャラスな感じのUIにしたかったので、背景は赤色にしました!

そして、少しばかりの遊び心を取り入れるために、吹き出しに挑戦!
いい感じにできました♪

参考サイト ▶ https://saruwakakun.com/html-css/reference/speech-bubble#section1

完成したもの

そんなこんなで、完成したものがこちら!

URL ▶ https://jovial-johnson-e7befb.netlify.app/handsup (PCのみ)

念願叶って、ステイサムたんに撃たれることができました。
(両手挙げながらだと動画撮れなかったので、ぜひご自身で体験してみてください♪)

検出の精度が低いので、たまに手を挙げてても撃ってきます
気まぐれステイサムです。キマグレン。

(追記)私の写真だけで学習したので、どうやら他の人だと比較的ずっと撃たれまくるらしいです。笑

Gifhubにソースコードも載せてるので、興味ある方はぜひご活用ください~。
CSSレベル低くてすみません。笑

ソースコード ▶ https://github.com/twtjudy1128/hands-up

おわりに

機械学習と聞くと難しいイメージがありますが、
ライブラリを活用したら、プログラミング歴2ヶ月の私でも簡単に扱うことができました!
発想次第で色んなことができるなぁと思ったので、とても良い勉強になりました。

また、CSSも定期的に触らないと忘れていくなと思ったので、意識的に使っていこうと思います!
センスが欲しいぜ・・・!

今日もプログラミングを楽しく勉強させてくれたステイサムたんに感謝です♪

最後までご覧いただき、ありがとうございました!

(*^^)v「よろしければLGTMも宜しくお願いします!」