かれ4

かれこれ4個目のブログ

Amazon Linuxのコンテナイメージを自分のdocker hubのリポジトリにコピーする

New Amazon Linux Container Image for Cloud and On-Premises Workloads | AWS Blog

こんなリリースがあったけど、ecrとイチャイチャしたり、色々めんどくさいから、手元で使いやすいように

規約的に大丈夫かわからないので自己責任で

#!/bin/bash

if [ $# -ne 1 ]
then
  echo "USAGE: $0 {MY_REPOSITORY}"
  echo " "
  exit;
fi
REPOSITORY=$1

LOGIN_CMD=$(aws ecr get-login   --registry-ids 137112412989)
eval "$LOGIN_CMD"

for image in $(aws ecr list-images --registry-id 137112412989 --repository-name amazonlinux |jq -r .imageIds[].imageTag);
do
  docker pull 137112412989.dkr.ecr.us-west-2.amazonaws.com/amazonlinux:${image}
  echo "IMAGE reTAG========================================================="
  docker images |grep "amazonaws.com/amazonlinux" |grep "${image}" | perl -anle 'print "$F[2]"' | xargs -I{} docker tag {} ${REPOSITORY}/amazonlinux:${image}
  echo "IMAGE push========================================================="
  docker push ${REPOSITORY}/amazonlinux:${image}
done

SORACOM Airを使わずに、SORACOMを楽しむ方法

はじめに

SORACOMリリース1周年記念リレーブログ 11月1日分です。 blog.soracom.jp

SORACOMももう1周年という事で、色々とサービスが増えて来ました。 まずは各サービスをGoogle Trendで見てみます。

↑読み込み遅いけどGoogle Trendsのグラフ出ます。

↑読み込み遅いけどGoogle Trendsのグラフ出ます。

SORACOM Airが 2014/7/6 - 12の間に検索されていたりするのは、 創業者二人が飲みながら名前を考えているときに、 検索していたのかなと想像すると楽しいですね。

AirとBeamの検索量にたいして、他のサービスはGateがかろうじて 検索されている位の状況です。

ということで、今回はCanal周りを中心に遊んでみようと思います。

VPGで遊ぶ

まずはVPGで遊んでみたいと思います。 VPGを作成するところから。

VPGの作成

$ soracom vpg create --device-subnet-cidr-range=10.0.0.0/9  --primary-service-name=canal
{
    "createdTime": 1477998721142,
    "deviceSubnetCidrRange": "10.128.0.0/9",
    "lastModifiedTime": 1477998722107,
    "operatorId": "OP0012950956",
    "primaryServiceName": "Canal",
    "status": "creating",
    "tags": {},
    "type": 12,
    "ueSubnetCidrRange": "10.128.0.0/9",
    "useInternetGateway": true,
    "virtualInterfaces": null,
    "vpcPeeringConnections": null,
    "vpgId": "********-****-****-****-************"
}

コマンドラインでサクと作ります。
### statusがrunnningになればvpg作成完了
$ soracom  vpg get --vpg-id=acf68be6-83f7-44c3-9fd5-bd741a434176 |jq -r .status
running

特に難しいこともなく、作成完了です。

$ soracom vpg list-ip-address-map-entries --vpg-id=********-****-****-****-************
[
    {
        "hostId": "100.64.148.132",
        "ipAddress": "10.64.148.132",
        "key": "100.64.148.132",
        "type": "gatePeer"
    },
    {
        "hostId": "100.64.148.4",
        "ipAddress": "10.64.148.4",
        "key": "100.64.148.4",
        "type": "gatePeer"
    }
]

f:id:tottokug:20161102003139p:plain

 なにやら、アドレスが2個作成されています。  推測ですが、VPGというのはVPCと(AZにまたがって)EC2が2台という構成で作られているのでは無いかと推測できます。  今作成したものであれば、  100.64.128.0/17と100.64.0.0/17というサブネットがあるのではないかと思います。

 このVPCがアカウント毎に違うVPCなのか、同じVPCなのかは今回は検証していませんが、おそらく別れていることでしょう。

AWS側でVPCを作って遊んでみる

こちらもさくと作ります。

$ aws ec2 create-vpc --cidr-block 172.19.0.0/16
{
    "Vpc": {
        "VpcId": "vpc-467*****",[f:id:tottokug:20161102003146p:plain]
        "InstanceTenancy": "default",
        "State": "pending",
        "DhcpOptionsId": "dopt-ada4b3cf",
        "CidrBlock": "172.19.0.0/16",
        "IsDefault": false
    }
}

f:id:tottokug:20161102003141p:plain

VPGとAWS VPCをつなぐ

VPCとつなぐのはコマンド一つのお手軽さです。

$ soracom vpg create-vpc-peering-connection \
--destination-cidr-block=172.19.0.0/16 \
--peer-owner-id=01234567890123 \
--peer-vpc-id=vpc-********** \
--vpg-id=********-****-****-****-************

これで、SORACOM側のAWSアカウントから、指定したVPCに対してPeeringのRequestが届きます。

それをAWS側でAcceptすることで、Peeringが完成しました。 f:id:tottokug:20161102003146p:plain

VPGとSORACOMのVPCの関係について後日追記予定の内容があります。

Subnetの作成とRouteTableの設定とEC2の起動

先程Peeringを作ったVPCもそのままでは特に何もないネットワークなので、 もうちょっと遊ぶために、Subnet(172.19.8.0/24)を作成し、 RouteTableに100.64.0.0/16 への通信をpeeringに渡す設定とSecurity Groupを適切に設定する事で、 AirからEC2への疎通は出来るはずです。 今回はAirは使っていないので、確認はできていません。。。

f:id:tottokug:20161102003148p:plain

EC2からアクセス出来るのはどこまでなのか

そして、今日の本題。 EC2からSORACOMのどこまでアクセス出来るのか試してみたいと思います。

Doorがあればまた話しは変わってくるのかもしれませんが、 今回はSORACOM CanalとSORACOM GateだけでEC2がどこまでアクセス出来るのかを試していきたいと思います。 vxlanの設定までを https://dev.soracom.io/jp/start/gate/ ここを見ながら終わらせます。

$ soracom vpg register-gate-peer --outer-ip-address 172.19.8.253 --vpg-id ********-****-****-****-************
{
    "innerIpAddress": "10.18.216.109",
    "netmask": null,
    "outerIpAddress": "172.19.8.253",
    "ownedByCustomer": true
}

SORACOM Air

これは公式ドキュメント https://dev.soracom.io/jp/start/gate/#step5 にも書いてある事で出来るはずです。 今回はSORACOM Airを使わないで楽しむことが目的なので、割愛します。

SORACOM Beamに

SORACOM Beamには100.127.127.100というIPアドレスがついています。 このネットワークにアクセス出来ると良いですね。 とりあえず、単純にRouteTableに100.127.0.0/16へのルートをPeeringに向けてみます。

$ nmap 100.127.127.100

Starting Nmap 6.40 ( http://nmap.org ) at 2016-11-01 14:58 UTC
Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn
Nmap done: 1 IP address (0 hosts up) scanned in 3.03 seconds

SORACOM Funnelに

Beamのときと同様にfunnel.soracom.io (100.127.65.43)にも

$ nmap  100.127.65.43

Starting Nmap 6.40 ( http://nmap.org ) at 2016-11-01 15:01 UTC
Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn
Nmap done: 1 IP address (0 hosts up) scanned in 3.03 seconds

さいごに

結論、頑張ったけど、EC2からBeamにもFunnelにも到達することはできませんでした。

もし、EC2から直接BeamやFunnelにアクセス出来たならば、 MQTTのフルマネージドサービスを手に入れることができ、 SORACOMをIoTのサービスではなく、データフローのサービスとしても楽しむことが出来るはずです。

VPGはセットアップの時に 980 円/回 (税別)がかかるのと、 VPG 利用料金: 1時間あたり 50 円 (税別) VPC ピア接続利用料金: 1ピア接続・1時間あたり 10 円 (税別) [2016/11/1 現在] がかかるので遊び終わったら削除する事と、無駄にVPGを作成しないことで 突然の課金にびっくりすることはないでせう。

と、自己満足に浸ったところで、11/1分はおしまいです。

Logicool (Logitech) R800の各ボタンのキーコード

Logicool R800とは

プレゼンを日常的に行う人なら誰でも一本は持っているであろう、道具。 これがあれば、PCの前にいなくてもKeynotePowerpointのスライド送りをすることが出来るすぐれもの。

LOGICOOL プロフェッショナルプレゼンター タイマー機能・LCD搭載 R800

LOGICOOL プロフェッショナルプレゼンター タイマー機能・LCD搭載 R800

R800はキーボード

PCに接続すると配列を問うダイアログが出たりすることから、キーボードとして認識される事は有名ですが、 キーコードはあまり知られていません。 各ボタンに対応するキーコードがわかれば、ブラウザでのデモなんかにも応用することが出来るようになってきます。

R800のボタン

f:id:tottokug:20160522162102p:plain

上の写真の通り、このプレゼンターには前面に5個のボタン 写真ではわかりませんが、右側面に2個のぜんぶで7個のボタンがついています。

このうち、PCに認識されているボタンとしては以下の画像の4つになります。

f:id:tottokug:20160522162449p:plain

キーコード表

位置 ボタン コード キーボード
左上 f:id:tottokug:20160522163732p:plain 33 PageUp
右上 f:id:tottokug:20160522163740p:plain 34 PageDown
左下 f:id:tottokug:20160522163747p:plain 27/116 Esc/F5
右下 f:id:tottokug:20160522163751p:plain 190 .

f:id:tottokug:20160522163747p:plainのボタンはF5とEscがトグルになっていて、27->116->27->....と交互にキーコードを送ってきます。

Visual Stuidio Code の0.10.6が出来たようです。

Macの日本語環境でVisual Studio Codeが動かなくなって困ったけれど
0.10.6が出てたみたいです。
おそらくこの0.10.6はupdateChannel が insiderのやつかと思われます。

このバージョンだとMacの日本語環境でも問題なく動きました。

github.com


ビルド済みのバージョンは以下からダウンロード出来ます。
https://az764295.vo.msecnd.net/public/0.10.6/VSCode-darwin.zip

ここのバージョン番号を書き換えればVisual Studio Codeのサイトでダウンロード出来ないバージョンもダウンロード出来ます。(2015/12/23)

Azure Advent Calendar - 三倉姉妹(マナカナ)をAzureを使って見分ける

Microsoft Azure Advent Calendar 2015 の20日目の記事です。


今回はProject Oxfordを使って三倉姉妹(マナカナ)の判別を行いたいと思います。

三倉姉妹とは?

三倉姉妹とは、三倉茉奈三倉佳奈の双子の女優・タレント・歌手です。
通称マナカナと呼ばれている人たちです。

「左がマナで、右がカナ。」という言葉が出来るほどに判別は難しく、人類がこれまで幾度と無く挑戦し失敗し諦めてきた大きな課題です。



準備としては、
まずBing Search APIを利用してマナカナの画像を集め、
blog.tottokug.com
Project OxfordのFace APIを使ってかおの画像を切り出しました。
blog.tottokug.com

今日はついにマナカナを判別する所を実装していきます。

実装するは言い過ぎました。実装は特にしません。

Project Oxfordの機能を使って、

といった感じに、Face APIに全てを任せます。

マナカナ判別用教師データの作成。

今回使うのもProject OxfordのFace APIです。
Face APIを使いはじめるところまでは、前回のマナカナの画像からProejctOxfordとimagemagickで顔を切り出す。 - かれ4で書いた通りで、
今回はここからさらにマナカナをマナとカナに分類することをしていきます。

今回は顔を切り出す必要はないので、ImageMagickは使わずにただBounding Boxを一覧化するところまでをおこえば良いのかなと。
気をつけないと行けないのはfaceAPIは秒間1回くらいの利用しか認めておらず、それを超えるとエラーが帰ってくるので要注意です。
なので、sleep 1などを入れて1秒待機させる事にすると回避出来るので、スリープはぜひ入れましょう。

#!/bin/bash
IFS='
'
APIKey=***************************************
[ -d images/detected ] || mkdir -p images/detected
for f in $(find ./images/manakana -type f);
do
  curl -X POST  -H "Content-Type: application/octet-stream" --data-binary @${f} \
  "https://api.projectoxford.ai/face/v0/detections?subscription-key=${APIKey}"  \
  |jq -r ".[]  | [\"$f\",.faceId,.faceRectangle.width,.faceRectangle.height,.faceRectangle.left,.faceRectangle.top] | @csv"  >> faceindex.csv
  mv "${f}" images/detected/
 sleep 1
done

これで faceindex.csvに下記のような

画像ファイル名,faceId,幅,高,x,y

という形式でのCSVファイルが吐き出せました。

"./images/manakana/00011738_02A.jpg","a6415064-2720-4c84-8dff-7701f006f36d",81,81,123,93
"./images/manakana/00011738_02A.jpg","3d957436-a206-4d78-839a-bc0174345f77",77,77,546,144
"./images/manakana/00011738_02A.jpg","2bf5f7dd-c9c5-45e5-acab-6a58b13da0ad",75,75,415,136
"./images/manakana/000504.jpg","0913d773-c52f-45f4-8dce-16ba86b26d42",115,115,28,75
"./images/manakana/001-199x300.jpg","94f18b64-1faf-425f-a064-1a203b8c4140",42,42,87,26
"./images/manakana/001-199x300.jpg","fc8407f4-4722-4e58-ad10-f5e1d1efb733",39,39,34,54
"./images/manakana/001.jpg","87de0b21-ee19-4072-bf7d-b6d14895578c",76,76,96,104
"./images/manakana/0014d0d9.jpg","ca4d66a1-2243-44ac-b084-c1703d419ff6",133,133,145,368
"./images/manakana/0014d0d9.jpg","7a71404c-81b3-4562-8f24-3d78e455b480",122,122,419,370
"./images/manakana/001l.jpg","a967b8e8-a50d-43be-beb7-5d718e0577bd",90,90,199,89

この処理はスリープが入っているので、時間がかかります。
待っている間に、先にPersonGroupの作成とPersonの作成をしてしまいます。
どちらも、繰り返し行う動作ではないのでブラウザでさくっとやってしまいます。
API Referenceから実行出来るようになっているので、そこから実行します。
最近API Referenceから実行出来るようなのが増えていますね。


Person Groupの作成

f:id:tottokug:20151220231830p:plain

f:id:tottokug:20151220231834p:plain

Person の作成

f:id:tottokug:20151220231418p:plain
f:id:tottokug:20151220231421p:plain
f:id:tottokug:20151220231436p:plain

Personができていることの確認

f:id:tottokug:20151220231438p:plain
f:id:tottokug:20151220231442p:plain


学習させる

ここまでで準備は整ったので、ついに学習させていくことになります。
学習させるためには、Face APIのPersonにあるAdd Faceを利用してまずは顔を登録していきます。
今回は顔を検出した結果、2人で写っているものだけを学習用に使い、1人もしくは3人以上で写っている画像を検証用に使います。

2人で写っているものを使う理由として、マナカナには「左:マナ、右:カナ」というルールがあるためです。
ここが今回一番大切な所です。
他にもカナの左目の下にほくろがあるとか、鼻の穴の角度が違うとかそんな見分け方も有りますが、それは今回は使いません。

大切な事なので、もう一度。
「左がマナで、右がカナです。」

言い換えると、Bounding BoxのLeftの値が小さい方がマナ、大きい方がカナです。
というわけで、2人で写っている画像を探し出してきてその画像と一緒に、顔の位置の情報を送ります。


#!/bin/bash
IFS='
'
APIKey=**************************************
personGroupId="manakana"
mana="4314b829-559c-4350-81d5-7bb24b4041e7"
kana="6eb1744b-a7e6-4782-acb4-6a35ec74a8a1"

for file in $(cat faceindex.csv|cut -d',' -f1  |sort |uniq -c  |grep "^\s*2"|perl -pe "s|.*images/manakana(.*?)\"|images/detected\1|g ");
do
  personId=$mana
  for bb in $(cat faceindex.csv |grep  "${file##*/}" |perl -pe "s|.*,(\d+),(\d+),(\d+),(\d+)|\3,\4,\2,\1|g")
  do
    echo "========="
    target=$bb
    eretry=1
    while :
    do
      URL="https://api.projectoxford.ai/face/v1.0/persongroups/${personGroupId}/persons/${personId}/persistedFaces?targetFace=${target}"
      faceId=$(curl -X POST "$URL" \
      -H "Content-Type: application/octet-stream" \
      -H "Ocp-Apim-Subscription-Key: ${APIKey}" \
      --data-binary @./${file} \
      )
      if [ ! -z "$(echo $faceId |grep RateLimitExceeded)"  ]
      then
        eretry=$(expr "$eretry" + "$eretry" )
        echo "retry ${eretry} sec ago"
        sleep ${eretry}
        continue
      fi
      echo "$file,$faceId,$bb" >> registIndex.csv
      break;
    done
    personId=$kana
    sleep ${eretry}
  done
done

ここで指定している

mana="4314b829-559c-4350-81d5-7bb24b4041e7"
kana="6eb1744b-a7e6-4782-acb4-6a35ec74a8a1"

はpersonを作った時に付与されたPersonIdになっています。
また、このAPIは1秒のSleepを入れても、RateLimitExceededが出てしまうので、出てしまった場合は1秒、2秒、4秒と増やしながらリトライする処理が入っています。
ひとまずこれで顔の登録が完了しました。

学習の開始

学習の開始は非常に簡単です。
これも繰り返し行う動作ではないのでブラウザ上で行ってしまいます。
https://dev.projectoxford.ai/docs/services/563879b61984550e40cbbe8d/operations/563879b61984550f30395249/console
こちらから
personGroupIdを指定してsendで完了です。
f:id:tottokug:20151221005302p:plain
Queueに登録するだけなので、202 Acceptedが帰ってきていれば成功です。
f:id:tottokug:20151221005733p:plain

学習の結果確認

こちらも繰り返し行うものではないので、ブラウザ上で確認します。
f:id:tottokug:20151221005736p:plain

f:id:tottokug:20151221005739p:plain

無事に成功しているようです。
今回顔画像をそれぞれ250枚ほど登録していますが、
約1分程度でステータスはSucceededになっていました。

検証

それではドキドキのマナカナが見分けられるかどうかのテストになります。

テストにはファイルを指定して、そのままどっちなのか判定出来るように以下のスクリプトを使います。

#!/bin/bash
IFS='
'
APIKey=****************************************

faceId=$(curl -s -X POST "https://api.projectoxford.ai/face/v1.0/detect?returnFaceId=true" \
-H "Content-Type: application/octet-stream" \
-H "Ocp-Apim-Subscription-Key: ${APIKey}" \
--data-binary @${1} \
| jq -r  .[].faceId)

echo "FACE ID = $faceId"
curl -s -X POST "https://api.projectoxford.ai/face/v1.0/identify" \
-H "Content-Type: application/json" \
-H "Ocp-Apim-Subscription-Key: ${APIKey}" \
--data-ascii "{\"personGroupId\":\"manakana\",\"faceIds\":[\"${faceId}\"],\"maxNumOfCandidatesReturned\":1 }" \
| jq -r '.[].candidates[] |[.personId,.confidence] | @csv' \
|perl -pe "s/4314b829-559c-4350-81d5-7bb24b4041e7/mana/g; s/6eb1744b-a7e6-4782-acb4-6a35ec74a8a1/kana/g"

マナの判定

ではまずは、こちらの画像から
f:id:tottokug:20151221012106j:plain

$ ./identify.sh images/detected/mikuramana.jpg
FACE ID = efd9608a-b6ff-47a9-84cc-4107f9789d2d
"mana",0.6302

無事にmanaと判定されました。

カナの判定

次に,この画像から、kanaと判別されれば成功です。

f:id:tottokug:20081227164536j:plain

$ ./identify.sh images/detected/kana.jpg
FACE ID = 6ff3601d-a2f6-4ba5-81e0-0e6a39df2a16
"kana",0.73804


無事に認識されました。


これで、マナカナを見分ける事が出来るようになりました。