【続】Microsoft Emotion APIをRaspberryPiで使用してみる【picameraと連携】

(続)Microsoft Emotion APIをRaspberryPiで使用してみる【picameraと連携】

これまでのエントリーでMicrosoft Emotion APIの使い方がわかったことに味を占めてRaspberry Piのカメラモジュールで撮影した画像を送ることにします。これまでcameraモジュールは持っていたんですが、宝の持ち腐れだったので。

自分の持っていたcameraモジュールはこれになります。

いろいろとカメラモジュールはありますが、自分の持っているRaspberryPiに対応したモジュールでいいんじゃないかと思います。ただし、NoIRとついているものは赤外線カメラなのでその点だけ気を付けてください。(使い方は変わらないみたいですが。)

Raspberry Piのcameraモジュールを有効化する

まずはcameraモジュールを使用できるようにraspi-configで設定します。

$ sudo raspi-config

以下のようなメニュー画面になります。

f:id:ueponx:20161025002333j:plain

この中から【6.Enable Camera】を選択します。

f:id:ueponx:20161025002407j:plain

cameraを有効化するか否かを尋ねられるので、

f:id:ueponx:20161025002546j:plain

【Enable】を選択します。

f:id:ueponx:20161025002641j:plain

選択するともとのメニュー画面に戻ります。

f:id:ueponx:20161025002722j:plain

メニューの下にある【Finish】を押して設定を終了させようとすると

f:id:ueponx:20161025002809j:plain

再起動を求められるので、再起動をします。

f:id:ueponx:20161025002837j:plain

これで正常にcameraモジュールを有効化できました。

cameraモジュールのテストを行う。

有効化したら以下のコマンドを実行してみます。

$ raspistill -o image.jpg

エラーが発生しなければOKです。 念のため生成された画像がjpegファイルになっているか確認してみます。

$ file image.jpg
image.jpg: JPEG image data, Exif standard: [TIFF image data, big-endian, direntries=10, height=0, manufacturer=RaspberryPi, model=RP_ov5647, xresolution=156, yresolution=164, resolutionunit=2, datetime=2016:10:24 23:36:00, width=0], baseline, precision 8, 720x480, frames 3

fileコマンドはファイルの解析ができるコマンドです。 デフォルト設定では720x480サイズで撮影され、Exif情報もちゃんと入っているので問題無いようです。

raspistillは静止画をキャプチャするコマンドですが、他にもraspividという動画撮影用のコマンドや圧縮をかけずにキャプチャを行うようなraspiyuvというコマンドも存在します。これらコマンドはシャッタースピードやホワイトバランス、簡易なフィルタなどをかける事ができるかなり多機能なコマンドになっています。このコマンドだけでもタイムラプスを取ることができるので、別途そのあたりも調べてみたいと思います。

それぞれのコマンドのhelpオプションは以下の通り。

$ raspistill --help
Runs camera for specific time, and take JPG capture at end if requested

usage: raspistill [options]

Image parameter commands

-?, --help      : This help information
-w, --width     : Set image width <size>
-h, --height    : Set image height <size>
-q, --quality   : Set jpeg quality <0 to 100>
-r, --raw       : Add raw bayer data to jpeg metadata
-o, --output    : Output filename <filename> (to write to stdout, use '-o -'). If not specified, no file is saved
-l, --latest    : Link latest complete image to filename <filename>
-v, --verbose   : Output verbose information during run
-t, --timeout   : Time (in ms) before takes picture and shuts down (if not specified, set to 5s)
-th, --thumb    : Set thumbnail parameters (x:y:quality) or none
-d, --demo      : Run a demo mode (cycle through range of camera options, no capture)
-e, --encoding  : Encoding to use for output file (jpg, bmp, gif, png)
-x, --exif      : EXIF tag to apply to captures (format as 'key=value') or none
-tl, --timelapse        : Timelapse mode. Takes a picture every <t>ms. %d == frame number (Try: -o img_%04d.jpg)
-fp, --fullpreview      : Run the preview using the still capture resolution (may reduce preview fps)
-k, --keypress  : Wait between captures for a ENTER, X then ENTER to exit
-s, --signal    : Wait between captures for a SIGUSR1 from another process
-g, --gl        : Draw preview to texture instead of using video render component
-gc, --glcapture        : Capture the GL frame-buffer instead of the camera image
-set, --settings        : Retrieve camera settings and write to stdout
-cs, --camselect        : Select camera <number>. Default 0
-bm, --burst    : Enable 'burst capture mode'
-md, --mode     : Force sensor mode. 0=auto. See docs for other modes available
-dt, --datetime : Replace output pattern (%d) with DateTime (MonthDayHourMinSec)
-ts, --timestamp        : Replace output pattern (%d) with unix timestamp (seconds since 1970)
-fs, --framestart       : Starting frame number in output pattern(%d)
-rs, --restart  : JPEG Restart interval (default of 0 for none)

Preview parameter commands

-p, --preview   : Preview window settings <'x,y,w,h'>
-f, --fullscreen        : Fullscreen preview mode
-op, --opacity  : Preview window opacity (0-255)
-n, --nopreview : Do not display a preview window

Image parameter commands

-sh, --sharpness        : Set image sharpness (-100 to 100)
-co, --contrast : Set image contrast (-100 to 100)
-br, --brightness       : Set image brightness (0 to 100)
-sa, --saturation       : Set image saturation (-100 to 100)
-ISO, --ISO     : Set capture ISO
-vs, --vstab    : Turn on video stabilisation
-ev, --ev       : Set EV compensation - steps of 1/6 stop
-ex, --exposure : Set exposure mode (see Notes)
-awb, --awb     : Set AWB mode (see Notes)
-ifx, --imxfx   : Set image effect (see Notes)
-cfx, --colfx   : Set colour effect (U:V)
-mm, --metering : Set metering mode (see Notes)
-rot, --rotation        : Set image rotation (0-359)
-hf, --hflip    : Set horizontal flip
-vf, --vflip    : Set vertical flip
-roi, --roi     : Set region of interest (x,y,w,d as normalised coordinates [0.0-1.0])
-ss, --shutter  : Set shutter speed in microseconds
-awbg, --awbgains       : Set AWB gains - AWB mode must be off
-drc, --drc     : Set DRC Level (see Notes)
-st, --stats    : Force recomputation of statistics on stills capture pass
-a, --annotate  : Enable/Set annotate flags or text
-3d, --stereo   : Select stereoscopic mode
-dec, --decimate        : Half width/height of stereo image
-3dswap, --3dswap       : Swap camera order for stereoscopic
-ae, --annotateex       : Set extra annotation parameters (text size, text colour(hex YUV), bg colour(hex YUV))


Notes

Exposure mode options :
off,auto,night,nightpreview,backlight,spotlight,sports,snow,beach,verylong,fixedfps,antishake,fireworks

AWB mode options :
off,auto,sun,cloud,shade,tungsten,fluorescent,incandescent,flash,horizon

Image Effect mode options :
none,negative,solarise,sketch,denoise,emboss,oilpaint,hatch,gpen,pastel,watercolour,film,blur,saturation,colourswap,washedout,posterise,colourpoint,colourbalance,cartoon

Metering Mode options :
average,spot,backlit,matrix

Dynamic Range Compression (DRC) options :
off,low,med,high

Preview parameter commands

-gs, --glscene  : GL scene square,teapot,mirror,yuv,sobel
-gw, --glwin    : GL window settings <'x,y,w,h'>
$ raspivid --help
Display camera output to display, and optionally saves an H264 capture at requested bitrate

usage: raspivid [options]

Image parameter commands

-?, --help      : This help information
-w, --width     : Set image width <size>. Default 1920
-h, --height    : Set image height <size>. Default 1080
-b, --bitrate   : Set bitrate. Use bits per second (e.g. 10MBits/s would be -b 10000000)
-o, --output    : Output filename <filename> (to write to stdout, use '-o -')
-v, --verbose   : Output verbose information during run
-t, --timeout   : Time (in ms) to capture for. If not specified, set to 5s. Zero to disable
-d, --demo      : Run a demo mode (cycle through range of camera options, no capture)
-fps, --framerate       : Specify the frames per second to record
-e, --penc      : Display preview image *after* encoding (shows compression artifacts)
-g, --intra     : Specify the intra refresh period (key frame rate/GoP size). Zero to produce an initial I-frame and then just P-frames.
-pf, --profile  : Specify H264 profile to use for encoding
-td, --timed    : Cycle between capture and pause. -cycle on,off where on is record time and off is pause time in ms
-s, --signal    : Cycle between capture and pause on Signal
-k, --keypress  : Cycle between capture and pause on ENTER
-i, --initial   : Initial state. Use 'record' or 'pause'. Default 'record'
-qp, --qp       : Quantisation parameter. Use approximately 10-40. Default 0 (off)
-ih, --inline   : Insert inline headers (SPS, PPS) to stream
-sg, --segment  : Segment output file in to multiple files at specified interval <ms>
-wr, --wrap     : In segment mode, wrap any numbered filename back to 1 when reach number
-sn, --start    : In segment mode, start with specified segment number
-sp, --split    : In wait mode, create new output file for each start event
-c, --circular  : Run encoded data through circular buffer until triggered then save
-x, --vectors   : Output filename <filename> for inline motion vectors
-cs, --camselect        : Select camera <number>. Default 0
-set, --settings        : Retrieve camera settings and write to stdout
-md, --mode     : Force sensor mode. 0=auto. See docs for other modes available
-if, --irefresh : Set intra refresh type
-fl, --flush    : Flush buffers in order to decrease latency
-pts, --save-pts        : Save Timestamps to file for mkvmerge
-cd, --codec    : Specify the codec to use - H264 (default) or MJPEG
-lev, --level   : Specify H264 level to use for encoding


H264 Profile options :
baseline,main,high


H264 Level options :
4,4.1,4.2

H264 Intra refresh options :
cyclic,adaptive,both,cyclicrows

Preview parameter commands

-p, --preview   : Preview window settings <'x,y,w,h'>
-f, --fullscreen        : Fullscreen preview mode
-op, --opacity  : Preview window opacity (0-255)
-n, --nopreview : Do not display a preview window

Image parameter commands

-sh, --sharpness        : Set image sharpness (-100 to 100)
-co, --contrast : Set image contrast (-100 to 100)
-br, --brightness       : Set image brightness (0 to 100)
-sa, --saturation       : Set image saturation (-100 to 100)
-ISO, --ISO     : Set capture ISO
-vs, --vstab    : Turn on video stabilisation
-ev, --ev       : Set EV compensation - steps of 1/6 stop
-ex, --exposure : Set exposure mode (see Notes)
-awb, --awb     : Set AWB mode (see Notes)
-ifx, --imxfx   : Set image effect (see Notes)
-cfx, --colfx   : Set colour effect (U:V)
-mm, --metering : Set metering mode (see Notes)
-rot, --rotation        : Set image rotation (0-359)
-hf, --hflip    : Set horizontal flip
-vf, --vflip    : Set vertical flip
-roi, --roi     : Set region of interest (x,y,w,d as normalised coordinates [0.0-1.0])
-ss, --shutter  : Set shutter speed in microseconds
-awbg, --awbgains       : Set AWB gains - AWB mode must be off
-drc, --drc     : Set DRC Level (see Notes)
-st, --stats    : Force recomputation of statistics on stills capture pass
-a, --annotate  : Enable/Set annotate flags or text
-3d, --stereo   : Select stereoscopic mode
-dec, --decimate        : Half width/height of stereo image
-3dswap, --3dswap       : Swap camera order for stereoscopic
-ae, --annotateex       : Set extra annotation parameters (text size, text colour(hex YUV), bg colour(hex YUV))


Notes

Exposure mode options :
off,auto,night,nightpreview,backlight,spotlight,sports,snow,beach,verylong,fixedfps,antishake,fireworks

AWB mode options :
off,auto,sun,cloud,shade,tungsten,fluorescent,incandescent,flash,horizon

Image Effect mode options :
none,negative,solarise,sketch,denoise,emboss,oilpaint,hatch,gpen,pastel,watercolour,film,blur,saturation,colourswap,washedout,posterise,colourpoint,colourbalance,cartoon

Metering Mode options :
average,spot,backlit,matrix

Dynamic Range Compression (DRC) options :
off,low,med,high
$ raspiyuv --help
Runs camera for specific time, and take uncompressed YUV capture at end if requested

usage: raspiyuv [options]

Image parameter commands

-?, --help      : This help information
-w, --width     : Set image width <size>
-h, --height    : Set image height <size>
-o, --output    : Output filename <filename>. If not specifed, no image is saved
-v, --verbose   : Output verbose information during run
-t, --timeout   : Time (in ms) before takes picture and shuts down. If not specified set to 5s
-tl, --timelapse        : Timelapse mode. Takes a picture every <t>ms
-rgb, --rgb     : Save as RGB data rather than YUV
-cs, --camselect        : Select camera <number>. Default 0
-fp, --fullpreview      : Run the preview using the still capture resolution (may reduce preview fps)
-l, --latest    : Link latest complete image to filename <filename>
-k, --keypress  : Wait between captures for a ENTER, X then ENTER to exit
-s, --signal    : Wait between captures for a SIGUSR1 from another process
-set, --settings        : Retrieve camera settings and write to stdout
-bm, --burst    : Enable 'burst capture mode'

Preview parameter commands

-p, --preview   : Preview window settings <'x,y,w,h'>
-f, --fullscreen        : Fullscreen preview mode
-op, --opacity  : Preview window opacity (0-255)
-n, --nopreview : Do not display a preview window

Image parameter commands

-sh, --sharpness        : Set image sharpness (-100 to 100)
-co, --contrast : Set image contrast (-100 to 100)
-br, --brightness       : Set image brightness (0 to 100)
-sa, --saturation       : Set image saturation (-100 to 100)
-ISO, --ISO     : Set capture ISO
-vs, --vstab    : Turn on video stabilisation
-ev, --ev       : Set EV compensation - steps of 1/6 stop
-ex, --exposure : Set exposure mode (see Notes)
-awb, --awb     : Set AWB mode (see Notes)
-ifx, --imxfx   : Set image effect (see Notes)
-cfx, --colfx   : Set colour effect (U:V)
-mm, --metering : Set metering mode (see Notes)
-rot, --rotation        : Set image rotation (0-359)
-hf, --hflip    : Set horizontal flip
-vf, --vflip    : Set vertical flip
-roi, --roi     : Set region of interest (x,y,w,d as normalised coordinates [0.0-1.0])
-ss, --shutter  : Set shutter speed in microseconds
-awbg, --awbgains       : Set AWB gains - AWB mode must be off
-drc, --drc     : Set DRC Level (see Notes)
-st, --stats    : Force recomputation of statistics on stills capture pass
-a, --annotate  : Enable/Set annotate flags or text
-3d, --stereo   : Select stereoscopic mode
-dec, --decimate        : Half width/height of stereo image
-3dswap, --3dswap       : Swap camera order for stereoscopic
-ae, --annotateex       : Set extra annotation parameters (text size, text colour(hex YUV), bg colour(hex YUV))


Notes

Exposure mode options :
off,auto,night,nightpreview,backlight,spotlight,sports,snow,beach,verylong,fixedfps,antishake,fireworks

AWB mode options :
off,auto,sun,cloud,shade,tungsten,fluorescent,incandescent,flash,horizon

Image Effect mode options :
none,negative,solarise,sketch,denoise,emboss,oilpaint,hatch,gpen,pastel,watercolour,film,blur,saturation,colourswap,washedout,posterise,colourpoint,colourbalance,cartoon

Metering Mode options :
average,spot,backlit,matrix

Dynamic Range Compression (DRC) options :
off,low,med,high

Emotion APIと連携してみる

では、raspistillで画像保存後にcurlコマンドでEmotion APIをKickしてみたいと思います。

Microsoftのサンプルをそのままみると…以下のように書けばいいようです。

参照:Microsoft Cognitive Services

#!/usr/bin/env bash
curl -X POST "https://api.projectoxford.ai/emotion/v1.0/recognize" -H "Content-Type: application/json" -H "Ocp-Apim-Subscription-Key: 発行されたAPIキー" --data-ascii "{'url':'http://www.mis.med.akita-u.ac.jp/~kata/image/lenna/lenna'}"

このサンプルではWeb上の画像を解析するだけなので、cameraモジュールで撮影したファイルをAPIで解析するにはOctet-Streamで送信する必要がありますので、以下のように変更します。

#!/usr/bin/env bash
raspistill -rot 180 -o image.jpg
curl -X POST "https://api.projectoxford.ai/emotion/v1.0/recognize" -H "Content-Type: application/octet-stream" -H "Ocp-Apim-Subscription-Key: 発行されたAPIキー" --data-binary @image.jpg

サンプルとの大きな違いは

  1. Content-TypeをOctet-Streamにした点
  2. --data-binary @image.jpgでContent-bodyを撮影したファイルにしている点

です。

このようにしてraspistillコマンドで撮影した画像をEmotion APIへ送信できます。

結果をみると

[{"faceRectangle":{"height":460,"left":1133,"top":756,"width":460},"scores":{"anger":0.0148205226,"contempt":0.0202304367,"disgust":0.00199702079,"fear":0.000178213842,"happiness":0.0006098823,"neutral":0.946034551,"sadness":0.013939213,"surprise":0.00219016313}}]

上記のようなJSONデータが帰ってきています。

ちなみにraspistillコマンドに-rot 180というオプションを指定していますが、cameraモジュールをフィルムケーブルを指す部分がモジュールの下部になり、 安定しておこうとすると、カメラの上下が反対になってしまうので入れているだけです。実際にはraspistill -o image.jpgで問題ありません。 MicrosoftのEmotion APIは顔が上下反対になっていたりすると認識できないようなのでそれに対する手になります。

やっほい!うまくいきました!

所詮shじゃん?もう少しなんとかならないの?

ですよね~。ってことでpythonからも触れるようにしたいと思います。

pythonからcameraモジュールを制御してみる

pythonからcameraモジュールにアクセスするためにpicameraというモジュールを導入します。詳しくは以下のサイトを参考にします。

参照:Python picamera - Raspberry Pi Documentation

参照:Documentation for picamera — Picamera 1.2 documentation

picameraをインストールする

pipでもいいのですが、Raspberry Piなのでapt-getでインストールすることにします。

$ sudo apt-get install python-picamera

これで完了です。もしpipでインストールするなら以下の様になるかと思います。(これでいいはず…)

$ sudo pip install picamera

対話型のインターフェースでimportしてみてエラーが出なければ正常にインストールできています。

$ python
Python 2.7.9 (default, Mar  8 2015, 00:52:26)
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import picamera
>>>

picameraを使用してみる

picameraのインポートが成功したのでpythonで撮影したカメラ画像をEmotionAPIに送ってみましょう。途中のコードに

with picamera.PiCamera() as camera:
        camera.start_preview()
        camera.hflip = True
        camera.vflip = True
        time.sleep(2) #カメラ初期化
        camera.capture('foo.jpg')

となっている部分がありますが、この部分がカメラ撮影をしてfoo.jpgというファイルに出力している部分です。hflipとvfilpの設定がありますが、カメラの置き方によって画像の方向が変わる可能性があるので、適宜変更してください。ちなみにEmotionAPIでは顔が正しい上下関係頭が上で顎が下になっているような画像でないと正しい結果を返さないので注意が必要です。(くどいですが)

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import requests
import json
import types
import time
import picamera

with picamera.PiCamera() as camera:
        camera.start_preview()
        camera.hflip = True
        camera.vflip = True
        time.sleep(2) #カメラ初期化
        camera.capture('foo.jpg')

url = 'https://api.projectoxford.ai/emotion/v1.0/recognize'
headers = {'Content-type': 'application/octet-stream', 'Ocp-Apim-Subscription-Key':'発行されたAPIキー'}
payload = open('./foo.jpg', 'rb').read()

r = requests.post(url, data=payload, headers=headers)
data = r.json()
dict = data[0]['scores']
max_key = max(dict, key=(lambda x: dict[x]))

print "key: %s,\t value:%f" %(max_key, dict[max_key])

後は、過去のエントリーと概ね変わりはないと思います。

uepon.hatenadiary.com

これでRaspberryPiとカメラがあれば表情を読みとりGPIOを制御するなんてこともできそうですね。次はそういうのを作ってみたいと思います。

Microsoft Emotion APIをRaspberryPiで使用してみる【requests版】

Microsoft Emotion APIをRaspberryPiで使用してみる

前回のエントリではMicrosoftEmotionAPIをテストサイトで実験することろまでやってみました。

uepon.hatenadiary.com

今回は多分に漏れずこれをRaspberryPiのpython(2系)から制御したいと思います。 テストの対象にした画像は以下になります。前回のlenaさんで検索したら違う玲奈さんが出てしまった。

https://pbs.twimg.com/profile_images/486393178153439232/iqm-9kRQ_400x400.png

pythonソースコード

公式サイト内のドキュメントをみれば主要なプログラミング言語のサンプルは載っています。 ただし、JSONをつかってURLを送信するパターンが限定であることと、urllibを使用ものだけとなっています。

Microsoft Cognitive Services

サンプルソースとしてはこれで申し分ないのですが(特にpythonは2系と3系の両方が書かれているのですばらしいサンプルページだと思います)、 個人的にはpythonのRequestsモジュール(http://docs.python-requests.org/en/master/)を使用することが多いのでこちらの使用を考えました。

JSON(Web上にアップされた画像)を使用するパターン

APIのテストページそのままの処理になります。

import requests
import json
import types

url = 'https://api.projectoxford.ai/emotion/v1.0/recognize'
payload = {'url':'https://pbs.twimg.com/profile_images/486393178153439232/iqm-9kRQ_400x400.png'}
headers = {'Content-type': 'application/json', 'Ocp-Apim-Subscription-Key':'発行されたKey'}

r = requests.post(url, data=json.dumps(payload), headers=headers)
data = r.json()
dict = data[0]['scores']
max_key = max(dict, key=(lambda x: dict[x]))

print "key: %s,\t value:%f" %(max_key, dict[max_key])

処理としてはRequestsのPOSTメソッドを使ってAPIのURLへアクセスします。 その際のヘッダには

headers = {'Content-type': 'application/json', 'Ocp-Apim-Subscription-Key':'発行されたKey'}

のようにKeyValueスタイルの値を渡します。Ocp-Apim-Subscription-Keyには登録時に発行されたキーを入力してください。

参考f:id:ueponx:20161016233525j:plain

POSTするデータの内容は以下のような

payload = {'url':'https://pbs.twimg.com/profile_images/486393178153439232/iqm-9kRQ_400x400.png'}

keyValueスタイルで変数に格納します。実際にはpythonの辞書型のオブジェクトなのでアクセスする際にはJSONデータに変換する必要があります。

アクセスするURL、HTTPヘッダ、解析する画像のURLを含んだJSONデータの準備ができたので以下のようにアクセスを行います。

r = requests.post(url, data=json.dumps(payload), headers=headers)

解析の結果はrとという変数に格納されますのでこれを解析することになります。

data = r.json()
dict = data[0]['scores']
max_key = max(dict, key=(lambda x: dict[x]))

結果からJSONデータを取り出し、その中のscoresから値が最大になるようなキーの値をmax_keyに格納する処理になります。maxをそのまま使うと、最大値のValueが取得されるのですが、このようにlambdaを使えばValueが最大値となるKeyを取り出すことができます。やっていることはそれほど難しくありません。

あとはprintで画面表示しています。

ローカルにある画像をOctet-Streamとして使用するパターン

JSON形式では画像がインターネット上にある必要があります。そのためにストレージの置場を作るのが難しい場合にはこちらを使うことになります。このパターンはなぜかサンプルに載ってなかったので作ってみました。

MicrosoftさんとしてはAzure上のストレージサービスにBLOB領域を作ってねって感じなのかもしれません。

以下のようなコードになります。

import requests
import json
import types

url = 'https://api.projectoxford.ai/emotion/v1.0/recognize'
headers = {'Content-type': 'application/octet-stream', 'Ocp-Apim-Subscription-Key':'発行されたKey'}
payload = open('解析したい画像ファイルのPATH', 'rb').read()

r = requests.post(url, data=payload, headers=headers)
data = r.json()
dict = data[0]['scores']
max_key = max(dict, key=(lambda x: dict[x]))

print "key: %s,\t value:%f" %(max_key, dict[max_key])

基本的な処理はほとんど変わりません。変更があるとすれば * HTTPヘッダのContent-typeがapplication/octet-streamに変更になる点 * ローカルにあるファイルをバイナリ形式で読み込む点 以上の2つになります。

HTTPヘッダは以下のようになります。

headers = {'Content-type': 'application/octet-stream', 'Ocp-Apim-Subscription-Key':'発行されたKey'}

Content-typeの値が変わっているのがわかるかと思います。

続いて、対象となる画像データをバイナリ形式で読み込みます。

payload = open('解析したい画像ファイルのPATH', 'rb').read()

後残りの処理は先ほどのJSONアクセスのパターンと全く同じになります。

まとめ

今回は同じ画像を使用してみましたが、結果はどちらの方式を使用しても同じ値が帰ってきました。ローカルファイルを使用する後者のほうががRaspberryPiでは使いやすいかもしれません。

本体のカメラで撮影して映っている人の表情を読み取ってGPIOの制御をするのも簡単に出来そうです。例えば帰宅時に奥さんの機嫌がいいとか悪いとかを教えてくれるようなガジェットはすぐに作れそうですねwそんな用途に使いたくないですけど。

Microsoft Emotion APIを使ってみる

Microsoft Emotion APIを使ってみる

最近使ってみようと調べていたのでメモ(かなり雑ですみません)

マイクロソフトのProject Oxfordというプロジェクトの成果とかそういうのは他のサイトでみればいいのでググってください。最近はいっぱい情報がでているのでそれを参考にしてみいいかもしれません。

サービスへの登録

まずはサービスに登録してAPIのキーを取得します。 公式サイトに行きましょう。EmotionAPIはMicrosoftのCognitiveServiceに含まれています。

www.microsoft.com

上記のURLにアクセスすると以下のような画面になります。

f:id:ueponx:20161016230611j:plain

中ほどにある【Get Started for Free】というボタンをクリックします。すると次のような画面に遷移します。

f:id:ueponx:20161016231409j:plain

画面の中ほどにある【Lets go】ボタンをクリックするとMicrosoft アカウントのログインを求められますのでログインをします。 予めログインが完了しているとボタンは表示されない画面になります。ログイン画面は表示されません。

ログインが完了するとどのサービスの試用をするか、選択する画面になります。

f:id:ueponx:20161016232442j:plain

この画面内のリストで使用するAPIにチェックをしていくことになります。(かなり多くのサービスを試用することができます。)

f:id:ueponx:20161016232740j:plain

そのなかで今回はEmotionAPIを試用するので以下のようにチェックを付けます。 以下のものにチェックをつけてください。

  • Emotion - Preview 30,000 transactions per month, 20 per minute.
  • I agree to the Microsoft Cognitive Services Terms and Microsoft Privacy Statement.

f:id:ueponx:20161016233306j:plain

f:id:ueponx:20161016233302j:plain

チェックを行うと【Submit】ボタンがアクティブになりクリックできるようになりますのでクリックします。

f:id:ueponx:20161016233525j:plain

すると、EmotionAPIの試用が可能になります。試用制限は画面にも書いてありますが

30,000 transactions per month, 20 per minute.

なので20回/分で月に30000回の試用が可能になっています。

試用してみる

先程のページでKey1とKey2の2つがありますが、そのうちのKey1の下辺りにあるCopyをクリックします。これでAPIに必要なキーがクリップボードにコピーされます。

f:id:ueponx:20161016234444j:plain

つづいて、EmotionAPIのページに移ります。

www.microsoft.com

f:id:ueponx:20161017000521j:plain

画面内にある【API Reference】をクリックします。 クリックするとEmotion APIのリファレンスページに遷移します。

f:id:ueponx:20161017000734j:plain

リファレンスページがとても優秀なのでAPI制限やRequestURL、HTTPヘッダー、HTTPレスポンス、主要言語のソースコードも載っています。

とりあえず、動作を確認するには中ほどにある【Open API Testing Console】のボタンをクリックします。すると次のようなAPIをWebページ上でテストできるようなページに遷移します。

f:id:ueponx:20161017001215j:plain

ページ中ほどにある【Ocp-Apim-Subscription-Key】の入力ボックスに先程入手したキーをペーストします。そして【Request body】のボックスにAPIの解析対象になる画像のURLをJSON形式で入力します。今回は画像処理でよく使用されているレナさんを対象にしたので以下のようにしてみました。

{ "url": "http://www.cs.cmu.edu/~chuck/lennapg/len_top.jpg" }

入力が完了すると以下のようになると思います。

f:id:ueponx:20161017002713j:plain

入力が完了したら【Send】ボタンをクリックします。クリックするとResponse同じ画面の下の方に表示されます。

f:id:ueponx:20161017002849j:plain

Pragma: no-cache
apim-request-id: b47957e8-4dc7-4d32-8b35-97165b6bde41
Cache-Control: no-cache
Date: Sun, 16 Oct 2016 15:23:03 GMT
X-Powered-By: ASP.NET
Content-Length: 257
Content-Type: application/json; charset=utf-8
Expires: -1

[
  {
    "faceRectangle": {
      "height": 68,
      "left": 177,
      "top": 85,
      "width": 68
    },
    "scores": {
      "anger": 3.3987697E-05,
      "contempt": 0.000354579,
      "disgust": 2.710808E-07,
      "fear": 3.346522E-06,
      "happiness": 0.00406290637,
      "neutral": 0.995369,
      "sadness": 6.767311E-05,
      "surprise": 0.000108244079
    }
  }
]

Responseの内容はJSONで帰ってきます。scoresの中にあるパラメータが解析結果となります。一番大きい値が解析された感情になります。今回はneutralの値が一番大きいので自然な表情だったことがでたようです。

終わりに

MicrosoftのCognitiveServiceの一つである、EmotionAPIの登録と試用をやってみました。ソースコードもあるのでとても親切なサービスのようです。今後はRaspberryPiなどでも実験して見る予定です。

RaspberryPiで複数のWiFiのアクセスポイントで固定IPの設定を登録する

RaspberryPiで複数のWiFiアクセスポイントで固定IPの設定を登録する

RaspberryPiを家で使用している時には固定IPで運用しているのですが、ハッカソンなどにいくと会場に設営されたWiFiに接続したり、個人持ち込みのPocketWiFiで運用したりとなり、最初にネットワークの設定で手間取ることが多くてRaspberryPiを使用した作品の制作から少し離れてしまうことが多くありました。(デモで機器が使えないのは正直キツイです)

そこで自宅でも、出先でも固定IPで使用できるようにしようと思いました。


参考にしたのは以下になります。ただ、少し古いためwheezベースになっていたので少し変更する必要がありました。

www.1ft-seabass.jp


アクセスポイントの情報を取得する

この部分は1つのアクセスポイントであっても同じですが、設定する可能性のあるアクセスポイントすべての情報を取得します。 結果部分にはパスフレーズの暗号化されていないものも含まれていますが、不要なので削除して使います。

$ sudo wpa_passphrase 【SSID】 【パスフレーズ】
network={
  ssid="【SSID】"
  #psk="【パスフレーズ】(入力値)"
  psk=【パスフレーズ(暗号化された値)】
}

使用する可能性のあるアクセスポイントの情報が取得できたら次のステップに進みます。

設定ファイルを編集する

今回編集するのは/etc/wpa_supplicant/wpa_supplicant.conf/etc/network/interfacesの2つのファイルです。どちらもアクセスポイントが1つの時にも設定するファイルなのでそれほど気にしなくても良いかなと思います。

/etc/wpa_supplicant/wpa_supplicant.confの編集

以下で編集を行います。(可能であればオリジナルファイルのバックアップをとっておきます。)

$ sudo vi /etc/wpa_supplicant/wpa_supplicant.conf 

以下のように編集します。

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
    ssid="【家で使用する1つ目のアクセスポイントのSSID】"
    psk=【パスフレーズ(暗号化された値)】
    key_mgmt=WPA-PSK
    priority=0
    id_str="HOME"
}

network={
    ssid="【外出時に使用する2つ目のアクセスポイントのSSID】"
    psk=【パスフレーズ(暗号化された値)】
    key_mgmt=WPA-PSK
    priority=1
    id_str="OUTSIDE"
}

アクセスポイントが1つの時と異なるのはpriorityとid_strになります。設定値通り優先順位と設定の識別になります。id_strは家で使用する設定をHOME、外で使用するPocketWiFiの設定をOUTSIDEとしました。

/etc/network/interfacesの編集

以下で編集を行います。(可能であればオリジナルファイルのバックアップをとっておきます。)

$ sudo vi /etc/network/interfaces

以下のように編集します。実際にはauto lo以下の行になります。 今回は家で使用するIPアドレス体系をを192.168.0.xとし、RaspberryPiのアドレスを192.168.0.200とし、外で使用するPocketWiFiのIPアドレス体系を192.168.179.xとし、RaspberryPiのアドレスを192.168.179.200としています。

 interfaces(5) file used by ifup(8) and ifdown(8)

# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'

# interfaces(5) file used by ifup(8) and ifdown(8)

# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'

# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d

auto lo

iface lo inet loopback
iface eth0 inet dhcp

auto wlan0
allow-hotplug wlan0

iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp

iface HOME inet static
address 192.168.0.200
netmask 255.255.255.0
gateway 192.168.0.1

iface OUTSIDE inet static
address 192.168.179.200
netmask 255.255.255.0
gateway 192.168.179.1

複数のアクセスポイントを使う設定として特徴のある点は /etc/wpa_supplicant/wpa_supplicant.confで設定したid_strifaceの設定として与えている部分とWiFiの設定ファイルの呼び出し部分を(旧)wpa-conf /etc/wpa_supplicant/wpa_supplicant.confから(新)wpa-roam /etc/wpa_supplicant/wpa_supplicant.confとしている部分になります。


実験

設定画終了したので念のためリブートをしてみたところ、一応アクセスができるようになりました。ただ、両方のアクセスポイントがあると設定に時間がかかってしまうようです。(相当時間はかかるのですが、その後両方のアクセスポイントのIPアドレスが使えるようになるようです。) とはいえ、アクセスポイントが共存することはなかなか無いかなと思うのでこれで良しとします。

まとめ

一応、複数のアクセスポイントが固定IPでも使用できるように設定ができました。これで、少しはRaspberryPiの作成のハードルも低くなるかなと思います。 ただ、インターフェースにIPが複数割り当てられるのが気になります、これってどういう状況なんでしょうか。

BitBalloonの使い方メモ

BitBalloonの使い方のメモ

今回にエントリーは内容が薄いので読まなくてもいいかなと思います。

ぜひ参照先をみてください。

blog.mlkcca.com

先日(といっても一ヶ月ほど立ってしまいましたが)、Milkcocoaのハンズオンに参加してきました。 Milkcocoaのサービスは少しかじっていましたが、ちゃんとした説明を受けたことがなかったので、いい刺激になりました。 その中で可視化するための仕組みでどうしてもWebサイトらしきものを作って見ないといけないことがあるので、その部分に関しては 敷居が少しあるなと感じていた(これ見ておいてって言う感じでメールを投げにくいかった)のですがハンズオンの中でBitBalloonという サービスの紹介があり、これには結構驚きました。

すでに一ヶ月も前のことでもあるので、備忘録としてメモを取っておこうと思います。多分、名前さえ覚えておけばこのメモも不要なぐらいに簡単だと思います。

BitBalloonとは

簡単に言うとhtmlなサイトを超簡単にホスティングしてくれるサービスになります。

サイト作成

以下にアクセスします。

www.bitballoon.com

f:id:ueponx:20160916120547j:plain

サインアップしろという内容がありますが、今回はテストとしてなので気にせず、右側にある「Drag Your Site Folder Here」にHTMLやJavascriptなどのファイルをドロップしてみます。

今回使ったのはMilkcocoaさんのChatサンプルのデータとなります。

f:id:ueponx:20160916120809j:plain

ファイル構成としては上のような3つのファイルからの構成になります。文面としてはFolderをドロップしない行けないように見えますが、使用するファイルすべてドロップしても問題はないみたいです。

ドラッグ&ドロップすると処理が開始します。

f:id:ueponx:20160916121102j:plain

ファイルが少なければものの数十秒で処理が完了し、サイトへアクセスできるようになります。

f:id:ueponx:20160916121333j:plain

URLなども生成してくれるので、これに対してアクセスをすると 以下のように使用ができるようになります。

f:id:ueponx:20160916121636j:plain

ちゃんとJavaScriptからMilkcocoaへのデータのやり取りもできるので短時間でサイトを作らないといけないときや、一時的にチェックしたい用途には便利そうです。

サイトの削除

管理画面の下にある【Delete the site】をクリックすると

f:id:ueponx:20160916122158j:plain

削除用のダイアログが開くので、入力ボックスに作成したサイトの名前を入力し【Delete】ボタンをクリックすれば削除が行われます。

f:id:ueponx:20160916122557j:plain

所感

すでにバックエンドが完成していて、フロントエンドをなんとしないと行けない場合には、かなりいい感じでしょうか。ハッカソンなどで短時間にサービスを作る場合にはかなり役に立つかなと思います。ある程度セキュリティの担保も行いたい場合にはパスワードなどもかけられるようなので、ちゃんとログインしてつかうことはいうまでもありませんけど。

しあし、FTPなどではなく、ドラッグ・アンド・ドロップでもういい時代は結構きているんだなと関心しました。

ちなみに

画像などの静的ファイルだけを置こうとすると

f:id:ueponx:20160916123146j:plain

index.htmlは必須だよと怒られます。index.htmlと一緒にドラッグ・アンド・ドロップを行えばいいようですが、その時はフォルダとしてドロップしないと処理が完了しないようです。成功すれば静的ファイルのURLをダイレクトに指定すれば参照は可能のようです。

/* -----codeの行番号----- */