先日のブログエントリで下記記事を紹介しました。以下に紹介する API 実装は、ここで書かれた内容の処理を自分のアプリケーションの中で実現するものです:
Bluemix の AlchemyAPI Face Detection(顔認識) API を使ってみた

この中で紹介している AlchemyAPI の顔認識 API 、これを自分のアプリケーションの中で使ってみるサンプルを紹介します。本エントリでは Java を使いますが、REST API なので Java でなくても実現できるはずです。

まず、自分のアプリケーションで AlchemyAPI を利用するには AlchemyAPI に利用者登録をして apiKey を入手する必要があります。まずは AlchemyAPI のサイトにアクセスして、"FREE API KEY" と書かれた箇所をクリックします:
2015041301


次の画面で必要事項を入力し、最後に "REGISTER FOR API KEY" ボタンをクリックして利用者登録を行います:
2015041302


しばらくすると登録したメールアドレスに API KEY の書かれたメールが送られてきます。この情報は実際にプログラミングを行う際に必要になるので、他の人にわからないように大切に管理する必要があります:
2015041303


↑このメールにも書かれていますが、AlchemyAPI は2015/04/13 現在では「1日に1000回までの API コールは無料」です。それ以上の利用は有料となり、その価格については最新のプライスリストで確認ください:
AlchemyLanguage Pricing | AlchemyAPI


さて、API KEY が入手できれば API の実装および実行が可能です。今回は AlchemyAPI で用意された中の顔認識機能である Face Detection API を実装してみます。 Face Detection API の詳細についてはリファレンスを参照してください:
Face Detection

上記ページを参照するとわかるのですが、AlchemyAPI の顔認識 API には2種類あります。1つは画像の URL を特定して、その画像から顔認識を行う URLGetRankedImageFaceTags と、もう1つは画像のバイナリデータを送信して、そのデータから顔認識を行う ImageGetRankedImageFaceTags です。画像がインターネット上にある場合は前者を、手元にある場合は後者を使うことになります。 本エントリでは前者の API を使う方法を紹介します。なおこの API を利用する場合、Alchemy のサーバーから指定された URL にアクセスして画像データを取り込む必要があるため、目的の画像データがプライベートネットワークやファイアウォールの内側、認証のかかったサイト内にある場合は利用できません。

画像が普通にインターネット上に存在している場合であれば、以下の URL に GET アクセスすることで、その画像を顔認識 API にかけることができます:
http://access.alchemyapi.com/calls/url/URLGetRankedImageFaceTags?apikey=(API KEY)&url=(画像のURLをエンコードしたもの)&outputMode=json

この実行が成功した場合の結果は JSON フォーマットで以下のように返ってきます(赤字はコメント):
{
    "status": "OK", 成功
    "usage": "By accessing AlchemyAPI or using information generated by AlchemyAPI, you are agreeing to be bound by the AlchemyAPI Terms of Use: http://www.alchemyapi.com/company/terms.html",
    "url": "(画像URL)",
    "totalTransactions": "4",
    "imageFaces": [ 実行結果は(複数個の顔を認識する可能性があるので)配列
        { 1つ目の顔検知結果
            "age": {
                "ageRange": "35-44", 年齢層
                "score": "0.403753" その確実度合い
            },
            "gender": {
                "gender": "MALE", 性別
                "score": "0.990987" その確実度合い
            },
            "height": "34", 見つかった顔の高さ
            "positionX": "176", 見つかった顔の横位置
            "positionY": "48", 見つかった顔の縦位置
            "width": "34" 見つかった顔の幅
        },
        { 2つ目の顔検知結果
            "age": {
                "ageRange": "<18",
                "score": "0.881865"
            },
            "gender": {
                "gender": "FEMALE",
                "score": "0.992608"
            },
            "height": "28",
            "positionX": "124",
            "positionY": "119",
            "width": "28"
        }
    ]
}

この例であれば2つの顔が検知されています。1つ目の顔は画像の ( 176, 48 ) - ( 210(=176+34), 82(=48+34) ) の位置にあり、約99% の確率で男性、約40% の確率で 35~44 歳であり、と判断されています。同様に2つ目の顔は画像の ( 124, 119 ) - ( 152, 147 ) の位置にあり、約99% の確率で女性、約88%の確率で 18 歳以下であると判断された、ということになります。

この実行部分を Java サーブレットで実装した例が以下になります。
public class FaceDetectionServlet extends HttpServlet {
  public String apiKey = "(API KEY)";
	
  protected void doPost( HttpServletRequest req, HttpServletResponse res ) throws ServletException, IOException{
    String contenttype = "application/json; charset=UTF-8";
    String url = null;
    String out = "";

    req.setCharacterEncoding( "UTF-8" );

    try{
      String _url = req.getParameter( "url" );
      if( _url != null && _url.length() > 0 ){
        url = _url;
      }
			
      if( url != null && url.length() > 0 ){
        HttpClient client = new HttpClient();
        url = URLEncoder.encode( url );
        GetMethod get = new GetMethod( "http://access.alchemyapi.com/calls/url/URLGetRankedImageFaceTags?apikey=" + apiKey + "&url=" + url + "&outputMode=json" );

        int sc = client.executeMethod( get );
        out = get.getResponseBodyAsString();
      }
    }catch( Exception e ){
      e.printStackTrace();
    }
		
    res.setContentType( contenttype );
    res.setCharacterEncoding( "UTF-8" );
    res.getWriter().println( out );
  }
}

このサーブレットに url という名前のパラメータで画像 URL を指定して Post アクセスすると上記の API が実行され、その結果がそのまま(JSON フォーマットのまま)返されます。後はこのサーブレットを改良して特定のデータだけを取り出して返すようにしてもいいし、サーブレット呼び出し元でこの JSON を解析して表示に使ってもいい、ということになりますね。