Pepperで撮影した写真をAmazon Rekognitionで分析してその結果をPepperがしゃべる ~(1)AWS編~
2018/07/10
Pepperの機能を使えるところは使って、何かしたいなあと思ってまして。
目(カメラ)が付いてて、音声(スピーカー)で話すことが出来るので、とりあえずは画像分析からかなと思いまして、Amazon Rekognitionを使ってみました。
※ソフトバンクロボティクスのPepperを活用し、私が独自に実施しているものです。
(1) PepperからはAPI Gateway経由でLambdaを実行します。
(2) Pepperからアップロードされた画像はS3に格納されます。
(3) その画像は、Amazon Rekognitionによって画像解析されてその結果がAPI Gateway経由でレスポンスンとして戻ります。
(4) レスポンスをPepperが会話文に整形して話します。
今回はAWS側の開発(1)~(3)について記載します。
AWS側にはこれらが必要です。
API GatewayとLambdaで実装します。
- Pepperから送信される画像をS3に格納する
- S3の画像をAmazon Rekognitionで分析する
リポジトリはGithubです。
LambdaのランタイムはPython3系です。
目次
撮影した写真をS3に格納する
1 2 3 4 5 6 7 8 9 10 11 12 13 |
s3 = boto3.resource('s3') bucket = s3.Bucket(bucekt_name) image_body = base64.b64decode(event['body-json']) n = 10 key = ''.join([random.choice(string.ascii_letters + string.digits) for i in range(n)]) bucket.put_object( Body=image_body, Key=key ) |
- バイナリデータをb64decodeでデコード
- S3オブジェクトキーをrandomで生成
- buckt.put_objectでS3に画像ファイルをアップロード
API Gatewayの設定
バイナリメディアタイプ
[設定] – [バイナリメディアタイプ]に、image/jpg を設定
他は任意で追加
本文マッピングテンプレート
[リソース] – [統合リクエスト] – [本文マッピングテンプレート]
Content-Typeに image/jpg を追加。
テンプレートの生成は「メソッドリクエストのパススルー」を設定。
他のContent-Typeは任意で追加。
(参考)リクエストを送信するクライアント
1 2 3 4 5 6 7 |
data = open(file_path, 'rb').read() response = requests.post( url=api_url, data=data, headers={'Content-Type': 'image/jpg'} ) |
- 画像ファイルをdata引数にわたす
- headersでContent-Typeで image/jpgを設定
画像を解析する
1 2 3 4 5 6 7 8 9 10 11 12 13 |
client = boto3.client('rekognition') response = client.detect_faces( Image={ 'S3Object': { 'Bucket': bucekt_name, 'Name': key } }, Attributes=['ALL'] ) return response |
- 引数のバケット名、オブジェクトキー対象の画像を分析
- バージョニングしているS3の場合はバージョンIDを指定することも可能
これ1行で書けちまってるんですよね。
Rekognition 顔分析(detect_faces)のレスポンス
FaceDetailsのに画像の中の人数分の結果が配列になって戻される。
key | 内容 | 値の例 |
---|---|---|
AgeRange.Low | 年齢幅の下 | 26 |
AgeRange.High | 年齢幅の上 | 43 |
Smile.Value | 笑顔か | true or false |
Smile.Confidence | 笑顔の可能性 | 88.67390441894531 |
Eyeglasses.Value | 眼鏡をしているか | true or false |
Eyeglasses.Confidence | 眼鏡をしている可能性 | 99.99993133544922 |
Sunglasses.Value | サングラスをしているか | true or false |
Sunglasses.Confidence | サングラスをしている可能性 | 99.99896240234375 |
Gender.Value | 性別 | Male or Female |
Gender.Confidence | 性別の可能性 | 52.36514663696289 |
Beard.Value | 髭が生えているか | true or false |
Beard.Confidence | 髭の可能性 | 99.86187744140625 |
Mustache.Value | 口ひげが生えているか | true or false |
Mustache.Confidence | 口ひげの可能性 | 99.57250213623047 |
EyesOpen.Value | 目が空いているか | true or false |
EyesOpen.Confidence | 目が空いている可能性 | 99.9950942993164 |
MouthOpen.Value | 口が空いているか | true or false |
MouthOpen.Confidence | 口が空いている可能性 | 98.92902374267578 |
Emotions.Type | 感情 | HAPPY,SAD,ANGRY |
Emotions.Confidence | 感情の可能性 | 98.92902374267578 |
※Emotionsは配列です。
※Emotionsの値にはHAPPY,SAD,ANGRY,CONFUSED,DISGUSTED,SURPRISED,CALM,UNKNOWNがあります。
レスポンスの例
上記以外にも画像内の位置情報も戻ってきます。
以下は実際のレスポンスです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
{ "FaceDetails": [ { "BoundingBox": { "Width": 0.5432692170143127, "Height": 0.5432692170143127, "Left": 0.1586538404226303, "Top": 0.39423078298568726 }, "AgeRange": { "Low": 26, "High": 43 }, "Smile": { "Value": true, "Confidence": 88.67390441894531 }, "Eyeglasses": { "Value": false, "Confidence": 99.99993133544922 }, "Sunglasses": { "Value": false, "Confidence": 99.99896240234375 }, "Gender": { "Value": "Female", "Confidence": 52.36514663696289 }, "Beard": { "Value": false, "Confidence": 99.86187744140625 }, "Mustache": { "Value": false, "Confidence": 99.57250213623047 }, "EyesOpen": { "Value": true, "Confidence": 99.9950942993164 }, "MouthOpen": { "Value": false, "Confidence": 98.92902374267578 }, "Emotions": [ { "Type": "HAPPY", "Confidence": 97.94617462158203 }, { "Type": "CALM", "Confidence": 3.9698123931884766 }, { "Type": "DISGUSTED", "Confidence": 3.0542492866516113 } ], "Landmarks": [ { "Type": "eyeLeft", "X": 0.3193352520465851, "Y": 0.6057592630386353 }, { "Type": "eyeRight", "X": 0.48970475792884827, "Y": 0.5856793522834778 }, { "Type": "nose", "X": 0.4043808877468109, "Y": 0.726554811000824 }, { "Type": "mouthLeft", "X": 0.3604806959629059, "Y": 0.7941246032714844 }, { "Type": "mouthRight", "X": 0.5140022039413452, "Y": 0.7713675498962402 }, { "Type": "leftPupil", "X": 0.3010416626930237, "Y": 0.6047616600990295 }, { "Type": "rightPupil", "X": 0.47773274779319763, "Y": 0.5898412466049194 }, { "Type": "leftEyeBrowLeft", "X": 0.24104659259319305, "Y": 0.554790735244751 }, { "Type": "leftEyeBrowUp", "X": 0.2922651171684265, "Y": 0.5291659832000732 }, { "Type": "leftEyeBrowRight", "X": 0.3543483316898346, "Y": 0.5445635914802551 }, { "Type": "rightEyeBrowLeft", "X": 0.438366562128067, "Y": 0.5284709334373474 }, { "Type": "rightEyeBrowUp", "X": 0.4927721917629242, "Y": 0.5032138824462891 }, { "Type": "rightEyeBrowRight", "X": 0.5485564470291138, "Y": 0.5106046199798584 }, { "Type": "leftEyeLeft", "X": 0.28682535886764526, "Y": 0.606676459312439 }, { "Type": "leftEyeRight", "X": 0.3523319363594055, "Y": 0.6040283441543579 }, { "Type": "leftEyeUp", "X": 0.3191685080528259, "Y": 0.5964699983596802 }, { "Type": "leftEyeDown", "X": 0.3192586898803711, "Y": 0.6154554486274719 }, { "Type": "rightEyeLeft", "X": 0.45716485381126404, "Y": 0.5941932797431946 }, { "Type": "rightEyeRight", "X": 0.5229200720787048, "Y": 0.5777791142463684 }, { "Type": "rightEyeUp", "X": 0.48767799139022827, "Y": 0.5762225389480591 }, { "Type": "rightEyeDown", "X": 0.4913938045501709, "Y": 0.5948292016983032 }, { "Type": "noseLeft", "X": 0.3742028474807739, "Y": 0.7420245409011841 }, { "Type": "noseRight", "X": 0.46468648314476013, "Y": 0.7333931922912598 }, { "Type": "mouthUp", "X": 0.4339665472507477, "Y": 0.7914789915084839 }, { "Type": "mouthDown", "X": 0.4400731921195984, "Y": 0.8227092027664185 } ], "Pose": { "Roll": -6.3993635177612305, "Yaw": -10.858695030212402, "Pitch": -12.548688888549805 }, "Quality": { "Brightness": 27.32587432861328, "Sharpness": 98.55191040039062 }, "Confidence": 99.9991455078125 } ], "OrientationCorrection": "ROTATE_0", "ResponseMetadata": { "RequestId": "3878b810-576c-11e8-b4ef-e9105707324f", "HTTPStatusCode": 200, "HTTPHeaders": { "content-type": "application/x-amz-json-1.1", "date": "Mon, 14 May 2018 11:44:55 GMT", "x-amzn-requestid": "3878b810-576c-11e8-b4ef-e9105707324f", "content-length": "2763", "connection": "keep-alive" }, "RetryAttempts": 0 } } |
最後までお読みいただきましてありがとうございました!
「AWS認定資格試験テキスト&問題集 AWS認定ソリューションアーキテクト - プロフェッショナル 改訂第2版」という本を書きました。
「AWS認定資格試験テキスト AWS認定クラウドプラクティショナー 改訂第3版」という本を書きました。
「ポケットスタディ AWS認定 デベロッパーアソシエイト [DVA-C02対応] 」という本を書きました。
「要点整理から攻略するAWS認定ソリューションアーキテクト-アソシエイト」という本を書きました。
「AWSではじめるLinux入門ガイド」という本を書きました。
開発ベンダー5年、ユーザ企業システム部門通算9年、ITインストラクター5年目でプロトタイプビルダーもやりだしたSoftware Engineerです。
質問はコメントかSNSなどからお気軽にどうぞ。
出来る限りなるべく答えます。
このブログの内容/発言の一切は個人の見解であり、所属する組織とは関係ありません。
このブログは経験したことなどの共有を目的としており、手順や結果などを保証するものではありません。
ご参考にされる際は、読者様自身のご判断にてご対応をお願いいたします。
また、勉強会やイベントのレポートは自分が気になったことをメモしたり、聞いて思ったことを書いていますので、登壇者の意見や発表内容ではありません。
ad
ad
関連記事
-
AWS Lambda(Python)でDynamoDB テーブルを日次で削除/作成(オートスケーリング付き)
この記事はAWS #2 Advent Calendar 2018に参加した記事で …
-
Amazon Glacierのプロビジョニングされた迅速取り出し容量をなぜか購入しました
過去1年ぐらいのAWSコストをCost Explorerで見てまして、10/10 …
-
DS18B20センサー+Raspberry Piで取得した温度をAmazon Kinesis FirehoseからS3へ格納してAthenaでクエリーしたのをQuickSightで可視化する
JAWS DAYS 2017でやりますハンズオンの「[IoTハンズオン] Ras …
-
S3バケットのリクエスタ支払い
S3バケットのリクエスタ支払いを試しました。 バケットの設定 検証用のS3バケッ …
-
RDS + VPC + Lambda + API Gateway + CloudFront + WAF + ACMでAPIを構築する
RDSのMySQLの情報を与えられたリクエストをキーにしてjsonで返すAPIを …
-
Lambda関数で自分自身の環境変数を更新する
Twitterでツイート検索するAPIを試してみるでツイートの取得を重複させない …
-
[JapanTaxi] Athena 指向アナリティクス 〜真面目に手を抜き価値を得よ〜(AWS Summit Tokyo 2017)を聞いてきました
Athenaのユースケースとして聞きにいきましたが、最近触ってるRe:dashも …
-
S3 過去のオブジェクトバージョンをコピーしてロールバックしました
バージョニングを有効にしているS3バケットで、オブジェクトを以前のバージョンに戻 …
-
Amazon Kinesis Data StreamsにTwitter検索データを送信する
Kinesis Data Streamsの作成 ストリーム名とシャード数を決定す …
-
ParquetフォーマットのデータにS3 Select SQLを実行する
RDSスナップショットのS3エクスポート結果確認で出力したデータが、S3にPar …