LoginSignup
39
38

More than 5 years have passed since last update.

MSの画像解析サービスProject Oxfordでコスプレ ラブライブ四天王の年齢判定をプログラミングしてみる

Last updated at Posted at 2015-08-31

Microsoft Azure Oxfordとは

スクリーンショット 2015-09-01 0.13.34.png

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 でできること、できないこと。

できること

年齢、性別判定

5464654016.png

年齢判定は多少誤差がありますが、だいたいあってます。
性別判定はほぼ100%あっています。
写真は内田真礼

複数人の写真判定も可能

CBIMfsdsfG001.png

普通の写真判定サービスでは、写真の中心に人の顔がないと判定できないとか糞なものが多いですが、これは驚異的な顔判定が可能です。
速度も脅威的で背筋が凍ります。
監視カメラなどに応用できそうです。

できないこと

写真に顔が写ってないとほぼ無意味な判定しか帰ってこない

5464654005.png

風景画像を投げても面白いデータは返ってきません。「風景」としかわからない

2316465003.jpg

streetroadの判定ぐらいはできるようです

食べ物も詳しい判定は不可能

2316465001.jpg

food ということしかわからない

肝心の?アニメ画像(二次元画像)はもちろん判定してくれない

CBIMGfsdasdad001.png

さすがにこれは日本の会社テメーで作れということですね解ります。

Computer Vision の判定カテゴライズ

clip_image001.jpg

かなりざっくりとしたカテゴライズなので、犬の種別とか食い物の詳細な判定まではできないようです。
人の解析に特化したサービスに使えそうです。

Azureからの利用方法

Azureに登録が済んでいる前提で話をすすめます、

マーケットプレイスから「Computer Vision API」を追加

5464654018.png

5464654021.png

5464654023.png

APIキーの発行

管理ボタンを押下

36565546002.jpg

36565546001.jpg

Primary keyがAPIキー

これだけです。

Azure Computer Vision API プログラミング

公式にも各種言語のサンプルが載っているのでそれをコマンドラインで実行できるよう引数パラメーター周りを改良してみました。

Computer Vision REST APIを叩く URLイメージ読み込み版

application.json
{
  "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

1.jpg

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

2.jpg

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

3.jpg

絶対に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

4.jpg

20歳。。。だいたいあってる気がします。
写真のボケ効果をしているのに背景の人物の年齢判定をしているのはかなり怖いです。
Azure Project Oxford 恐るべし。。

まとめ

Project Oxford・・・
犯罪対策に使ったら美しい世界(ディストピア)が構築されそうな気がします。
APIが開放されてるのはプログラマーにとってはすごく良くて、いろんなアイディアで応用が効くので
これからもマイクロソフトの機械学習APIに期待したいです。

2316465002.jpg

ちなみにビル・ゲイツは生誕 1955年10月28日で  2015年9月1日現在(59歳) だそうです。

39
38
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
39
38