MSの機械学習 画像解析サービスです。
一応カテゴリ的にはAzure MLグループに位置しています。
一般の人でもDemoサイトで直接画像から年齢判定、性別判定が可能。
またAzureに登録しているユーザーは開発者キーでREST APIでプログラミングが可能です。
教師データをユーザーが使って機械学習させるのではなく、MSが予め持っている判定ロジックをクラウドAPIとして利用可能な素敵なサービスです。
今回は汎用画像解析の**「Computer Vision API」**について触ってみたいと思います。
扱える画像フォーマット、サイズ
- Input requirements:
- Supported image formats: JPEG, PNG, GIF, BMP.
- Image file size should be less than 4MB.
- Image dimension should be great than 50 x 50.
つまり画像は4MBというリミットがあるのでREST APIでファイルをアップロードする場合は、プログラム側でリサイズが必要です。
試して分かった Azure Project Oxford でできること、できないこと。
できること
年齢、性別判定
年齢判定は多少誤差がありますが、だいたいあってます。
性別判定はほぼ100%あっています。
写真は内田真礼
複数人の写真判定も可能
普通の写真判定サービスでは、写真の中心に人の顔がないと判定できないとか糞なものが多いですが、これは驚異的な顔判定が可能です。
速度も脅威的で背筋が凍ります。
監視カメラなどに応用できそうです。
できないこと
写真に顔が写ってないとほぼ無意味な判定しか帰ってこない
風景画像を投げても面白いデータは返ってきません。**「風景」**としかわからない
streetかroadの判定ぐらいはできるようです
食べ物も詳しい判定は不可能
food ということしかわからない
肝心の?アニメ画像(二次元画像)はもちろん判定してくれない
さすがにこれは日本の会社かテメーで作れということですね解ります。
Computer Vision の判定カテゴライズ
かなりざっくりとしたカテゴライズなので、犬の種別とか食い物の詳細な判定まではできないようです。
人の解析に特化したサービスに使えそうです。
Azureからの利用方法
Azureに登録が済んでいる前提で話をすすめます、
マーケットプレイスから「Computer Vision API」を追加
APIキーの発行
管理ボタンを押下
Primary keyがAPIキー
これだけです。
Azure Computer Vision API プログラミング
公式にも各種言語のサンプルが載っているのでそれをコマンドラインで実行できるよう引数パラメーター周りを改良してみました。
Computer Vision REST APIを叩く URLイメージ読み込み版
{
"Azure" : {
"subscription_key": ""
}
}
require 'net/http'
require 'json'
File.open './config/application.json' do |file|
@conf = JSON.load(file.read)
@subscription_key = @conf['Azure']['subscription_key']
end
uri = URI('https://api.projectoxford.ai/vision/v1/analyses')
uri.query = URI.encode_www_form({
# Request parameters
'visualFeatures' => 'All'
})
request = Net::HTTP::Post.new(uri.request_uri)
# Request headers
request['Content-Type'] = 'application/json'
# Request headers
request['Ocp-Apim-Subscription-Key'] = @subscription_key
# Request body
request.body = sprintf('{ "Url": "%s"}', ARGV[0])
response = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
http.request(request)
end
puts response.body
実行
ruby from_url.rb http://news.mynavi.jp/articles/2014/05/25/uchidamaaya/images/001.jpg
{
"categories": [
{
"name": "people_",
"score": 0.98046875
}
],
"adult": {
"isAdultContent": false,
"isRacyContent": false,
"adultScore": 0.009153234772384167,
"racyScore": 0.014479533769190311
},
"requestId": "1757a848-d47a-4cb6-860d-96e72a65ac7a",
"metadata": {
"width": 225,
"height": 338,
"format": "Jpeg"
},
"faces": [
{
"age": 20,
"gender": "Female",
"faceRectangle": {
"left": 84,
"top": 47,
"width": 40,
"height": 40
}
}
],
"color": {
"dominantColorForeground": "White",
"dominantColorBackground": "White",
"dominantColors": [
"White",
"Black"
],
"accentColor": "356375",
"isBWImg": false
},
"imageType": {
"clipArtType": 0,
"lineDrawingType": 0
}
}
Computer Vision REST APIを叩く ローカルファイルのイメージ読み込み版
require 'net/http'
require 'json'
file_path = ARGV[0]
File.open './config/application.json' do |file|
@conf = JSON.load(file.read)
@subscription_key = @conf['Azure']['subscription_key']
end
uri = URI('https://api.projectoxford.ai/vision/v1/analyses')
uri.query = URI.encode_www_form({
# Request parameters
'visualFeatures' => 'All'
})
request = Net::HTTP::Post.new(uri.request_uri)
# Request headers
request['Content-Type'] = 'application/octet-stream'
# Request headers
request['Ocp-Apim-Subscription-Key'] = @subscription_key
# Request body
File.open(file_path) do |filename_stream_data|
request.body = filename_stream_data.read
response = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
http.request(request)
end
puts response.body
end
コードのフルセット
https://github.com/AKB428/oxford_vision_sample1
Azure Computer Vision API プログラミング (応用編)
レスポンスのjsonで年齢や性別が分かるので、その値をImageMagickで書きこめばProject Oxfordのサービスと近いものが自分のアプリ、サービスでも使用可能です。
ざっくりJSONのパース部分、年齢を書き込むべき位置の算出を書いてみます
require 'json'
require './lib/image_string_write'
class AzureOxfordVision
def initialize(target_file_or_url, conf)
@file_path = target_file_or_url
@conf = conf
# Local Fileの場合コピー
@write_filename = File.join(conf['oxford_app']['output_directory'], File::basename(target_file_or_url))
FileUtils.cp(target_file_or_url, @write_filename)
#TODO urlだったらファイルをダウンロード
end
def iamge_info_write(face_data)
p @write_filename
#imageを初期化
#loopして情報を書き込む
#出力ファイルを返す
face_data.each do |data|
puts data['age']
puts data['gender']
puts data['faceRectangle']
left = data['faceRectangle']['left']
top = data['faceRectangle']['top']
width = data['faceRectangle']['width']
height = data['faceRectangle']['height']
write_string = sprintf('age=%d gender=%s',data['age'],data['gender'])
position_x = left
position_y = top + height + 1
puts position_y
#(filename, write_string = nil, input_desc = nil, del_exif = false, font_size = 16, position_x = 5, position_y = 5)
#"faceRectangle": {
# "left": 256,
# "top": 126,
# "width": 108,
# "height": 108
#}
ImageStringWrite.new(@write_filename, write_string, "", false, 16, position_x, position_y).write
end
end
def image_info_parse(response_body)
image_info = JSON.load(response_body)
face_data = image_info['faces']
return if face_data.nil?
#[{"age"=>19, "gender"=>"Female", "faceRectangle"=>{"left"=>77, "top"=>39, "width"=>51, "height"=>51}}]
p face_data
iamge_info_write(face_data)
end
end
フル版のソース
https://github.com/AKB428/oxford_vision_sample2
本当は二次元がよかったですが、実写判定しかできないということでラブライブ四天王と言われているコスプレイヤーの画像を解析してみます。
####一人目
oxford_vision_sample2 (master)$ bundle exe ruby from_local.rb sample/single/1.jpg
{"categories":[{"name":"people_","score":0.9765625}],"adult":{"isAdultContent":false,"isRacyContent":false,"adultScore":0.025486733764410019,"racyScore":0.27363106608390808},"requestId":"8cc0d06e-98e2-433d-b13d-0e92a8e8c72d","metadata":{"width":600,"height":900,"format":"Jpeg"},"faces":[{"age":8,"gender":"Female","faceRectangle":{"left":256,"top":126,"width":108,"height":108}}],"color":{"dominantColorForeground":"White","dominantColorBackground":"White","dominantColors":["White"],"accentColor":"6D3A3E","isBWImg":false},"imageType":{"clipArtType":0,"lineDrawingType":0}}
[{"age"=>8, "gender"=>"Female", "faceRectangle"=>{"left"=>256, "top"=>126, "width"=>108, "height"=>108}}]
"./private/1.jpg"
8
Female
{"left"=>256, "top"=>126, "width"=>108, "height"=>108}
235
age 8 ・・・
まぁこういうこともあります。だってAIだもん。。
####二人目
oxford_vision_sample2 (master)$ bundle exe ruby from_local.rb sample/single/2.jpg
{"categories":[{"name":"people_young","score":0.6015625}],"adult":{"isAdultContent":false,"isRacyContent":false,"adultScore":0.045799832791090012,"racyScore":0.085988312959671021},"requestId":"44c64b3d-c4b8-4685-a7ce-0fd1cbd69825","metadata":{"width":599,"height":900,"format":"Jpeg"},"faces":[{"age":17,"gender":"Female","faceRectangle":{"left":254,"top":236,"width":142,"height":142}}],"color":{"dominantColorForeground":"White","dominantColorBackground":"White","dominantColors":["White"],"accentColor":"2673A5","isBWImg":false},"imageType":{"clipArtType":0,"lineDrawingType":0}}
[{"age"=>17, "gender"=>"Female", "faceRectangle"=>{"left"=>254, "top"=>236, "width"=>142, "height"=>142}}]
"./private/2.jpg"
17
Female
{"left"=>254, "top"=>236, "width"=>142, "height"=>142}
379
Age17・・だいたいあってるような気がします
####三人目
oxford_vision_sample2 (master)$ bundle exe ruby from_local.rb sample/single/3.jpg
{"categories":[{"name":"others_","score":0.00390625},{"name":"people_","score":0.65625}],"adult":{"isAdultContent":false,"isRacyContent":false,"adultScore":0.045954208821058273,"racyScore":0.1188076063990593},"requestId":"221d32bb-d3be-4a48-abce-8346b0850e28","metadata":{"width":590,"height":885,"format":"Jpeg"},"faces":[{"age":36,"gender":"Female","faceRectangle":{"left":186,"top":68,"width":107,"height":107}}],"color":{"dominantColorForeground":"White","dominantColorBackground":"White","dominantColors":["White"],"accentColor":"326E99","isBWImg":false},"imageType":{"clipArtType":0,"lineDrawingType":0}}
[{"age"=>36, "gender"=>"Female", "faceRectangle"=>{"left"=>186, "top"=>68, "width"=>107, "height"=>107}}]
"./private/3.jpg"
36
Female
{"left"=>186, "top"=>68, "width"=>107, "height"=>107}
176
絶対に36歳じゃないと思いますが・・・Adobe加工の問題なのか・・
Azureのコスプレイヤー画像判定能力対策が望まれます
####4人目
oxford_vision_sample2 (master)$bundle exe ruby from_local.rb sample/single/4.jpg
{"categories":[{"name":"people_crowd","score":0.4453125}],"adult":{"isAdultContent":false,"isRacyContent":true,"adultScore":0.046315658837556839,"racyScore":0.40509960055351257},"requestId":"386ae066-a4f8-4d46-9d8e-595024813e51","metadata":{"width":599,"height":900,"format":"Jpeg"},"faces":[{"age":20,"gender":"Female","faceRectangle":{"left":270,"top":121,"width":114,"height":114}},{"age":22,"gender":"Female","faceRectangle":{"left":40,"top":566,"width":84,"height":84}}],"color":{"dominantColorForeground":"White","dominantColorBackground":"White","dominantColors":["White","Pink"],"accentColor":"8A417C","isBWImg":false},"imageType":{"clipArtType":0,"lineDrawingType":0}}
[{"age"=>20, "gender"=>"Female", "faceRectangle"=>{"left"=>270, "top"=>121, "width"=>114, "height"=>114}}, {"age"=>22, "gender"=>"Female", "faceRectangle"=>{"left"=>40, "top"=>566, "width"=>84, "height"=>84}}]
"./private/4.jpg"
20
Female
{"left"=>270, "top"=>121, "width"=>114, "height"=>114}
236
22
Female
{"left"=>40, "top"=>566, "width"=>84, "height"=>84}
651
20歳。。。だいたいあってる気がします。
写真のボケ効果をしているのに背景の人物の年齢判定をしているのはかなり怖いです。
Azure Project Oxford 恐るべし。。
まとめ
Project Oxford・・・
犯罪対策に使ったら美しい世界(ディストピア)が構築されそうな気がします。
APIが開放されてるのはプログラマーにとってはすごく良くて、いろんなアイディアで応用が効くので
これからもマイクロソフトの機械学習APIに期待したいです。
ちなみにビル・ゲイツは生誕 1955年10月28日で 2015年9月1日現在(59歳) だそうです。