Pepperで撮影した写真をAmazon Rekognitionで分析してその結果をPepperがしゃべる ~(2)Pepper編~
2018/07/10
Pepperで撮影した写真をAmazon Rekognitionで分析してその結果をPepperがしゃべる ~(1)AWS編~の続きで、今回はPepper編です。
※ソフトバンクロボティクスのPepperを活用し、私が独自に実施しているものです。
(1) PepperからはAPI Gateway経由でLambdaを実行します。
(2) Pepperからアップロードされた画像はS3に格納されます。
(3) その画像は、Amazon Rekognitionによって画像解析されてその結果がAPI Gateway経由でレスポンスンとして戻ります。
(4) レスポンスをPepperが会話文に整形して話します。
今回はPepper側の開発(1)と(4)について記載します。
目次
Pepperの開発
PepperのSDkであるChoregraphを使いました。
ChoregrahにはボックスというPepperを動かすためのコンポーネントが多数あらかじめ用意されています。
そのボックスを選んでつなぐことでPepperを簡単に動かすことが出来ます。
それでは今回選んでつないだボックスが、それぞれ何をしているかを以下に書きます。
Set Language
まず最初にこのプログラムが実行されたときにPepperが扱う言語を設定します。
今回は日本語を扱いたいのでJapaneseにします。
OnReadyから次のボックスのSpeech Recoへつなぎます。
Speech Reco
Pepperに話しかけた言葉をトリガーとしたいので、Speech Recoのボックスを使います。
今回は「かおをみて」と言うと次の動作に遷移します。
WordListにはセミコロン ; 区切りで複数の言葉を登録することも出来ます。
wordRecognizedから次にボックスへ文字列を渡してつなぎます。
今回はこの文字列の再利用はしませんが、複数のWordListに対して聞き取った言葉の分岐を行うなどSwitchCaseと組み合わせて使用することが出来ます。
次はFace Trackerのボックスへつなぎます。
Face Tracker
話しかけたあと、顔を追いかけてほしいので、Face Trackerを使います。
Face Trackerが実行されるとPepperが両手をふりあげて顔を追いかけてきます。
ModeをHeadにすると頭だけを動かしますが、今回はおおげさに動かしたかったのでMoveにしました。
Efectは右腕左腕のどちらかでも両腕でも選択することが出来ます。
これも派手にしたかったので両腕にしました。
顔が見つかったとPepperが判断すると、TargetReachedのイベントが発生します。
TargetReacheから次のボックスのTake Pictureにつなぎます。
Take Picture
Pepperが顔を見つけたらその顔の写真をとりたいので、Take Pictureボックスを利用します。
撮影した写真はPepperローカルに image.jpgというファイル名で保存されます。
これをタブレットに表示したいので、このあとOnStoppedイベントから次のShow Imageボックスへつなぎます。
このへんの設定はこちらの
Pepperで画像を撮影してタブレットに画像表示
を参考にさせていただきました。
ボックスはダブルクリックするとスクリプトエディタが起動してPythonコードを直接編集できます。
先ほどの参考サイトの記載どおりに、コードを編集します。
onLoadメソッドでALFrameManagerオブジェクトを生成します。
1 2 3 4 5 |
def onLoad(self): # ここから追加 self.framemanager = ALProxy("ALFrameManager") # ここまで追加 |
onInput_onStartメソッドで先ほど生成したALFrameManagerオブジェクトのgetBehaviorPathメソッドを使って、写真の保存先のディレクトリを再定義します。
このディレクトリがShow Imageボックスで表示する画像のディレクトリパスです。
平行してAmazon Rekognitionで解析するためのAPIへ画像を渡すためにPythonスクリプトのボックスへもつないでいます。
PythonスクリプトがS3へアップロードする画像の参照先も同じディレクトリです。
1 2 3 4 5 6 7 |
def onInput_onStart(self): # ここから追加 import os self.recordFolder = os.path.join( self.framemanager.getBehaviorPath(self.behaviorId), "../html") # ここまで追加 |
Show Image
Pepperが解析した結果を話している間、撮影した写真をタブレットに表示するためにShow Imageボックスを使います。
表示する写真はimage.jpgです。
Take Pictureでは拡張子が指定できないのか省略形式で入力、
Show Imageでは拡張子までを指定、とややくせがあるので注意です。
Show Imageで表示する写真はhtmlディレクトリが必要なのでプロジェクト直下に作成しておく必要があります。
このままのShow Imageですと、ファイルパスが同じ場合に、前の画像がキャッシュされてしまうので、それを回避するために、先述のサイトを参考にさせていただき、下記コードを追加しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
def onInput_onStart(self): # ここから追加 import time # ここまで追加 tabletService = self._getTabletService() if tabletService: try: url = self.getParameter("ImageUrl") if url == '': self.logger.error("URL of the image is empty") if not url.startswith('http'): url = self._getAbsoluteUrl(url) # ここから追加 url += "?" + str(time.time()) # ここまで追加 tabletService.showImage(url) |
Python Script
Show Imageで撮影した写真の表示と平行して、本処理である画像をS3にアップロードしてRekognitionで解析した結果を受け取ります。
呼び出すコードはPepperで撮影した写真をAmazon Rekognitionで分析してその結果をPepperがしゃべる ~(1)AWS編~にも簡単に書いていますが下記のようにしました。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
def onInput_onStart(self): import os import requests recordFolder = os.path.join( self.framemanager.getBehaviorPath(self.behaviorId), "../html") file_path = recordFolder + '//image.jpg' data = open(file_path, 'rb').read() response = requests.post( url=api_url, data=data, headers={'Content-Type': 'image/jpg'} ) |
requestsモジュールはPepperに標準でインストールされているので、インストール不要です。
Python Scriptでは結果として次のボックスの渡したい文字列を、self.text()メソッドにセットします。
1 2 |
self.text(return_text) |
self.text()メソッドにセットした文字列は出力のtextから受け取れるので、それを次のボックスへ渡します。
Say Text
Python ScriptでAPIを実行した結果をtextで受け取って、Say Textボックスを使ってPepperに話してもらいます。
Say Textは直前のボックスから渡されたテキストをそのまま話します。
話すスピードや抑揚の調整ができます。
そして、OnStoppedで話し終わったあとに、タブレットをデフォルトの表示に戻すために、別で用意したShow Imageのボックスへつなぎます。
Show Image(デフォルト画像表示用)
プログラム開始直後に表示しておいて、Take Pictureで新たな写真が撮影されるまで表示されています。
Say Textで顔分析結果を話終わった後もこのShow Imageに戻るようにフローをつないでいます。
デフォルトイメージはあらかじめプロジェクトに追加しておいたロゴ画像が表示されるようにしました。
作ってみて
Python Scriptではコードを書いてAPIを実行して結果を日本語文字列になるように調整していますが、
それ以外のPepperそのものの動作については、ほとんどGUIだけで実装することが出来ました。
各ボックスも必要に応じてPythonコードを修正出来るので、どうしても変更したい場合にこまわりが効きます。
最後までお読みいただきましてありがとうございました!
「AWS認定資格試験テキスト&問題集 AWS認定ソリューションアーキテクト - プロフェッショナル 改訂第2版」という本を書きました。
「AWS認定資格試験テキスト AWS認定クラウドプラクティショナー 改訂第3版」という本を書きました。
「ポケットスタディ AWS認定 デベロッパーアソシエイト [DVA-C02対応] 」という本を書きました。
「要点整理から攻略するAWS認定ソリューションアーキテクト-アソシエイト」という本を書きました。
「AWSではじめるLinux入門ガイド」という本を書きました。
開発ベンダー5年、ユーザ企業システム部門通算9年、ITインストラクター5年目でプロトタイプビルダーもやりだしたSoftware Engineerです。
質問はコメントかSNSなどからお気軽にどうぞ。
出来る限りなるべく答えます。
このブログの内容/発言の一切は個人の見解であり、所属する組織とは関係ありません。
このブログは経験したことなどの共有を目的としており、手順や結果などを保証するものではありません。
ご参考にされる際は、読者様自身のご判断にてご対応をお願いいたします。
また、勉強会やイベントのレポートは自分が気になったことをメモしたり、聞いて思ったことを書いていますので、登壇者の意見や発表内容ではありません。
ad
ad
関連記事
-
SQLAlchemyでjoinする
PythonのSQLAlchemyでMySQLのテーブルをjoinするときの覚書 …
-
Python SQLAlchemy MySQLでcase文を使う
PythohのORMライブラリSQLAlchemyでMySQLのテーブルSele …
-
Rocket.ChatのAPIでユーザーを一括登録する
Rocket.Chatの管理画面にインポートのメニューはあって、どうやらuser …
-
PyCharmでテキストを折り返す
超小ネタです。 コーディングしているときは1行でそんなに長いコードを書かないので …
-
SQLAlchemyのModelクラスをMySQLから自動生成する
SQLAlchemyのMySQLモデルを書くのが面倒で、きっと何かツールがあるの …
-
Python openpyxlで結合セルを含むExcelファイルを開くと罫線が消える
PythonのExcelを読み書きするためのライブラリ、openpyxlで結合セ …
-
Python SQLAlchemy MySQLでテーブルを指定せずにFunctionを使う
難しく考えて悩んでいましたが、queryに書いてやればいいだけでした。 sess …
-
SendGrid(sendgrid_python)でメール送信してイベントの情報からメール本文をたどれるようにしておく
動的に生成するメールで実際にどんな本文が送信されたかを記録しておきたいときもある …
-
「MonotaRo Tech #3 テスト自動化」に行ってきました
モノタロウさんの「MonotaRo Tech #3 テスト自動化」に行ってきまし …
-
個人のGoogleカレンダーの予定をPythonで取得する
Google Calendar Twilio ReminderのGoogleカレ …