Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
3
Help us understand the problem. What is going on with this article?
@chiapis2

clmtraker.jsとobnizを使用して顔の表情からLチカさせる

More than 1 year has passed since last update.

はじめに

プログラミングやマイコンボードに初めて触れた超初心者がjavascriptを駆使して表情検出で遊んでみた時の個人用備忘録である。
clmtracker.jsというjavascriptの表情検出APIを使って2種類の表情を捉え、obnizと連動させ、表情に合わせてLEDライトが光る仕組みを考えた。

obniz準備

  • 自分のobnizをPCと接続する。
    「ドキュメント」→「obnizの始め方」に記載されているようにnodejsがインストールされたVisualStudioCodeを使用する。(Nodejsは入っていなくても動いている気がする。)
    obniz公式サイト
    Node.jsダウンロードページ
  • obnizをWifiに接続し、画面上にQRコードと8桁の数字が表示された状態にする。
  • 抵抗付き青色LEDを準備し、アノードをobnizのio0に、カソードをio1にさす。
    obniz LEDを付ける 参照

clmtracker.js準備(今回はクラウドファイルを使用するためダウンロード不要)

  • GitHubにアップロードされているclmtrcker.jsファイルをPCにダウンロードし全て解凍する。
    GitHub clmtracker.js
  • VScodeにて使用できるようにフォルダに名前を付けて保存する。

実装

  • VScodeを立ち上げて、clmtrackをダウンロードした同じフォルダの中に新しくhtmlファイルを作成する。
    (今回は適当にhtmlファイルを作成する。「新しいファイル作成」→XXX.htmlとすれば作れる。)
  • 自分のフォルダ内のclmtrackerを使用する場合は4つ分のscript内を自分のフォルダから引用するコードに変更する。
  • var obniz = new Obniz("XXXX-XXXX") XXXX-XXXXの部分に自分のobnizの8桁の数字を入力することを忘れずに行う。
  • PCのWEBカメラを使用する。
    obniz キッズプロジェクト 参考
  • サーバーを経由する必要があるためVScodeの拡張機能で[Live Server]を入れておいた。
    Live Server 参考
<html>
<head>
  <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
  <script src="https://unpkg.com/obniz@2.0.2/obniz.js"></script>
  <script src="https://rawgit.com/auduno/clmtrackr/dev/build/clmtrackr.js"></script>
  <script src="https://rawgit.com/auduno/clmtrackr/dev/models/model_pca_20_svm.js"></script>
  <script src="https://rawgit.com/auduno/clmtrackr/dev/examples/js/emotion_classifier.js"></script>
  <script src="https://rawgit.com/auduno/clmtrackr/dev/examples/js/emotionmodel.js"></script>
</head>

<body>
  <div id="obniz-debug"></div>
  <video id="video" width="400" height="300" autoplay></video>
  <canvas id="canvas" width="400" height="300"></canvas> 
  <div id="print"></div>
<script>

var speaker;
var obniz = new Obniz("XXXX-XXXX")  //自分のobnizの8桁の数字を入力する
obniz.onconnect = async () => {
    var led = obniz.wired("LED", {anode:0, cathode:1});
 await startEmotion()
}

async function startEmotion() {
  var video = document.getElementById("video");
  var canvas = document.getElementById("canvas");
  var context = canvas.getContext("2d");

  var stream = await navigator.mediaDevices.getUserMedia({
    video: {facingMode: "user"},
    audio: false
  });
  video.srcObject = stream;
  video.onloadedmetadata = function(e) {
    video.play();
  };

  var tracker = new clm.tracker();
  tracker.init(pModel);
  tracker.start(video);

  var classifier = new emotionClassifier();
  classifier.init(emotionModel);

  function drawLoop() {
    requestAnimationFrame(drawLoop);
    var positions = tracker.getCurrentPosition();
    var parameters = tracker.getCurrentParameters();
    var emotion = classifier.meanPredict(parameters);   
    context.clearRect(0, 0, canvas.width, canvas.height);
    tracker.draw(canvas);
    var emotions = {};
    for (var i=0; i<emotion.length; i++) {
      emotions[emotion[i].emotion] = emotion[i].value;
    }

    $("#print").html("sad: " + emotions.sad +"happy: " + emotions.happy)

    var led = obniz.wired("LED", {anode:0, cathode:1});

    if(emotions.happy > emotions.sad){
     led.on();
     console.log("happy");
    } else if (emotions.happy < emotions.sad){
     led.off();
     console.log("sad");
    }
}
  drawLoop();
}

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

フルカラーLEDでも試してみた

WS2811もしくはWS2812円形タイプを購入し、表情によって色が変化するようにした。
今回のコードは楽しいと黄色、悲しいと青になるように設定した。RGBで数値を弄れば色を変えることができる。
配線の方法はパーツライブラリを参照した。
パーツライブラリ

<html>
<head>
  <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
  <script src="https://unpkg.com/obniz@2.0.2/obniz.js"></script>
  <script src="https://rawgit.com/auduno/clmtrackr/dev/build/clmtrackr.js"></script>
  <script src="https://rawgit.com/auduno/clmtrackr/dev/models/model_pca_20_svm.js"></script>
  <script src="https://rawgit.com/auduno/clmtrackr/dev/examples/js/emotion_classifier.js"></script>
  <script src="https://rawgit.com/auduno/clmtrackr/dev/examples/js/emotionmodel.js"></script>
</head>

<body>
  <div id="obniz-debug"></div>
  <video id="video" width="400" height="300" autoplay></video>
  <canvas id="canvas" width="400" height="300"></canvas> 
  <div id="print"></div>
<script>

var speaker;
var obniz = new Obniz("XXXX-XXXX")  //自分のobnizの8桁の数字を入力する
var emotions = {};

var HAPPY = false;
var SAD = false;

obniz.onconnect = async function () {
    const leds = obniz.wired("WS2812", {gnd:0, vcc: 1, din: 2});


    var video = document.getElementById("video");
    var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");

    var stream = await navigator.mediaDevices.getUserMedia({
        video: {facingMode: "user"},
        audio: false
    });
    video.srcObject = stream;
    video.onloadedmetadata = function(e) {
        video.play();
    };

    var tracker = new clm.tracker();
    tracker.init(pModel);
    tracker.start(video);

    var classifier = new emotionClassifier();
    classifier.init(emotionModel);


    function drawLoop() {
        requestAnimationFrame(drawLoop);
        var positions = tracker.getCurrentPosition();
        var parameters = tracker.getCurrentParameters();
        var emotion = classifier.meanPredict(parameters);   
        context.clearRect(0, 0, canvas.width, canvas.height);
        tracker.draw(canvas);

        for (var i=0; i<emotion.length; i++) {
            emotions[emotion[i].emotion] = emotion[i].value;
        }

        $("#print").html("sad: " + emotions.sad +"happy: " + emotions.happy)

        if(HAPPY){

        leds.rgbs([
            [255,215,0],
            [255,215,0],
            [255,215,0],
            [255,215,0],
            [255,215,0],
            [255,215,0],
            [255,215,0],
            [255,215,0],
            [255,215,0],
            [255,215,0],
            [255,215,0],
            [255,215,0],
            [255,215,0],
            [255,215,0],
            [255,215,0],
            [255,215,0],
            [255,215,0],
            [255,215,0],
            [255,215,0],
            [255,215,0],
        ]);

    } 
    else {

        leds.rgbs([
        [0x00, 0x00, 0xFF] , 
        [0x00, 0x00, 0xFF] ,
        [0x00, 0x00, 0xFF] , 
        [0x00, 0x00, 0xFF] ,
        [0x00, 0x00, 0xFF] , 
        [0x00, 0x00, 0xFF] ,
        [0x00, 0x00, 0xFF] , 
        [0x00, 0x00, 0xFF] ,
        [0x00, 0x00, 0xFF] , 
        [0x00, 0x00, 0xFF] ,
        [0x00, 0x00, 0xFF] , 
        [0x00, 0x00, 0xFF] ,
        [0x00, 0x00, 0xFF] , 
        [0x00, 0x00, 0xFF] ,
        [0x00, 0x00, 0xFF] , 
        [0x00, 0x00, 0xFF] ,
        [0x00, 0x00, 0xFF] , 
        [0x00, 0x00, 0xFF] ,
        [0x00, 0x00, 0xFF] , 
        [0x00, 0x00, 0xFF] ,
        ]);
    }

        if(emotions.happy > emotions.sad){
            HAPPY = true;
            SAD = false;
            obniz.display.print("happy");
        }
        else{
            SAD =false;
            HAPPY = false;
            obniz.display.print("sad");
        }
    }
    drawLoop();
}
</script>
</body>
</html>
<html>
<head>
  <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
  <script src="https://unpkg.com/obniz@2.0.2/obniz.js"></script>
  <script src="https://rawgit.com/auduno/clmtrackr/dev/build/clmtrackr.js"></script>
  <script src="https://rawgit.com/auduno/clmtrackr/dev/models/model_pca_20_svm.js"></script>
  <script src="https://rawgit.com/auduno/clmtrackr/dev/examples/js/emotion_classifier.js"></script>
  <script src="https://rawgit.com/auduno/clmtrackr/dev/examples/js/emotionmodel.js"></script>
</head>

<body>
  <div id="obniz-debug"></div>
  <video id="video" width="400" height="300" autoplay></video>
  <canvas id="canvas" width="400" height="300"></canvas> 
  <div id="print"></div>
<script>

var speaker;
var obniz = new Obniz("XXXX-XXXX")  //自分のobnizの8桁の数字を入力する
var emotions = {};

var HAPPY = false;
var SAD = false;

obniz.onconnect = async function () {
    const leds = obniz.wired("WS2811", {gnd:0, vcc: 1, din: 2});


    var video = document.getElementById("video");
    var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");

    var stream = await navigator.mediaDevices.getUserMedia({
        video: {facingMode: "user"},
        audio: false
    });
    video.srcObject = stream;
    video.onloadedmetadata = function(e) {
        video.play();
    };

    var tracker = new clm.tracker();
    tracker.init(pModel);
    tracker.start(video);

    var classifier = new emotionClassifier();
    classifier.init(emotionModel);


    function drawLoop() {
        requestAnimationFrame(drawLoop);
        var positions = tracker.getCurrentPosition();
        var parameters = tracker.getCurrentParameters();
        var emotion = classifier.meanPredict(parameters);   
        context.clearRect(0, 0, canvas.width, canvas.height);
        tracker.draw(canvas);

        for (var i=0; i<emotion.length; i++) {
            emotions[emotion[i].emotion] = emotion[i].value;
        }

        $("#print").html("sad: " + emotions.sad +"happy: " + emotions.happy)

        if(HAPPY){

        leds.rgbs([
            [255,215,0],
        ]);

    } 
    else {

        leds.rgbs([
        [0x00, 0x00, 0xFF] , 
        ]);
    }

        if(emotions.happy > emotions.sad){
            HAPPY = true;
            SAD = false;
            // obniz.display.print("happy");
        }
        else{
            SAD =false;
            HAPPY = false;
            // obniz.display.print("sad");
        }
    }
    drawLoop();
}
</script>
</body>
</html>
3
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
chiapis2
看護とテクノロジーで未来は変わらないだろうか。 プログラミング超初心者。亀速度で勉強中。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
3
Help us understand the problem. What is going on with this article?