8
3

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 5 years have passed since last update.

J2complexedAdvent Calendar 2016

Day 24

JavaScriptで顔認識 - サンタさんを捉える!

Posted at

この記事は J2complexed Advent Calendar 2016 の24日目です。

もうすぐサンタさんがやってきます。もう一度言いますが、サンタさんが来ます。
でも、せっかくサンタさんが来てくれたのに、寝ていたら申し訳がないです。
健康的なエンジニアにとって夜更かしはできませんので、サンタさんが来たらメッセージを表示したいと思います。

顔認識のライブラリであるtracking.jsを使えば、簡単に作れちゃいます。
tracking.js

作り方

顔認識というと少し機械学習的な気がしますが、すでに顔認識のデータが準備されているので、何もすることはありません。

ライブラリの準備

まずは公式のサイトにあるDownloadボタンで一式を取得してください。
その中の build/tracking-min.js が本体です。
普通にscriptタグで読み込みます。
あと顔認識するために build/data/face-min.js も読み込んでください。
これは機械学習で言うところの学習データです。他にも eye mouth がありますが、今回はサンタを認識できればいいので使いませんでした。

Scriptを書く

ほとんどサンプルを利用してます。なので、簡単に説明だけ。

var tracker = new tracking.ObjectTracker('face')

これで顔認識をするオブジェクトができます。

tracker.setInitialScale(4)
tracker.setStepSize(2)
tracker.setEdgesDensity(0.1)

今回は設定はサンプルのままで使いましたが、特にいじらなくても問題ありませんでした。

setInitialScale 特徴量の初期サイズを指定するそうなのですが、変更してもとくに変化を感じませんでした。なんなんでしょうか?

setStepSize 物体検出を行う頻度でしょうか?変更をすると、検出をチラチラと行っているように感じました。

setEdgesDensity はエッジの密度を設定するそうです。あまり物体認識について詳しくないのですが、画像の明るさの差が大きいところを物体の境界としていて、それをエッジと言って、これは密になっていると認識する閾値みたいです。

tracking.track('#video', tracker, { camera: true });

トラッキングする対象と、顔認識をするオブジェクトを渡しておきます。

tracker.on('track', function(event) {
  if (event.data.length === 0) {
    // 何も検知できない
  } else {
    // 検知した
  }
}

オブジェクトが検知した際にイベントを待機させておきます。

困ったこと

わかっていたことですが、やはり精度があまりよくありませんでした。テスト段階で謎に背後の壁に対して顔を検出したりと怖かったので、ある程度連続して検出したときのみ、検出したと認識することにしました。

完成

以下がそのコードです。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>santa - tracking</title>
  <script src="js/tracking-min.js"></script>
  <script src="data/face-min.js"></script>

  <style>
  .xmas {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    z-index: -1;
    transition-duration: 0.8s;
    opacity: 0;
  }
  .merry .xmas {
    opacity: 1;
  }
  #tracking_level {
    background: red;
    height: 5px;
    position: fixed;
    top: 0;
    width: 0;
    left: 0;
    z-index: 10;
  }
  video, canvas {
    margin-left: 230px;
    margin-top: 120px;
    position: absolute;
    bottom: 50px;
    right: 50px;
  }
  </style>
</head>
<body>
  <div id="tracking_level"></div>
  <div class="xmas"><img src="assets/xmas.svg" alt="santa"></div>
  <video id="video" width="320" height="240" preload autoplay loop muted></video>
  <canvas id="canvas" width="320" height="240"></canvas>
  <script>
    window.onload = function() {
      var video = document.getElementById('video');
      var canvas = document.getElementById('canvas');
      var context = canvas.getContext('2d');
      var tracker = new tracking.ObjectTracker('face');
      var trackingLevel = document.getElementById('tracking_level');
      var trackCounter = 0.0;
      tracker.setInitialScale(4);
      tracker.setStepSize(2);
![santa.gif](https://qiita-image-store.s3.amazonaws.com/0/109382/250c7263-da6d-5a29-a9ee-991ff3f7b166.gif)
      tracker.setEdgesDensity(0.1);
      tracking.track('#video', tracker, { camera: true });
      tracker.on('track', function(event) {

        if (event.data.length === 0) {
          trackCounter = Math.max(0, trackCounter - 0.25)
        } else {
          trackCounter = Math.min(100, trackCounter + 1)
        }
        trackingLevel.style.width = trackCounter + '%'

        document.body.classList = trackCounter > 20 ? 'merry' : ''

        context.clearRect(0, 0, canvas.width, canvas.height);
        event.data.forEach(function(rect) {
          context.strokeStyle = '#ffffff';
          context.strokeRect(rect.x, rect.y, rect.width, rect.height);
        });
      });
    };
  </script>
</body>
</html>

で、以下が動作したデモです。

santa.gif

これでサンタさんがいつ来ても大丈夫ですね!それでは、おやすみなさい。

8
3
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
8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?