先日紹介した、この↓ IBM Watson の画像認識機能(のバージョンアップ)を Java で実装して、マンホールマップに組み込んでみました:
IBM Watson の Visual Recognition(画像認識)サービスにマンホール画像を学習させる


実を言うと、この画像認識機能自体は以前からマンホールマップのベータ機能として実装していました。が、期待通りの認識結果にならず、むしろ自虐的な「ネタ機能」としての位置付けだったのですが、上記ページで紹介した学習機能のバージョンアップとその実装により、とりあえず「マンホール画像」だと認識できそうなレベルにすることができたので、その報告です。

まず、実際の認識結果が今回の改良前後でどのように変わったかを紹介します。試したのはこのつくば市のスペースシャトル・マンホール蓋画像です:
2015122201


以前のバージョン(v1)でこの画像を認識させた時の結果がこちらでした。「Brown(茶色)」とか「Food(食べ物)」とか「Arthropod(節足動物)」とか・・・ Brown はともかくとして、それ以外に正解といえるものがないような状態でした。もちろん「マンホール」とは判定されていません:

2015122202


このロジックを変更して、前回紹介した方法でマンホールを学習させた上で新しい v2 の API を呼び出すようにした結果がこちらです。1位は見事「Manhole(マンホール)」、それ以外にも「Carpenter_Plane(手作り飛行機)」とか近い結果も出ていますし、「Catacomb(カタコンブ=地下納骨堂)」のようなマニアック(笑)な学習もされている様子が確認できます:

2015122203


この機能はマンホールマップの個別ページで確認することができます。上記のスペースシャトル蓋であればこれです:
http://manholemap.juge.me/page.jsp?id=84004


PC版であれば画面右下の "Visual Recognition" と書かれた箇所をクリックすると認識結果が展開表示されます(認識に少し時間がかかるので、ロード後少しだけ待ってからクリックしてください):
2015122204


スマホ版であれば個別詳細ページ下のここをクリックすると認識結果が展開されます:
2015122205



この機能を実装するには、まずこちらの記事を参考にマンホールを学習させておく必要があります。 その上で /api/v2/classify に対して目的の画像データを POST して、その結果の JSON を取得して解析する、という内容になります。Java であればこんな感じになります:
byte[] img = null;
    :
    :
(img に目的画像のバイナリを読み込む)
    :
    :

PostMethod post = new PostMethod( "https://gateway.watsonplatform.net/visual-recognition-beta/api/v2/classify?version=2015-12-02" );
Part[] parts = new Part[]{ 
	new FilePart( "images_file", new ByteArrayPartSource( "imgFile.jpg", img ) )
};
byte[] b64data = Base64.encodeBase64( ( "(username):(password)" ).getBytes() );
post.setRequestHeader( "Authorization", "Basic " + new String( b64data ) );
post.setRequestEntity( new MultipartRequestEntity( parts, post.getParams() ) );

int sc = client.executeMethod( post );
String json = post.getResponseBodyAsString();
    :
    :

この方法を実装すると、String 型の json 変数には以下のような値が入ってきます:
{"images":[
	{"image":"imgFile.jpg",
	 "scores":[
		 {"classifier_id":"Manhole_1277505833","name":"Manhole","score":0.799763},
		 {"classifier_id":"Brown","name":"Brown","score":0.634311},
		 {"classifier_id":"Carpenter_Plane","name":"Carpenter_Plane","score":0.620247},
		 {"classifier_id":"Wallet","name":"Wallet","score":0.599018},
		 {"classifier_id":"Chocolate_Mousse","name":"Chocolate_Mousse","score":0.582803},
		 {"classifier_id":"Chocolate_Mousse","name":"Chocolate_Mousse","score":0.582803},
		 {"classifier_id":"Diving","name":"Diving","score":0.570293},
		 {"classifier_id":"White","name":"White","score":0.554109},
		 {"classifier_id":"Desert","name":"Desert","score":0.532132},
		 {"classifier_id":"Cliff_Diving","name":"Cliff_Diving","score":0.531722},
		 {"classifier_id":"Zoo","name":"Zoo","score":0.524164},
		 {"classifier_id":"Bottle_Storage","name":"Bottle_Storage","score":0.518594},
		 {"classifier_id":"Catacomb","name":"Catacomb","score":0.512115}]}]
}

あとはこの JSON をデコードして、images 配列最初の要素の、scores 配列の中身を順に調べていけば目的の結果を取り出せる、ということになります。上記のマンホールマップ内ページではその結果を表形式にして表示しています。

画像を扱うウェブページやウェブサービスを運用している皆さま、是非色々試してみてください。