FlashAirのLuaスクリプトでComputer Vision APIを使ってみた

　FlashAir Developersサイトに、突如、[ユーザーチュートリアル「Bluemixに繋げてみよう」](https://flashair-developers.com/ja/documents/tutorials/users/4/)が公開されました。しかもしっかりと同人誌風の冊子pdfファイルで！ずるい！
　これは対抗するしかないと思い立ち、Microsoftが提供するCognitive Servicesのひとつで、画像ファイルの分析サービス[Computer Vision API](https://www.microsoft.com/cognitive-services/en-us/computer-vision-api)を、FlashAirのLuaスクリプトから呼び出してみました。
　ここでは、デジタルカメラにFlashAirを装着し、撮影後に画像ファイルが追記されると、Luaスクリプトが起動し、Computer Vision APIのなかの[Describe Image](https://dev.projectoxford.ai/docs/services/56f91f2d778daf23d8ec6739/operations/56f91f2e778daf14a499e1fe)を呼び出して、その画像ファイルのタグとキャプションを記載したテキストファイルをFlashAir内に生成してみます。

（追記 2016/8/13）機能拡張した内容をユーザーチュートリアルとしてFlashAir Developersサイト - ユーザーチュートリアルに公開していただきました。こちらも合わせて、お読みください。
[FlashAir+Azureで「しゃべるデジカメ」](https://flashair-developers.com/ja/documents/tutorials/users/6/)

![sample04_結果.png](https://qiita-image-store.s3.amazonaws.com/0/89137/f11baf3d-0d75-ddf2-4198-edab61d77cdb.png)

#サブスクリプションキーの取得
　まず、Microsoft Cognitive Services - Computer Vision APIを利用するためのサブスクリプションキーを入手します。現時点では、月間5,000リクエストまで、または１分間に20リクエストまでは無料で利用できます。
　[Microsoft Cognitive Services サブスクリプション](https://www.microsoft.com/cognitive-services/en-us/subscriptions)に、自分のMicrosoftアカウント（もし、お持ちでなければ無料で作成できます）でログインします。すると、以下のようなページで各種APIのサブスクリプションキーを入手することができます。今回は、「Computer Vision API」のチェックをつけて、Subscribeボタンを押します。

![subscriptions取得画面1.png](https://qiita-image-store.s3.amazonaws.com/0/89137/df9cc09a-8b8f-1b62-d35c-93ef929cf7f1.png)

　つぎの画面で、以下のようにサブスクリプションキーが生成されます。Key 1のCopyという文字列をクリックすると、キー文字列がクリップボードにコピーされますので、どこかに保存しておいてください。後ほど使います。

![subscriptions取得画面2.png](https://qiita-image-store.s3.amazonaws.com/0/89137/50bffaae-0609-d191-56a2-1bcda30fff30.png)


#CONFIGファイルの設定
　FlashAirのSD_WLANフォルダ内のCONFIGファイルに、以下のLuaスクリプト起動オプションを付加します。
```LUA_SD_EVENT=/azure_sample.lua
```
　※SD_WLANフォルダとCONFIGファイルは不可視属性ファイルなので注意してください。

#Luaスクリプトファイル
　FlashAirのルートフォルダに以下のコードを記述したテキストファイル（azure_sample.lua）をコピーします。

```azure_sample.lua
local cjson = require "cjson"
print("HTTP/1.1 200 Internal OK\n\n")
last_fname = ""
last_fpath = ""
last_modif = 0
fpath = "/DCIM/100__TSB" --任意のフォルダを指定する
for filename in lfs.dir(fpath) do
  filepath = fpath .. "/" .. filename
  modif = lfs.attributes( filepath, "modification" )
  if modif > last_modif then
    last_modif = modif
    last_fname = filename
    last_fpath = filepath
  end
end

boundary = "1234567890"
contenttype = "multipart/form-data; boundary=" .. boundary
mes = "--" ..  boundary .. "\r\n"
  .."Content-Disposition: form-data; name=\"file\"; filename=\""..last_fname.."\"\r\n"
  .."Content-Type: image/jpg\r\n\r\n"
  .."<!--WLANSDFILE-->\r\n"
  .."--" .. boundary .. "--\r\n"

blen = lfs.attributes(last_fpath,"size") + string.len(mes) - 17
b, c, h = fa.request{url = "https://api.projectoxford.ai/vision/v1.0/describe?",
  method = "POST",
  headers = {["Content-Length"] = tostring(blen),
  ["Content-Type"] = contenttype, 
  ["Ocp-Apim-Subscription-Key"] = "ここにサブスクリプションキーを記述する",
  ["maxCandidates"] = "1"},
  file = last_fpath,
  body = mes
}

if(c == 200) then
  --APIが正常に応答したら、まず画面表示する
  res = cjson.decode(b)
  tagstr = ""
  for idx=1,#res.description.tags do
    tagstr = tagstr .. res.description.tags[idx] .. " "
  end

  print("<img src=\"http://flashair" .. filepath .. "\" width=\"640\"><br>\n")
  print("filepath  [" .. filepath .. "]<br>\n")
  print("Tags      [" .. tagstr .. "]<br>\n")
  print("Captions  [" .. res.description.captions[1].text .. "]<br>\n")
  print("Confidence[" .. res.description.captions[1].confidence .. "]<br>\n")

  --以下、テキストファイルの生成処理
  local logfilename = last_fname .. ".txt"
  local fh = io.open(logfilename, "w")
  fh:write("filepath  [" .. filepath .. "]\n")
  fh:write("Tags      [" .. tagstr .. "]\n")
  fh:write("Captions  [" .. res.description.captions[1].text .. "]\n")
  fh:write("Confidence[" .. res.description.captions[1].confidence .. "]\n")
  fh:flush()
  fh:close()
end
```

#動作確認（デバッグ）
　いろいろな画像で動作確認をしてみました。まずはFlashAirに適当な画像ファイルをコピーして、手動でazure_sample.luaを起動してみます。

　このページの最初に掲載した猫の写真ですが、タグには「cat、animal、mammal、grass、fox、sitting、outdoor、orange、looking、black、white、television、top、green laying、standing、screen、field」と当たらずも遠からずな単語が並んでいますが、キャプションにはしっかり「a cat is sitting in the grass（猫が草の中に座っている）」と返ってきており、なかなかの認識です。Confidence（確からしさ）は84.5%となっており、だいぶ自信があるようです。

![sample10_結果.png](https://qiita-image-store.s3.amazonaws.com/0/89137/cde27aa3-62cb-8291-07db-b546fbcebc02.png)

　つぎは犬の写真ですが、タグには「dog、indoor、cabinet、 brown、sitting、looking、kitchen、large、standing、laying、top、table、black、wooden、white、water」とあり、キャプションには「a large blown dog laying on the floor」と返ってきました。Confidence（確からしさ）は67.6%となっており、ちょっと自信ないようですが、概ね合っていますね。

#動作確認（デジカメ）
　いよいよデジカメで動作確認をしてみます。FlashAirを装着したデジカメで、手元にあったマグカップの写真を撮ってみました。すると、IMGP9964.JPG.txtというテキストファイルが生成されました。しっかりコーヒーカップと認識していますね。（ソラちゃんは、残念ながら認識されなかったようです）

![IMGP9964b.jpg](https://qiita-image-store.s3.amazonaws.com/0/89137/6e48ee26-b9e2-7735-622c-b771127d2156.jpeg)

```IMGP9964.JPG.txt
filepath  [/DCIM/101_0630/IMGP9964.JPG]
Tags      [cup coffee grass table sitting mug drink keyboard small computer black doughnut breakfast laptop donut food desk close mouse sandwich hot phone plate white ]
Captions  [a cup of coffee]
Confidence[0.78216114349096]
```

#まとめ
　これで、FlashAirと最近流行りのクラウドのAIサービスを簡単に使えることがわかりました。工夫次第で、デジカメで撮影した写真を、AIで分析して得られたタグで自動分類し、キャプションをつけたアルバムを自動生成することもできますね。
　今回利用したComputer Vision APIには、Describe Image機能ほか以下の機能があります。ちょっと書き換えれば利用できる機能もありますので、試してみてください。

- [Analyze Image](https://dev.projectoxford.ai/docs/services/56f91f2d778daf23d8ec6739/operations/56f91f2e778daf14a499e1fa)
- [Describe Image](https://dev.projectoxford.ai/docs/services/56f91f2d778daf23d8ec6739/operations/56f91f2e778daf14a499e1fe)
- [Get Thumbnail](https://dev.projectoxford.ai/docs/services/56f91f2d778daf23d8ec6739/operations/56f91f2e778daf14a499e1fb)
- [List Domain Specific Models](https://dev.projectoxford.ai/docs/services/56f91f2d778daf23d8ec6739/operations/56f91f2e778daf14a499e1fd)
- [OCR](https://dev.projectoxford.ai/docs/services/56f91f2d778daf23d8ec6739/operations/56f91f2e778daf14a499e1fc)
- [Recognize Domain Specific Content](https://dev.projectoxford.ai/docs/services/56f91f2d778daf23d8ec6739/operations/56f91f2e778daf14a499e200)
- [Tag Image](https://dev.projectoxford.ai/docs/services/56f91f2d778daf23d8ec6739/operations/56f91f2e778daf14a499e1ff)

#参考資料
　[FlashAir Developers - ユーザーチュートリアル「Bluemixに繋げてみよう」](https://flashair-developers.com/ja/documents/tutorials/users/4/)
　[Microsoft Cognitive Services - Computer Vision API](https://www.microsoft.com/cognitive-services/en-us/computer-vision-api)
　[Microsoft Cognitive Services - Computer Vision API - Describe Image](https://dev.projectoxford.ai/docs/services/56f91f2d778daf23d8ec6739/operations/56f91f2e778daf14a499e1fe)