obniz公式の顔検出扇風機サンプル 動かない人は、こちらへどうぞ

はてなブックマーク - obniz公式の顔検出扇風機サンプル 動かない人は、こちらへどうぞ
LINEで送る
Pocket

obniz公式サイトにある動作例の一つ

顔検出扇風機

ですが、ソースコードが少し古いようで、そのまま動かないです!

https://obniz.io/explore/25

内容がとても面白そうですから

どうしても動かしてみたいです。

動くプログラムはここに!

opencv.jsも利用して、顔を検出して、追跡する訳ですから、とても動作して欲しかったです。

もし、あなたも同じことで悩んでいるのならば

もう、ここに来てよかったです!

はい、前置きはこのぐらいにして、動くソースコードはこちらです!どうぞ!

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Video Capture Example</title>
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <script src="https://docs.opencv.org/3.4/opencv.js"></script>
  <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
  <script src="https://unpkg.com/[email protected]/obniz.js"></script>
  <style>
.refrect-lr{
  -webkit-transform: scaleX(-1);
  -o-transform: scaleX(-1);
  -moz-transform: scaleX(-1);
  transform: scaleX(-1);
  filter: FlipH;
  -ms-filter: "FlipH";
}
  </style>
</head>
<body>

<div id="obniz-debug"></div>

<div>
  <div class="control">
    <button id="startAndStop">Start</button>
  </div>
</div>
<p class="err" id="errorMessage"></p>
<div>
  <table cellpadding="0" cellspacing="0" width="0" border="0">
    <tr>
      <td>
        <video id="videoInput" autoplay playsinline width=320 height=240 class="refrect-lr"></video>
      </td>
      <td>
        <canvas id="canvasOutput" width=320 height=240 style="-webkit-font-smoothing:none"
                
                class="refrect-lr"></canvas>
      </td>
      <td></td>
      <td></td>
    </tr>
    <tr>
      <td>
        <div class="caption">videoInput</div>
      </td>
      <td>
        <div class="caption">canvasOutput</div>
      </td>
      <td></td>
      <td></td>
    </tr>
  </table>
</div>

<script src="https://webrtc.github.io/adapter/adapter-5.0.4.js" type="text/javascript"></script>
<script src="https://docs.opencv.org/3.4/utils.js" type="text/javascript"></script>
<script type="text/javascript">

  var servo;

  obniz = new Obniz("YOUR_OBNIZ_ID");

  obniz.onconnect = async () => {
    obniz.display.print("ready")
    var usb = obniz.wired("USB" , {gnd:11, vcc:8} );
    usb.on();
  
    servo = obniz.wired("ServoMotor", {signal:0,vcc:1, gnd:2});
  
  }

  let utils = new Utils('errorMessage');

  let faceCascadeFile = 'haarcascade_frontalface_default.xml';
  utils.createFileFromUrl(faceCascadeFile, 'https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml', () => {
    startAndStop.removeAttribute('disabled');
  });


  let streaming = false;
  let videoInput = document.getElementById('videoInput');
  let startAndStop = document.getElementById('startAndStop');
  let canvasOutput = document.getElementById('canvasOutput');
  let canvasContext = canvasOutput.getContext('2d');


  function successCallback(stream) {
    document.getElementById("videoInput").srcObject = stream;
    onVideoStarted();
  };

  function errorCallback(err) {
    console.error('mediaDevice.getUserMedia() error:', error);
  };

  startAndStop.addEventListener('click', () => {


    if (!streaming) {
      utils.clearError();

      const medias = {
        audio: false, video: {
          facingMode: "user" 
        }
      };


navigator.mediaDevices = navigator.mediaDevices || ((navigator.mozGetUserMedia || navigator.webkitGetUserMedia) ? {
   getUserMedia: function(c) {
     return new Promise(function(y, n) {
       (navigator.mozGetUserMedia ||
        navigator.webkitGetUserMedia).call(navigator, c, y, n);
     });
   }
} : null);

if (!navigator.mediaDevices) {
  console.log("getUserMedia() not supported.");
  return;
}

// Prefer camera resolution nearest to 1280x720.

var constraints = { audio: true, video: true };

navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
  streaming=true;
  var video = document.querySelector('video');
  video.src = window.URL.createObjectURL(stream);
  video.onloadedmetadata = function(e) {
    video.play();
    start();
  };
})
.catch(function(err) {
  console.log(err.name + ": " + err.message);
});

    } else {
      utils.stopCamera();
      onVideoStopped();
    }

  });

  function onVideoStarted() {
    streaming = true;
    startAndStop.innerText = 'Stop';
    start();
  }

  function onVideoStopped() {
    streaming = false;
    canvasContext.clearRect(0, 0, canvasOutput.width, canvasOutput.height);
    startAndStop.innerText = 'Start';
  }

  async function start() {
    let video = document.getElementById('videoInput');
    let src = new cv.Mat(video.height, video.width, cv.CV_8UC4);
    let dst = new cv.Mat(video.height, video.width, cv.CV_8UC4);
    let gray = new cv.Mat();
    let cap = new cv.VideoCapture(video);
    let faces = new cv.RectVector();
    let classifier = new cv.CascadeClassifier();


    let result = classifier.load("haarcascade_frontalface_default.xml");

    const FPS = 30;

    function processVideo() {
      try {
        if (!streaming) {
          // clean and stop.
          src.delete();
          dst.delete();
          gray.delete();
          faces.delete();
          classifier.delete();
          return;
        }
        let begin = Date.now();
        // start processing.
        cap.read(src);
        src.copyTo(dst);
        cv.cvtColor(dst, gray, cv.COLOR_RGBA2GRAY, 0);
        // detect faces.
        classifier.detectMultiScale(gray, faces, 1.1, 3, 0);
        // draw faces.
        for (let i = 0; i < faces.size(); ++i) {
          let face = faces.get(i);
          let point1 = new cv.Point(face.x, face.y);
          let point2 = new cv.Point(face.x + face.width, face.y + face.height);
          cv.rectangle(dst, point1, point2, [255, 0, 0, 255]);
        }
        cv.imshow('canvasOutput', dst);
        if(servo && faces.size() > 0){
           	let face = faces.get(0);
          	console.log('servo.angle((320-(face.x + face.width/2)) * 180 / 320) -->',(320-(face.x + face.width/2)) * 180 / 320);
        	servo.angle((320-(face.x + face.width/2)) * 180 / 320)
        }
        
        // schedule the next one.
        let delay = 100 / FPS - (Date.now() - begin);
        setTimeout(processVideo, delay);
      } catch (err) {
        console.error(err);
      }
    };

    // schedule the first one.
    setTimeout(processVideo, 0);

  }
</script>
</body>
</html>

他のハードウェア接続などは

公式の説明に参照してください。そのままです。

実行

  • いつものやり方で、ブラウザーで実行してください。
  • 上のプログラムにYOUR_OBNIZ_IDのところに、あたなのobniz個体のIDを上書きしてください。
  • その前もちろん、obnizの方も電源を接続して置いてください。

起動すると、カメラの許可を求められます。

もちろん、許可してください。セキュリティー関係はご自身の責任で確認してから行ってください。

許可すると

パソコンのカメラのインジケータが点灯します。

カメラが使用中ですよという合図です。

ちなみに、私は、chromeとsafariが上手くいかず

Firefoxでちゃんとカメラが起動して、動作しました。

そうすると、あなたの顔が検出されて、サーボの回転する角度に変換されます!

いかがですか?

動くと嬉しいですね。

しかも顔を検出して、追跡するという動作まで

本当に簡単に実現できたことに驚きばかりです!

obnizが本当にすごいです!これでウェブエンジニアもすぐIoTができてしまいます!

(ソースコードが動くとは言え、だいぶ急いで殴り書きになっておりまして、もっと綺麗に書ける余地があるかと思います、何か気づいたことがあれば、ご連絡いただければ、嬉しいです。)

@obniz_io #obniz とサーボたち

賢 川島さん(@kawashimaken)がシェアした投稿 –

はてなブックマーク - obniz公式の顔検出扇風機サンプル 動かない人は、こちらへどうぞ
LINEで送る
Pocket

Add a Comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close