登録されたタグ情報の取得

face.comは顔写真から顔の部分を認識し、タグ付けして分類することができるWebサービスである。前回の記事では、その顔認識機能にアクセスするface.com APIを使い、任意の写真から検出した顔にタグ情報を追加する手順を紹介した。このプロセスのことを"トレーニング"と呼ぶ。

トレーニングを行った結果、ユーザIDやラベルなどをタグ情報はface.comのデータベースに登録される。トレーニングされた顔写真のタグ情報はtags.getメソッド(JavaScriptライブラリのtags_getメソッド)を用いて取得することができる。tags.getメソッドは、写真のURLを渡して実行すると、その写真に付けられたタグ情報を返すメソッドである。JavaScriptにおいてtags_getメソッドを呼び出す例を以下に示す。urlGetResultはtags_getのコールバック関数であり、第1引数に写真のURLが、第2引数にタグ情報を含むJSONデータが渡される。

リスト1

var api = new Face_ClientAPI("APIキー");

// 写真を指定してタグを取得
function tagsGetForPhoto() {
     var url = "写真のURL";
     api.tags_get({ urls: url }, urlGetResult);
}

// 取得結果を表示
function urlGetResult(url, jsData) {
     alert(urls + "\n" + jsData);
}

tags.getメソッドは、URLではなくユーザIDを指定して実行することもできる。その場合、指定されたユーザIDを持つタグ情報をすべて取得することができる。特定のユーザの顔写真を探したいときにはこの方法を利用すればよい。ユーザIDを指定してtage_getメソッドを呼び出す例を以下に示す。uidGetResultaはコールバック関数であり、引数にはタグ情報を含むJSONデータが渡される。URLを使って呼び出す場合と違い、写真のURLは渡されない。

リスト2

// ユーザIDを指定してタグを取得
function tagsGetForUserID() {
     var uid = "ユーザID";
     api.tags_get({ uids: uid }, uidGetResulta);
}

// 取得結果を表示
function uidGetResulta(jsData) {
     alert(jsData);
}

以上を踏まえて、フォームを表示するHTMLと、JSONを解析してHTMLを構成するparseJSON関数を含むソースを以下のように作成した。tags_getメソッドより返されるJSONデータの詳細はAPIドキュメントのこのページを参照してほしい。

リスト3

<html>
  <head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <title>Face.comを使った顔認識のサンプル</title>
    <script type="text/javascript" src="api_client.js"></script>
    <script type="text/javascript">

      <!--
     var api = new Face_ClientAPI("APIキー");

     // 写真を指定してタグを取得
     function tagsGetForPhoto() {
       var url = document.getElementById("urlInput").value;
       api.tags_get({ urls: url }, urlGetResult);
     }
     // 取得結果を表示
     function urlGetResult(url, jsData) {
       document.getElementById("result").innerHTML = parseJSON(jsData);
     }

     // ユーザIDを指定してタグを取得
     function tagsGetForUserID() {
       var uid = document.getElementById("uidInput").value;
       api.tags_get({ uids: uid }, uidGetResulta);
     }
     // 取得結果を表示
     function uidGetResulta(data) {
       document.getElementById("result").innerHTML = parseJSON(data);
     }

     // JSONのデータを解析してHTMLを構成
     function parseJSON(jsData) {
       var resultData = "";

       var photos = jsData.photos;
       for (var i in photos) {
         resultData += "<h3>【写真" + i + "】</h3>";
         resultData += "<img src='" + photos[i].url + "' align='left' height='100'/><br/>";

         var tags = photos[i].tags;
         for (var j in tags) {
           resultData += "<table border='1'>";
           resultData += "<caption>【写真" + i + ": 顔" + j + "】</caption>";
           resultData += "<tr><td>タグID</td><td>" + tags[j].tid + "</td></tr>";
           if (tags[j].uids[0]) {
             resultData += "<tr><td>ユーザID</td><td>" + tags[j].uids[0].uid + " (" + tags[j].uids[0].confidence + "%)</td></tr>";
           } else {
             resultData += "<tr><td>ユーザID</td><td>unknown</td></tr>";
               }
           resultData += "<tr><td>ラベル</td><td>" + tags[j].label + "</td></tr>";
           resultData += "</table>";
         }
     }

       return resultData;
     }
// -->

    </script>
  </head>

  <body>
    <h1>Face.comを使った顔認識のサンプル</h1>
    <p>Face.comのAPIを利用して顔写真を調べます。</p>

    <form name="tagsGetForm">
      URL: <input id="urlInput" type="input"  size="30"/>
      <input type="button" value="写真を指定して顔情報を取得" onClick="tagsGetForPhoto()"><br/>

      ユーザID: <input id="uidInput" type="input"  size="30"/>
      <input type="button" value="ユーザIDを指定して顔情報を取得" onClick="tagsGetForUserID()"><br/>
    </form>

    <div id="result"></div>

  </body>
</html>

これを任意のサーバにアップし、Webブラウザからアクセスして実行する。写真のURLを指定してタグ情報を呼び出した例が図1である。前回トレーニングした際に「Takaaki Sugiyama」というラベルを付けたので、それが反映されていることがわかる。

図1 写真のURLを指定してタグ情報を取得

一方、ユーザIDを指定して呼び出した場合には図2のようになる。前回と同様の方法で何枚かの写真に対してトレーニングを実施してあるので、ここではその一覧が表示されている。

図2 ユーザIDを指定してタグ情報を取得

faces.recognizeメソッドによる顔認識

トレーニングによってサンプルとなるタグ情報が登録できたので、今度は新しい写真を指定して顔の認証を行ってみたい。顔の認証はfaces.recognizeメソッド(JavaScriptライブラリのfaces_recognizeメソッド)を用いて行う。faces_recognizeメソッドには、写真のURLとユーザID、名前空間を指定する。以下はコールバック関数としてrecognizeResultを指定してface_recognizeメソッドを呼び出すコード例である。recognizeResult関数には第1引数に写真のURLが、第2引数にタグ情報を含むJSONデータが渡される。

リスト4

var api = new Face_ClientAPI("APIキー");

// 顔認証を実行
function faceRecognize() {
     var url = "写真のURL";
     var uid = "ユーザID";
     var namespace = "名前空間";

     api.faces_recognize(url, { uids: uid, namespace: namespace }, recognizeResult);
}

// 結果を表示
function recognizeResult(urls,jsData) {
     alert(urls + "\n" + jsData);
}

これにフォームを表示するHTMLと、JSONを解析してHTMLを構成するparseJSON関数を加えたソースが次の例である。なお、parseJSON関数についてはtags_getの例と同じ内容になっている。

リスト5

<html>
  <head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <title>Face.comを使った顔認識のサンプル</title>
    <script type="text/javascript" src="api_client.js"></script>
    <script type="text/javascript">

      <!--
     var api = new Face_ClientAPI("APIキー");

     // 顔認証を実行
     function faceRecognize() {
       var url = document.getElementById("url").value;
       var uid = document.getElementById("uidInput").value;
       var namespace = document.getElementById("namespaceInput").value;

       api.faces_recognize(url, { uids: uid, namespace: namespace }, recognizeResult);
     }
     // 結果を表示
     function recognizeResult(urls,jsData) {
       document.getElementById("result").innerHTML = parseJSON(jsData);
     }

     // JSONのデータを解析してHTMLを構成
     function parseJSON(jsData) {
       var resultData = "";

       var photos = jsData.photos;
       for (var i in photos) {
         resultData += "<h3>【写真" + i + "】</h3>";
         resultData += "<img src='" + photos[i].url + "' align='left' height='100'/><br/>";

         var tags = photos[i].tags;
         for (var j in tags) {
           resultData += "<table border='1'>";
           resultData += "<caption>【写真" + i + ": 顔" + j + "】</caption>";
           resultData += "<tr><td>タグID</td><td>" + tags[j].tid + "</td></tr>";
           if (tags[j].uids[0]) {
             resultData += "<tr><td>ユーザID</td><td>" + tags[j].uids[0].uid + " (" + tags[j].uids[0].confidence + "%)</td></tr>";
           } else {
             resultData += "<tr><td>ユーザID</td><td>unknown</td></tr>";
               }
           resultData += "<tr><td>ラベル</td><td>" + tags[j].label + "</td></tr>";
           resultData += "</table>";
         }
       }

       return resultData;
     }
// -->

    </script>
  </head>

  <body>
    <h1>Face.comを使った顔認識のサンプル</h1>
    <p>Face.comのAPIを利用して顔写真を調べます。</p>

    <form name="recognizeForm">
      URL: <input id="url" type="input"  size="100"/><br/>
      ユーザID: <input id="uidInput" type="input"  size="30"/>
      ネームスペース: <input id="namespaceInput" type="input"  size="30"/><br/>
      <input type="button" value="顔写真を調べる" onClick="faceRecognize()"><br/>
    </form>

    <div id="result"></div>

  </body>
</html>

これを任意のサーバにアップしてWebブラウザから実行する。まず、トレーニング済みの写真を指定して実行してみると、結果は図3のようになった。トレーニングによって登録したラベル情報が反映されているのがわかる。それに対して、新しい写真を指定して実行した例が図4だ。この写真はまだトレーニングされていないのでタグIDは「TEMP」から始まる仮のものとなっているが、ユーザIDは自動で認識されており、認識率は99%という結果になっている。

既知の写真に対して顔認識を実行した例

新たな写真に対して顔認識を実行した例

図5では、もうひとつ別の写真を認識させてみた。この写真では顔が3つ検出されており(画像が小さいのでわかりにくいが、奥にもう1名写っている)。そのうちの2番目の顔はユーザIDが認識されているが、その他の2つの顔はUnknownになっている。つまり一致するサンプルが見つからなかったということである。

図5 認識できなかった顔を含む写真の場合

このように、face.com APIを利用すれば非常にシンプルなコードで顔の検出や認識を実施することができる。これを利用すれば、検出した顔のパーツの座標情報などを利用して自動で写真を加工することなども可能となる。図6は、目や鼻の位置に自動で点などを描画した例であり、HTML5のCanvas APIを利用して実装してみたものだ。Canvas APIならば特定のライブラリを使わなくても画像の加工が行えるため、face.com APIとは相性がよく、アイデア次第で面白いサービスが実現できるのではないだろうか。

図6 face.com APIとHTML5のCanvas APIを組み合わせて写真を加工した例