LoginSignup
11
5

More than 3 years have passed since last update.

Teachable MachineをNoodlで使ってみたメモ

Last updated at Posted at 2020-04-30

Teachable Machineとは

Googleが開発した、ブラウザ上で超カンタンに機械学習できるサービスです。
くわしくはこちら

学習できるもの

すでに色々試されています!
- 画像 参考: 爆速で画像認識ができる!?Teachable Machineでカピバラとビーバー判別をしてみた
- 音 参考: toio を音で制御してみた(Audio用の Teachable Machine でベルやタンバリンの音を機械学習)
- ポーズ 「うちでヨガしよう」ヨガポーズがあっているか判定してくれるLINE bot~Node.jsに読み込む~

ポーズを学習させて、モデルデータを作る

まずはブラウザで学習させてみよう

こちらの記事が参考になります!
Teachable Machine を使った音声からの任意のキーワードの検出(ブラウザ上で機械学習)
ここでは音声を学習させていますが、今回はポーズを選択します。
スクリーンショット 2020-04-24 21.10.23.png

注意!学習中にタブの切り替えをすると止まってしまいます!そのまま、何もせず待ちましょう!

動画入れる

ブラウザ上で、うまく動作することが確認できたら次に進みます。

ちなみに、今回私が学習した、ガニ股検出モデルはコチラで試せます。

モデルデータとScriptのダウンロード

スクリーンショット 2020-04-24 21.19.24.png

  • Export Modelボタンを押す
  • Export your modelのDownloadを選択
  • Download My modelを押してダウンロード。これが学習したモデルデータです。

作成したモデルデータをNoodlで使う

学習させるのが面倒くさい!という方はコチラからモデルデータをダウンロードしてください!

モデルデータを、Noodlプロジェクトに格納する

ダウンロードしたモデルデータを解凍しフォルダごとNoodlプロジェクトに、格納。
Noodlのプロジェクトデータの場所は、歯車アイコン→Open project folderで開くことが出来ます。

格納するデータは3つ
my-pose-model/
- metadata.json
- model.json
- weights.bin

Script Downloaderノードを作成し、ライブラリを読み込む

ScriptDownloaderノードに、<script src="... で読み込んでいるjsライブラリのURLを入れる
この2つのライブラリを、ScriptdownloaderノードのExternal Scriptsに入力
https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.3.1/dist/tf.min.js
https://cdn.jsdelivr.net/npm/@teachablemachine/pose@0.8/dist/teachablemachine-pose.min.js

Javascriptノードを作成し、下記スクリプトをコピペ

元のJSを、NoodlのJavascriptノードの一番下にコピペします。

Javascriptノード

define({
    // The input ports of the Javascript node, name of input and type
    inputs:{
        // ExampleInput:'number',
        // Available types are 'number', 'string', 'boolean', 'color' and 'signal',
        loaded:'signal'
    },

    // The output ports of the Javascript node, name of output and type
    outputs:{
        // ExampleOutput:'string',
        classLabel:'string',
        class1:'number',
        class2:'number'
    },

    // All signal inputs need their own function with the corresponding name that
    // will be run when a signal is received on the input.
    loaded:function(inputs,outputs) {
        init();
    },

    // This function will be called when any of the inputs have changed
    change:function(inputs,outputs) {
        outputs.class1 = class1;
        outputs.class2 = class2;
        this.flagOutputDirty("class1")
        this.flagOutputDirty("class2")
        this.runNextFrame();
    }
})
let model, webcam, maxPredictions, class1, class2;
async function init() {
    console.log('init');
    const modelURL = "my-pose-model/model.json";
    const metadataURL = "my-pose-model/metadata.json";
    model = model = await tmPose.load(modelURL, metadataURL);
    maxPredictions = model.getTotalClasses();
    const size = 200;
    const flip = true; // whether to flip the webcam
    webcam = new tmPose.Webcam(size, size, flip); // width, height, flip
    await webcam.setup(); // request access to the webcam
    await webcam.play();
    window.requestAnimationFrame(loop);
}

async function loop(timestamp) {
        webcam.update(); // update the webcam frame
        await predict();
        window.requestAnimationFrame(loop);
    }

// run the webcam image through the image model
async function predict() {
    const { pose, posenetOutput } = await model.estimatePose(webcam.canvas);
        // Prediction 2: run input through teachable machine classification model
    const prediction = await model.predict(posenetOutput);
    class1 = prediction[0].probability.toFixed(2);
    class2 = prediction[1].probability.toFixed(2);
}

ノードをつなぐ

図のようにノードを作成してつなぎ、数字が出ていれば成功です!
スクリーンショット 2020-04-24 22.05.19.png

WebカメラをNoodl画面に表示する

自分の体がきちんと写っているかどうか、わかりにくいためカメラの映像をNoodl画面に表示します。
- 図のようにWeb CameraノードとVideoノードを作成してつなぐ
- VideoノードのAutoplayにチェックを入れ、Size ModeをContent Heightに変更する。
スクリーンショット 2020-04-24 22.12.24.png

これで、クリックするとWebカメラの映像がストリーム再生されます。

自分がガニ股すると、キャラクターもガニ股するように

下記2枚のイラストをダウンロードし、Noodlプロジェクトに格納してください。(画像をNoodlにドラッグ&ドロップ)
今度は、自分がガニ股したときにガニ股している画像に切り替えるようにしていきます。
c-naruto02500.png
gani500.png
※このキャラクターはナルトの成瀬といいます。

Imageノードを作成し、プロパティを図のようにセットします。
画像の選択は、Sourceプロパティをクリックすると格納されている画像一覧が出てきて直感的に選ぶことが出来ます。
スクリーンショット 2020-04-24 22.15.51.png

先程作ったImageノードをコピペし、Sourceだけガニ股している画像に変更します。
2つの画像が重なっていればOKです。
スクリーンショット 2020-04-24 22.16.06.png

さらに、JavascriptノードとImageノードをつなぎます。
ポーズの判定結果は、各クラスが0-1.0の数値で出力されます。それをImageノードのOpacityにつなぐことで、
ポーズに合わせて画像の切り替えを行います。
スクリーンショット 2020-04-24 22.17.20.png

完成〜〜〜!

いい感じです。少し処理が遅れますね。

11
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
5