昨年10月に東芝無線LAN内蔵SDカード「FlashAir」をIoTデバイスとして活用するためのプラットフォームとして「FlashAir IoT Hub」が発表されました。現在、プレビュー公開が行われています。今回は、これにFlashAirからデータを送信して、グラフ表示することを試してみます。
送信するデータは、デジタルカメラで撮影した写真画像ファイルをLuaスクリプトでFace APIを呼び出して、写った人物の男女別人数、年齢層別人数をカウントしたデータを送信することにします。
ただ、今回、Cognitive ServicesのFace APIをFlashAirのLuaスクリプトから呼び出そうとしたのですが、どうしてもHTTP 415エラーとなり呼び出せませんでした。そのため、Computer Vision APIのvisualFeaturesに「Faces」を指定して、Face APIと同等の結果を得ることにしました。
REST APIの仕様は、こちらのドキュメントComputer Vision API - v1.0を参照してください。
#FlashAir IoT Hubの準備
こちらのFlashAir IoT Hubチュートリアルを参考に、準備してください。今回は、ご利用の流れのFlashAir登録まで済んでいれば大丈夫です。
###FlashAirのファイル配置
以下のファイルを配置しておきます。
・iothub.lua
取得した「スクリプト」ファイルのひとつ、FlashAir IoT Hub SDKファイルです。
・credentials.json
FlashAir IoT Hubのアクセストークン取得で取得したJSONファイルです。
###今回利用するコマンド
FlashAir IoT Hub SDK(iothub.lua)のなかのデータ送信機能addMeasurementを利用します。
iothub.addMeasurement(arg1, arg2, arg3, arg4, arg5)
使い方は簡単で、addMeasurementの引数に最大5個まで送信するデータを指定するだけです。
#サブスクリプションキーの取得
次に、Microsoft Cognitive Services - Computer Vision APIを利用するためのサブスクリプションキーを入手します。現時点では、月間5,000リクエストまで、または1分間に20リクエストまでは無料で利用できます。
Microsoft Cognitive Services サブスクリプションに、自分のMicrosoftアカウント(もし、お持ちでなければ無料で作成できます)でログインします。すると、以下のようなページで各種APIのサブスクリプションキーを入手することができます。今回は、「Computer Vision API」のチェックをつけて、Subscribeボタンを押します。
つぎの画面で、以下のようにサブスクリプションキーが生成されます。Key 1のCopyという文字列をクリックすると、キー文字列がクリップボードにコピーされますので、どこかに保存しておいてください。後ほど使います。
#CONFIGファイルの設定
FlashAirのSD_WLANフォルダ内のCONFIGファイルに、以下のLuaスクリプト起動オプションを付加します。
LUA_RUN_SCRIPT=/faceapi_sample.lua
※SD_WLANフォルダとCONFIGファイルは不可視属性ファイルなので注意してください。
#Luaスクリプトファイル
FlashAirのルートフォルダに以下のコードを記述したテキストファイル(faceapi_sample.lua)をコピーします。
このスクリプトでは、最新の画像ファイルをDCIMフォルダ配下に探しに行きファイル名を取得、このファイルをComputer Vision APIに投げて、Facesの結果を得ます。得たJSONファイルのなかから必要なデータを取り出して、FlashAir IoT Hubに送信します。その後、1分待機して、同じ処理を繰り返します。
処理を繰り返す中で、画像ファイルが更新されていない場合は、Face APIの呼び出しはスキップしますが、FlashAir IoT Hubには前回を同じデータを送信するようにしています。
cjson = require "cjson"
iothub = require("iothub")
latest_fpath = ""
faces_num_00 = 0
faces_num_20 = 0
faces_num_60 = 0
faces_num_male = 0
faces_num_female = 0
function funcfacecount()
last_fname = ""
last_fpath = ""
last_modif = 0
last_moddir = 0
last_dirname = "/DCIM"
fpath = "/DCIM"
for dirname in lfs.dir(fpath) do
dirpath = fpath .. "/" .. dirname
mod_dir = lfs.attributes( dirpath, "mode" )
if mod_dir == "directory" then
dir_modifficate = lfs.attributes( dirpath, "modification" )
if dir_modifficate > last_moddir then
last_moddir = dir_modifficate
last_dirname = dirpath
end
end
end
for filename in lfs.dir(last_dirname) do
if(string.sub(filename, 1, 1) ~= ".") then
filepath = last_dirname .. "/" .. filename
mod = lfs.attributes( filepath, "modification" )
if mod > last_modif then
last_modif = mod
last_fname = filename
last_fpath = filepath
end
end
end
if(latest_fpath == last_fpath) then
return
end
latest_fpath = last_fpath
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/analyze?visualFeatures=Faces",
method = "POST",
headers = {["Content-Length"] = tostring(blen),
["Content-Type"] = contenttype,
["Ocp-Apim-Subscription-Key"] = "ここにサブスクリプションキーを記述する",
file = last_fpath,
body = mes
}
if(c == 200) then
res = cjson.decode(b)
for idx=1,#res.faces do
local agenum = tonumber(res.faces[idx].age)
if(agenum < 20) then
faces_num_00 = faces_num_00 + 1
elseif(agenum >= 20 and agenum < 60) then
faces_num_20 = faces_num_20 + 1
elseif(agenum >= 60) then
faces_num_60 = faces_num_60 + 1
end
if( res.faces[idx].gender == "Female" ) then
faces_num_female = faces_num_female + 1
else
faces_num_male = faces_num_male + 1
end
end
end
end
while(1) do
funcfacecount()
iothub.addMeasurement({faces_num_00, faces_num_20, faces_num_60, faces_num_male, faces_num_female})
sleep(60000)
collectgarbage("collect")
end
#動作確認
今回は、著作権フリー写真・イラスト素材集のサンプル画像で動作確認をしてみました。まずはFlashAirに適当な画像ファイルをコピーしてみます。1分ごとに画像ファイルをComputer Vision APIで分析して、その画像に写っている人物の認識結果がうまくグラフに表示されました。
FlashAir IoT Hubでは5つのデータまでしか送信できないため、今回は、(1)20歳以下の人数、(2)20〜60歳の人数、(3)60歳以上の人数、(4)男性の人数、(5)女性の人数の5つのデータを送信しています。
#まとめ
FlashAirからCognitive ServicesのComputer Vision APIを呼び出して、写真に写っている人物の男女別人数と年齢層別人数をカウントすることができるようになりました。
デジタルカメラでインターバル撮影を行えば、定点観測による人物カウンターが実現できますね。
#参考資料
FlashAir IoT Hubチュートリアル
Microsoft Cognitive Services - Computer Vision API
Microsoft Cognitive Services - Computer Vision API - Document