12
8

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.

Cogbot! - Cognitive Services, Bot Framework, Azure ML, Cognitive Toolkit(CNTK)Advent Calendar 2017

Day 21

「笑顔が素敵かどうか」をAIに診断してもらうアプリを作ってみた(Emotion API)

Last updated at Posted at 2017-12-20

この記事は

です。

人に会う仕事、接客する仕事に携わる人たちは、表情にとても気を使っています。
毎日鏡に向かって笑顔を作り、良い笑顔ができているかどうか、チェックする人も多いと聞きます。

しかし、自分が作った笑顔が魅力的かどうか、自分自身ではなかなか判断がつかないもの。

そこで、MS AzureCognitive Services の一つ、Emotion API を利用して

「あなたの笑顔が魅力的かどうか、AIに判断してもらおう!」

という (お遊び) アプリを作ってみました。

実際の挙動

フォームから、自分の表情を写真で撮影し、アプリにアップロードします。
(ここではサンプルの写真を利用。「ぱくたそ」「フォト蔵」さんからお借りしました。)

サンプル1

sc_1.jpg

最初の写真。とても素敵な笑顔です。

sc_2.jpg

AIも、「最高の笑顔です」と認識してくれました。

サンプル2

sc_3.jpg

ややアルカイックスマイル気味ですが、素敵な笑顔です。

sc_4.jpg

やはり良い笑顔と判定してくれたようです。

サンプル3

sc_5.jpg

どうすれば人々は苦しみから開放されるのか、悩んでいるのでしょうか。
憂いを秘めた表情です。

sc_6.jpg

AIは「お疲れのご様子ですね」と判断したようです。

このように、素敵な笑顔を作れているかどうか、アプリ が診断してくれます。

仕様

Emotion API に対して、人間の表情が写っている写真を投げると、JSONのレスポンスデータが返って来ます。

emotion_top.png

画像は、Emotion API のページからキャプチャしたものです。サンプルの写真と、写真に対する返り値のJSONが表示されています。このJSONデータには、表情から感情を読み取り、各種の感情をパラメーター化した結果が含まれています。

 JSON:
 [
  {
    "faceRectangle": {
      "top": 114,
      "left": 212,
      "width": 65,
      "height": 65
    },
    "scores": {
      "anger": 1.0570484E-08,
      "contempt": 1.52679547E-09,
      "disgust": 1.60232943E-07,
      "fear": 6.00660363E-12,
      "happiness": 0.9999998,
      "neutral": 9.449728E-09,
      "sadness": 1.23025981E-08,
      "surprise": 9.91396E-10
    }
  },

レスポンスデータの「scores」には、怒り(anger)、恐れ(fear)、幸せ(hapiness)などの各種パラメーターが、最低値0-最高値1の間の値で付与されています。

今回のスマイルチェッカーでは

  • 良い笑顔 = 幸せ度数が高い笑顔

と定義して、返り値のJSONから「hapiness」の値を抽出。hapiness値が高い= 素敵な笑顔、として判断するようにしました。

Emotion API の準備

まず最初に、Emotion API を利用できるよう、Azure からAPIキーを発行します。Azure のダッシュボードから
「新規」を選び、検索から「emotion」と入力。Emotion API を選択します。

emo_1.png

Emotion API を選択して、作成ボタンをクリックします。

emo_2.png

各設定項目を入力、選択します。

emo_3.png

Emotions API がデプロイされたら、APIキーを取得します。

emo_4.png

Emotion API の使い方は以下に詳しく記述されています。

実際のコード

先程取得したAPIキーを利用して、コードを書きます。

今回のサンプルではシンプルに

  • html5 のFile APIで、写真を取得(撮影)
  • 取得した写真を、Emotion API に送信
  • 返り値からhapinessの値を取得
  • 条件分岐で、出力するメッセージを変更

としました。Azure への画層送信やサムネイルの表示など、画像の各種処理には jQueryを使ってます。

※サンプル実装ということで、APIキーを直接html内に書く形にしましたが、APIキーが視認できる状態は危険ですのでご注意ください。第三者に勝手に使われてしまいます

<!DOCTYPE html>
<html lang="ja">
<head>
  <title>スマイルチェッカー</title>
  <meta charset="utf-8">
  <meta content="width=device-width, initial-scale=1" name="viewport">
</head>
<body>
  <div class="container" id="container">
    <h2>スマイルチェッカー</h2>
    <div id="message"></div>
    <div id="content">
      <p><input id="fileToUpload" name="upload" type="file"></p>
    </div>
  </div>
  <script src="https://code.jquery.com/jquery-2.1.4.min.js">
  </script> 
  <script>

       var html = '';

    $(function() {

     $('input[type=file]').after('<span id=\"image\"><\/span>');

     $('input[type=file]').change(function() {

       var file = $(this).prop('files')[0];

       if (!file.type.match('image.*')) {
         $(this).val('');
         $('span').html('');
         return;
       }

       var reader = new FileReader();

       reader.onload = function() {
         var img_src = $('<br><img height=\"300\">').attr('src', reader.result);
         $('span').html(img_src);
       }
       reader.readAsDataURL(file);


         $.ajax({
           url: "https://westus.api.cognitive.microsoft.com/emotion/v1.0/recognize",
           beforeSend: function(xhrObj){
               // Request headers
               xhrObj.setRequestHeader("Content-Type","application/octet-stream");
               xhrObj.setRequestHeader("Ocp-Apim-Subscription-Key","APIキーを記述する");
           },
           type: "POST",
           data: file,
           processData: false,
       })
       .done(function(data) {

           var smileScore = data["0"].scores.happiness;

          if(smileScore > 0.99) {
            var message = "最高の笑顔です!あなたの笑顔はすべての人を幸せにすることでしょう。";
          }

          if(0.7 <= smileScore && smileScore <= 0.99) {
            var message = "良い笑顔です!あなたの笑顔はみんなをホッとさせることでしょう。";
          }

          if(smileScore < 0.7) {
            var message = "疲れているのかな?早めに睡眠を取って、明日に備えましょう。";
          }

        alert(message);

       })
       .fail(function() {
           alert("error");
       });
     });
    });
  </script>
</body>
</html>

Monacaでスマホアプリ用にアレンジする

上記のコードを元に、Monacaでスマホアプリ用に整形します。

Monacaは、スマートフォンアプリ開発のフレームワークです。

sc_7.png

ちょっとだけ Onsen UI を使いました。

<!DOCTYPE html>
<html>
<head>
  <title>スマイルチェッカー</title>
</head>
<body>
  -
  <meta charset="utf-8">
  <meta content="width=device-width, initial-scale=1" name="viewport">
  <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
  <meta content="default-src * data: gap: https://ssl.gstatic.com; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'" http-equiv="Content-Security-Policy">
  <script src="components/loader.js">
  </script> 
  <script src="lib/onsenui/js/onsenui.min.js">
  </script>
  <link href="components/loader.css" rel="stylesheet">
  <link href="lib/onsenui/css/onsenui.css" rel="stylesheet">
  <link href="lib/onsenui/css/onsen-css-components.css" rel="stylesheet">
  <link href="css/style.css" rel="stylesheet">
  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" rel="stylesheet">
  <div class="center">
    スマイルチェッカー
  </div>
  <div class="container" id="container">
    <div id="message"></div>
    <div id="content">
      <div class="form-group">
        <input class="form-control-file" id="diletoUpload" name="upload" type="file">
      </div>
    </div>
  </div>
  <script src="https://code.jquery.com/jquery-2.1.4.min.js">
  </script> 
  <script>


    $(function() {

     $('input[type=file]').after('<span id=\"image\"><\/span>');

     $('input[type=file]').change(function() {

       var file = $(this).prop('files')[0];

       if (!file.type.match('image.*')) {
         $(this).val('');
         $('span').html('');
         return;
       }

       var reader = new FileReader();

       reader.onload = function() {
         var img_src = $('<br><img width=\"300\">').attr('src', reader.result);
         $('span').html(img_src);
       }
       reader.readAsDataURL(file);


         $.ajax({
           url: "https://westus.api.cognitive.microsoft.com/emotion/v1.0/recognize",
           beforeSend: function(xhrObj){
               // Request headers
               xhrObj.setRequestHeader("Content-Type","application/octet-stream");
               xhrObj.setRequestHeader("Ocp-Apim-Subscription-Key","APIキーを記述する");
           },
           type: "POST",
           data: file,
           processData: false,
       })
       .done(function(data) {

           var smileScore = data["0"].scores.happiness;

          if(smileScore > 0.99) {
            var message = "最高の笑顔です!あなたの笑顔はすべての人を幸せにすることでしょう。";
          }


          if(0.7 <= smileScore && smileScore <= 0.99) {
            var message = "良い笑顔です!あなたの笑顔はみんなをホッとさせることでしょう。";
          }


          if(smileScore < 0.7) {
            var message = "疲れているのかな?早めに睡眠を取って、明日に備えましょう。";
          }

        alert(message);


       })
       .fail(function() {
           alert("error");
       });

     });

    });


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

応用

今回は単純にEmotion API の「hapiness」の値だけを使って条件分岐しました。より複雑に判断するなら、angerなど、他のパラメーターも考慮して判断するのも良いかもしれません。

また、写真と同時に、一言コメントを記述して、Movable Type やmBaaS系のサービスに笑顔+コメント付きで投稿する「笑顔日記」的なサービスも面白いかも。

他にもビジネスになりそうなアイディアはいくつかあるのですが、事業化をご希望の方はご連絡ください(嘘)

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?