16
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

atWareAdvent Calendar 2020

Day 11

ml5.jsを知っているかい?

Posted at

はじめに

@makky0620 くんが ビデオツールなどの背景機能をReactとTensorflow.jsで再現してみる という記事を書いていました。
まぢすごい:relaxed:まぢ尊敬:relaxed:と思うような内容でしたが、
ちょっと僕には量子?モデル?よく分からん!というところも…

スクリーンショット 2020-12-10 19.46.21.png

そんな私にml5.js

ml5.jsはアーティストやクリエィティブ・コーダー、学生などの幅広いユーザーが機械学習を親しみやすく触れるられるように作られたライブラリです。TensorFlow.js がベースになっています。また、p5jsからの影響を受けて制作されています。

つまりはTensorFlow.jsをさらに使いやすくしてくれたライブラリ。

実際に使ってみる

今回はml5.jsが提供している機能の中でも、体の部位の座標を取得してくれる poseNet を使ってみます。

ml5.jsを利用するにはCDNを書くだけ。

<script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>

実装してみる

モデルのロード

function setup() {
  createCanvas(windowWidth, windowHeight);
  video = createCapture(VIDEO);
  video.hide();
  picture = loadImage('./sample.png');

  poseNet = ml5.poseNet(video, modelReady);
  poseNet.on('pose', gotPoses);
}

function modelReady() {
  console.log('model ready');
}

今回は画面の描画にp5.jsを使っています。
ml5.poseNet()の引数に対象のVideo Element とロード後に実行される関数を渡しています。
poseNet.on('pose', gotPoses);で新しいポーズが検出されるたびにgotPoses()が実行されます。
gotPoses()で取得したオブジェクトを利用していきます。

座標の取得

function gotPoses(poses) {
    if (poses.length > 0) {
        let pose = poses[0].pose;
        eyelX = pose.leftEye.x;
        eyelY = pose.leftEye.y;
        eyerX = pose.rightEye.x;
        eyerY = pose.rightEye.y;
    }
}

poseオブジェクトを取得したらそれぞれの体の部位のオブジェクトの(x,y)座標を取得します。今回は右目と左目の座標を取得してみます。
取得したオブジェクトは下記のような構造をしています。
leftEyeなどの利用できる体の部位は17種類あるみたいです。

[
  {
    pose: {
      keypoints: [{position:{x,y}, score, part}, ...],
      leftAngle:{x, y, confidence},
      leftEar:{x, y, confidence},
      leftElbow:{x, y, confidence},
      ...
    }
  }
]

描画する

function draw() {
    d = dist(eyerX, eyerY, eyelX, eyelY) / 100;
    image(video, 0, 0);

    image(picture, eyelX - widthOfPicture() / 2, eyelY - heightOfPicture() / 2, widthOfPicture(), heightOfPicture());
    image(picture, eyerX - widthOfPicture() / 2, eyerY - heightOfPicture() / 2, widthOfPicture(), heightOfPicture());
}

image()の第2引数と第3引数に表示したい画像の座標(x,y)を渡すので、ここに取得した目の座標を渡します。(画像の中心に目が来るように画像の幅・高さの半分をずらすように書いてます)

完成物

dsem4-gxb3y.gif
サンプル
https://ta9ma0k.github.io/

簡単にできた:hugging:おためしを!

参考

16
17
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
16
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?