LoginSignup
13

More than 5 years have passed since last update.

getUserMediaで取得した映像でリアルタイム顔認識 [HTML5, openCV]

Posted at

方針

まず、HTML5のAPI getUserMedia を使ってローカルカメラの映像を取得できる。映像は静止画をコマ送りすることで実現しているので、特定のタイミングで画像を切り出し、その画像に対して顔認識を適用すればよい。
顔認識はサーバサイドで行う。ローカル側で切り出した画像をbase64エンコードしてAjaxでサーバに送信し、サーバ側ではbase64をデコードして顔認識器に入力する。そして、その結果をクライアント側に返す。

環境

環境はなんでもいい。以下は自身の環境で実績のあるもの。

  • フロントエンド
    • jquery
  • サーバ
    • node v.6.2
    • 顔認識
    • python 2.7
    • openCV 2系

顔認識

base64を受け取って顔認識するやつ
http://qiita.com/komakomako/items/91eb5bba927b23587ed4

フロントエンド

<header class="hero-unit" id="banner">
  <div class="container">
    <h1>顔認識します</h1>
  </div>
</header>

<div class="container">
  <div class="row">
    <div class="col-lg-12">
      <br>
      <button class="btn btn-lg btn-success" onclick="startVideo()">Start</button>
      <br>
      <canvas style="display:true;" width="640" height="480"></canvas>
      <video id="local_video" width="640" height="480" autoplay style="display: true;"></video>

    </div>
  </form>
</div>

<script type="text/javascript">
  var localVideo  = document.getElementById('local_video');
  var canvas = document.querySelector('canvas');
  var ctx = canvas.getContext('2d');
  var localStream = null;

  // 顔認識結果を四角い枠で描画するための座標
  var x = []

  var base64 = ''

  // ローカルビデオをスタートさせる
  function startVideo() {
    navigator.mediaDevices.getUserMedia({video: true, audio: false})
    .then(function (stream) { // success
      localStream = stream;
      localVideo.src  = window.URL.createObjectURL(localStream);
    }).catch(function (error) { // error
      console.error('mediaDevice.getUserMedia() error:', error);
      return;
    });
  }

  // カメラ画像キャプチャ
  var capture = function() {
    if (localStream) {
      ctx.drawImage(localVideo, 0, 0);
      ctx.beginPath();
      ctx.rect(x[0], x[1], x[2], x[3]);
      ctx.stroke();
      base64 = canvas.toDataURL('image/webp');
    }
  }

  //認識
  var detect = function() {
    var request = {
      url: 'http://localhost:9000/api/detect',
      method: 'POST',
      data: {
        image: base64.replace(/^.*,/, '')
      }
    };
    $.ajax(request).done(function(data){
       console.log(data)
       if(data.face) {
         for(var i=0; i<data.face.split(' ').length; i++){
           x[i] = data.face.split(' ')[i] - 0 ;
         }
         console.log(data.face.split(' '));
       }
    });
  }

  setInterval("capture()",100);
  setInterval("detect()",500);

</script>

サーバ

エンドポイント http://localhost:9000/api/detect をPOSTでたたくと、以下の関数にルーティングされるようにしておきます。

export function detect(req, res) {

  const exec = require('child_process').exec;
  exec('python /path/to/detect_base64.py "' + req.body.image + '"',
    function(err, stdout, stderr) {
      if (err) { console.log(err); }
      console.log(stdout);
      return res.status(201).json({"face": stdout});
    }
  );

}

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
13