まだプログラマーですが何か?

プログラマーネタとアスリートネタ中心。たまに作成したウェブサービス関連の話も http://twitter.com/dotnsf

タグ:alchemy

2016年のコード書き初めで新しいマンホール関連ウェブサービスを作ったので早速公開します。


まず、今回作成したサービスの元ネタアイデアはこの1枚の写真でした:
2016010107
 ↑下水道広報プラットフォームの中山様 元ネタはこちら


この写真自体は、昨年11月に行われた「第7回マンホールナイト」の中で撮影したものです。マンホールを型どった「ミニ顔はめ」を用意し、これと一緒に記念写真を撮ってもらおう、というものでした。これによって誰でも大津市の下水道マスコット「ホール・まん蔵」のような姿に変身することができます:



これ、なかなか面白いアイデアだと思い、もっとどこでも手軽に楽しめないだろうかと考えていました。そのアイデアと、AlchemyAPI が提供する写真の顔認識 API 機能を使い、任意の顔写真画像にマンホールをはめ込んだ合成画像を作るサービスを作れないかと考えたものが、今回実装した誰でもマンホールになれる「マンホライザー(Manholizer)」です:

http://manholizer.mybluemix.net/
2016010101


このマンホライザーは最初の画面で、顔が写っている写真の URL を指定します。例えばこの画像で試してみます:
http://codezine.jp/static/images/article/8900/8900_001.jpg

 ↑翔泳社様の、昨年の夏サミのセッションレポートで使っていただいた画像です


こんな感じで URL 欄に画像の URL を(コピペなどで)指定してください:
2016010102


で Submit すると、指定した画像から顔の位置や、その人の性別・年齢を推測して、マンホール画像の大きさを調整して合成する、というサービスです。女性と判断した場合はピンクの、男性と判断した場合は青いマンホールが合成されます:
2016010103
 ↑ちゃんと顔の位置が認識できてます。また青マンホールなので男性と認識されています。


なお、マンホール上部にはその人の推測年齢帯も表示されるようになっています:
2016010104
 ↑この画像では 18~24 歳と認識された模様です。ありがとうございます(笑)


もちろん1枚の画像に複数人が写っていても構いません。その場合はそれぞれの顔にマンホールを合わせて合成します:


http://uzukin-news.com/wp/wp-content/uploads/2014/09/AKB48-11-HD-Wallpaper.jpg
2016010105

 ↑この画像は、こうなりました↓

2016010106


誰でもホール・まん蔵のようになれる写真合成サービス「マンホライザー」、IBM Bluemix 上で絶賛稼働中です!
http://manholizer.mybluemix.net/



IBM Bluemix から使える Node-RED 環境内には AlchemyAPI の画像解析機能を持ったノードがあります。analysis カテゴリ内にある "Image Analysis" と書かれたノードがそれです:
2015120810


このノードを Node-RED 内で使うと比較的簡単に画像認識機能を実装することができます。実際に使ってみましょう。まずはこのノードをキャンバスにドラッグ&ドロップします:
2015120817


同様にして input カテゴリの inject ノードと、output カテゴリの debug ノードをドラッグ&ドロップでキャンバスに貼り付け、以下のように線で結びます:
2015120811


各ノードの属性を順に指定していきます。まずは inject ノードです。ここでは画像解析する画像の URL を文字列で指定します。というわけで種類には "string" を選択し、その下のフィールドには解析したい画像の URL を指定します。ここでは以下の画像(の URL)を指定することにしましょう:
http://news-de-smile.com/wp-content/uploads/2015/02/america-obama.jpg

↑これが何の画像なのか、は普通の人間であればわかるはず。これがコンピュータにわかるか??


"Payload" の種類に "string" を、その下に画像 URL を入力します:
2015120812


次に Image Analysis ノードの属性を指定します。ここでは AlchemyAPI を使うため、AlchemyAPI の API Key を指定します(未取得の方はここから登録して取得してください、無料です)。また解析内容は顔認識機能を使うことにしましょう。Detect の種類には "Faces" を選択します:
2015120813


最後に debug ノードの属性を指定します。この Image Analysis ノードの結果はメッセージ内に "result" という名前が付いた状態で返されます(一般的な "payload" ではありません)。というわけで、debug ノードでは debug タブに msg.result を表示するよう指定します:
2015120814


これで準備は完了です。右上の "Deploy" ボタンでデプロイします。また解析結果は debug タブに出力されるため、debug タブが表示されるよう選択しておきます:
2015120815


では解析を実行してみましょう。inject ノードの左にあるボタン部分をクリックすると、指定した画像 URL が AlchemyAPI の FaceDetection API によって解析され、その解析結果が debug タブに出力されるはずです:
2015120816


おそらくこんな感じの JSON テキストが実行結果として得られるはずです:
[
 {
  "age": {
   "ageRange": "55-64",
   "score": "0.447907"
  }, 
  "gender": {
   "gender": "MALE",
   "score": "0.993307"
  },
  "height": "389",
  "identity": {
   "disambiguated": {
    "dbpedia": "http://dbpedia.org/resource/Barack_Obama",
    "freebase": "http://rdf.freebase.com/ns/m.02mjmr",
    "name": "Barack Obama",
    "subType": [ "Person", "Politician", "President", "Appointer", "AwardWinner", "Celebrity", "PoliticalAppointer", "U.S.Congressperson", "USPresident", "TVActor" ],
    "website": "http://www.whitehouse.gov/",
    "yago": "http://yago-knowledge.org/resource/Barack_Obama"
   },
   "name": "Barack Obama",
   "score": "0.960834"
  },
  "positionX": "223",
  "positionY": "125",
  "width": "389"
 }
]

この中を見ると、画像に写っているのは1人の男性でその確率は 99.3307% 、年齢層は 55-64 歳でその確率は 44.7907%。そしてその人が "Barak Obama" である確率が 96.0834% である、という結果になっていることがわかります。それ以外の情報も含まれていますが、ともあれ Node-RED と Image Analysis ノードを使って簡単に画像認識 API を呼び出すアプリが作れてしまいました。

来たる5月19日&20日に IBM テクノロジーの祭典「IBM XCITE SPRING 2015」がグランドプリンスホテル新高輪で開催されます:
https://ibmxcite.jp/

この初日、5月19日にエンジニア向けのサブイベント dev@XCITE が併催されます。
http://ibmxcite.jp/dev/
2015050701


特にアプリケーション開発者を対象とした同イベントではアプリケーション開発基盤やホットワードになりつつある IoT(Internet of Things) をテーマとしたセッション等が予定されています。

実はその中のお昼のセッションの中で私が担当する時間が用意されています:
ライブコーディングで見せます!Bluemix アプリの作り方(11:50-12:35)

予定している内容としては IBM Bluemix を使って WordPress 環境を構築し、更にその WordPress 環境を IBM の人工知能エンジンの1つである AlchemyAPI の顔認識 API を使ってカスタマイズします。そして WordPress 内に添付された写真に人が映っているか?写っていた場合、その性別と年齢層はどのくらいか? を識別するようなカスタマイズを加えて公開する、というところまでをライブコーディングでお届けする予定です。

(完成イメージ WordPress コンテンツ内の画像内の顔を検出して性別、年齢、有名人の場合は誰かを認識させる機能をカスタマイズで追加します)
2015050700


ライブコーディング、つまりこの与えられた 45 分の中で実際にこのカスタマイズのコーディングをする、ということです。WordPress のカスタマイズなので言語としては PHP になりますが、Alchemy API は REST なので、普段は他の言語をお使いの方でもさほど混乱なく理解できる内容であると思っています。 

しかし 45 分って大丈夫か、俺!? まあヤバそうだったら最後はコピペするけど・・・

IBM Bluemix に興味ある方、AlchemyAPI の人工知能 API に興味ある方、自分でも顔認識 API を使ってみたいと思っているエンジニアの方、最近人工知能の話題をよく聞くけどどんなもんだろうと思っている方、僕のリアルなソースコードを見てみたい方、お昼の時間がヒマだなあという方、などなど、ちょっとでもこんな内容のセッションに興味があれば是非ご参加ください。




 

やられた・・・ orz

Microsoft が作って話題になった写真からの性別&年齢推定サービス How-Old.net
2015050501

精度に???な所はあるけど面白い、とネットでも結構話題になった印象です。

そして悔しい。自分達にも同じようなサービスがあるのに、正しく情報を伝えきれなかったせいで話題を Microsoft に持っていかれてしまいました。残念だ。 改めて Microsoft のマーケティングのうまさと画像認識機能への本気度を感じました。


いい機会なので、自分達が提供している機能と Microsoft の機能との違いを明確にしながら、この how-old.net に相当する機能を自分で作るにはどうしたらいいか、という話をしようと思います。

この画像認識/顔認識の機能は比較的最近になってホットになりつつある技術分野です。最近になってなぜ?かというと、この所ニューラルネットやディープラーニング技術による人工知能分野が活気づいてきており、特にこの「画像認識」や「パターン認識」の分野に関してはディープラーニングによってある程度の成果を上げることができつつあることが挙げられます。画像認識コンテストではディープラーニング技術を使ったエンジンが軒並み上位の結果を残している、という事実もあります。つまり画像認識はここ数年で研究レベルから実用レベルになりつつあると言えます。

IBM も人工知能研究には長い歴史があります。最近は Watson というブランドの下で色々な人工知能エンジンの実用化に向けた取り組みを行っていました。その一部は誰でも使えるように IBM Bluemix を通じて API としても提供されるようになりました。ただ実は Watson はディープラーニング技術をメインにしているわけではありません。Watson にもパターン認識機能がありますし、その API も公開されていますが、現時点で人気のディープラーニングをベースとしたものではありませんでした。

そのような中で IBM は2015年3月にディープラーニング技術に優れた AlchemyAPI 社を買収しました。画像認識だけでなく数々の人工知能エンジンにディープラーニング技術を取り入れている同社の技術を取り込んだことで、IBM の人工知能エンジンはディープラーニングをベースとした Alchemy と、大量の仮説から絞り込んでゆく Watson という、2つの柱ができました。このディープラーニングだけではない人工知能エンジンを研究している点が IBM の強みといえるかもしれません。

現在は Watson だけでなく、Alchemy の API も IBM Bluemix を通じて、ある程度の無料利用枠を設けて提供されています。これが何を意味するかというと、プログラマーやデベロッパーと呼ばれるプログラミングのできる人であれば誰でも画像認識やその他の人工知能 API を使って how-old.net のようなサービスを作ることができる、ということになります。

この「誰かが作ったものを使う」だけではなく「自分で作ることもできるような機能も提供されている」のが特徴です。例えば Alchemy にも画像から顔を認識する機能がウェブ API として提供されています。以前に自分のブログで紹介したことがあるので、興味のある方はこちらを参照ください:
AlchemyAPI の顔認識 API を使ってみる


また IBM が提供する人工知能 API の特徴として、認識結果の自信度合いも結果に含まれる、という点が挙げられます。例えば「この顔は男性だと思うけど、その確率は99%」とか「この人の年齢は30歳前後だと思うけど、その確率は60%」といった具合です。ピンポイントで回答しているわけではなく、現在の人工知能エンジンが弾きだした結果をその確実性と一緒に取得できるような API が提供されている点が特徴です。例えばですが API を実行した結果の自信が60%以下だった場合は使わない、といった判断をプログラミング内で行うことで精度の高い結果だけをサービスとして採用する、という条件分岐を含めることもできます。

また、特に顔認識機能に関しては有名人の顔に限りますが面白い特徴があり、性別や年齢だけでなく「○○さんの顔」として識別できるという特徴があります。例えばアメリカでも有名な渡辺謙さんの画像を問い合わせてみるとこんな結果になります。"Ken Watanabe" と認識されているのがわかるでしょうか?:
2015050502


まだ試作段階なので今後変更の予定もありますが、一応上記の確認ができるようなサービスを作ってこちらで公開してみました。興味ある方は使ってみてください:
http://dotnsf-watson.mybluemix.net/


同じ顔認識機能でも、こういった特徴というか特色が各社ごとにあるのも面白いですよね。IBM の AlchemyAPI ではこのような「有名人であればピンポイントで識別する」機能が提供されている点が面白いです。 興味のあるプログラマの皆さんは、上記の AlchemyAPI の顔認識 API を使ってみる を参考に画像をポストして、認識結果を JSON で受け取って表示する、というアプリを作ってみることに挑戦してみてください。いずれ近い将来にこのブログでもその内容を紹介するつもりです。
 





 

先日のブログエントリで下記記事を紹介しました。以下に紹介する 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 を解析して表示に使ってもいい、ということになりますね。

 

このページのトップヘ