Pepperハンズオン ～基本編B 音声認識～ Google Speech APIを使ってPepperにあなたの名前を知ってもらう [Tech-Circle#7]

本記事は [Tech-Circle#7 Pepper ハンズオン](http://techcircle.connpass.com/event/16275/) のハンズオン ～基本編B～ の内容です。

---
**Google Speech APIを使ってPepperにあなたの名前を知ってもらう**（所要時間目安: 15分）

* [① Google Speech APIをターミナルから実行してみる (要Pythonインストール)](http://qiita.com/shiraco/private/460b9a6ce7c9426d6be3#-google-speech-api%E3%82%92%E3%82%BF%E3%83%BC%E3%83%9F%E3%83%8A%E3%83%AB%E3%81%8B%E3%82%89%E5%AE%9F%E8%A1%8C%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B-%E8%A6%81python%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)
* [② Google Speech APIを使ってPepperにあなたの名前を確実に覚えてもらう](http://qiita.com/shiraco/private/460b9a6ce7c9426d6be3#-google-speech-api%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6pepper%E3%81%AB%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AE%E5%90%8D%E5%89%8D%E3%82%92%E7%A2%BA%E5%AE%9F%E3%81%AB%E8%A6%9A%E3%81%88%E3%81%A6%E3%82%82%E3%82%89%E3%81%86)
* [③ (おまけ) よしもとロボット研究所モーションボックスライブラリでPepperに動きを付けてみよう](http://qiita.com/shiraco/private/460b9a6ce7c9426d6be3#-%E3%81%8A%E3%81%BE%E3%81%91-%E3%82%88%E3%81%97%E3%82%82%E3%81%A8%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E7%A0%94%E7%A9%B6%E6%89%80%E3%83%A2%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%A7pepper%E3%81%AB%E5%8B%95%E3%81%8D%E3%82%92%E4%BB%98%E3%81%91%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86)

## はじめに

ハンズオンBで利用するプロジェクトは[shiraco/techcircle_pepper_handson_b](https://github.com/shiraco/techcircle_pepper_handson_b)にあります。作業ディレクトリに一括**git clone**でダウンロードしておきます。

```bash
$ cd ~/workspace/techcircle
$ git clone https://github.com/shiraco/techcircle_pepper_handson_b.git
$ cd techcircle_pepper_handson_b
```

ディレクトリ構成は以下のようになっています。

```bash
$ tree -L 1
.
├── google_stt             # ①で利用
└── pepper_google_stt      # ②で利用
```

以降では上記のプロジェクトを利用します。

## ① Google Speech APIをターミナルから実行してみる (要Pythonインストール)

まず、ターミナルからpythonスクリプトで実行して動作確認してみます。基本的には、動作確認がとれたpythonスクリプトをPepperのボックスとして組み込めばPepperアプリとして実装もできるはずです。

### プロジェクトの確認 (google_stt)

スクリプトは先ほどダウンロードした**google_stt**を使用します。

```bash
$ cd ~/workspace/techcircle/techcircle_pepper_handson_b/google_stt
```

### 外部ライブラリのインポート (requests)

このプロジェクトはAPIにアクセスするにあたって、**requests**というライブラリを使っています。`pip`が実行できる環境であれば以下のコマンドでインストールできます。

```bash
$ pip install -r requirements.txt
```

### API_KEYの設定

エディタを開いて**apikey**の値をあなたのGoogleのAPI_KEYの値で上書きしましょう。API_KEYの確認は https://console.developers.google.com から行えます。

```py:stt.py
apikey = os.environ.get("GOOGLE_API_KEY")
```

となっている所を以下のように直接書き換えてしまいましょう。

```py:stt.py
apikey = "YOUT_API_KEY_HERE"
```

### スクリプトの実行と動作確認

pythonのスクリプトを実行することでクラウドの音声認識を呼び出すことができます。

```bash
$ python stt.py test.wav
白石です
```

認識された結果、もっともらしい結果が得られます。

ちなみに`test.wav`にはあらかじめ以下の（参考)の手順で音声で私の名前「シライシです。」という音声を録音していました。
実際Googleの音声認識結果は確信度付きで複数件戻ってきます。その中で一番確信度の高いものを取り出しています。

### (参考) マイクの音声をwavファイルに録音[mac]

macの場合、Homebrewを使ってsoxをインストールすれば、音声ファイル(wav)ファイルを作成することができます。自分の名前を録音してみましょう。

```
$ brew install sox
$ rec --encoding signed-integer --bits 16 --channels 1 --rate 16000 test.wav
```

`test.wav`というファイルを開いてみると録音した音声が聞けるはず。

## ② Google Speech APIを使ってPepperにあなたの名前を確実に覚えてもらう

### アプリケーションの作成

それでは上記で試した内容をPepperアプリとして実装してみます。

本節では、最終的にChoregrapheで以下のようなアプリを作ります。順番に説明します。
![2-2-1.png](https://qiita-image-store.s3.amazonaws.com/0/5707/da49bbfe-edc5-3a53-67c8-fae6c0d86fb4.png)

### プロジェクトのオープン (pepper_google_stt)

スクリプトは先ほどダウンロードした**pepper_google_stt**を使用します。

```bash
$ cd ~/workspace/techcircle/techcircle_pepper_handson_b/pepper_google_stt
```

このプロジェクトは、新規のプロジェクトに対して利用するライブラリ(requests)をあらかじめインポートしたものになります。以下の通り、`lib`に`requests`がインポートされているのが確認できます。
**requests**については後で説明します。

```bash
$ tree . -L 3
.
└── pepper_google_stt
    ├── behavior.xar
    ├── lib
    │   └── requests
    ├── manifest.xml
    └── pepper_google_stt.pml
```

プロジェクトを開くと以下のような状態になっています。

![Screen Shot 2015-07-22 at 09.28.27.png](https://qiita-image-store.s3.amazonaws.com/0/5707/08da6960-66d6-e63b-0c9c-a3830b9b2da9.png)

この状態から、以降のステップでボックスをつないでPepperアプリを作っていきます。

#### **Set Language**

最初に**Set Language**を配置し、**Language**を「Japanese」にします。

![2-2-1.png](https://qiita-image-store.s3.amazonaws.com/0/5707/9cd3fbfa-9d81-2ec5-0a2d-ab706b0c0a1b.png)

#### (ヒント) ボックスはボックスライブラリビューの一番右の検索タブから探しましょう

![Screen_Shot_2015-07-22_at_00_28_59.png](https://qiita-image-store.s3.amazonaws.com/0/5707/77c9fcb2-6a64-eed7-f55b-f758deb2989e.png)



#### **Text Edit** + **Say Text**

次に**Text Edit** + **Say Text**を配置します。**Text Edit**の入力は「あなたのお名前は？」にします。

![2-2-2.png](https://qiita-image-store.s3.amazonaws.com/0/5707/dbfe8825-d5c0-57f0-186d-6ab4619ecd6c.png)

#### **Record Sound for Google STT**

次は音声認識するためのボックスを配置します。このボックスは今回のハンズオンではこちらで用意したものを使います。以下でその使い方を説明します。

以下にアクセスして、**techcircle_box**ボックスライブラリをダウンロードします。
https://github.com/shiraco/techcircle_box

**techcircle_box**ボックスライブラリは次のハンズオンCでも利用するため、親ディレクトリにダウンロードしておきます。

```bash
$ cd ~/workspace/techcircle
$ git clone https://github.com/shiraco/techcircle_box.git
```

**ボックスライブラリを開く**から、ダウンロードしておいた**techcircle_box**ボックスライブラリ(`techcircle_box/techcircle.cbl`)を開きます。

![2-2-3.png](https://qiita-image-store.s3.amazonaws.com/0/5707/532e26c5-a62d-6d7d-6fd5-188d9b82506b.png)
![2-2-4.png](https://qiita-image-store.s3.amazonaws.com/0/5707/f2085433-8ca7-2b8c-4790-5ae444bf76b8.png)

**techcircle_box**ボックスライブラリにあるボックスを配置します。

![2-2-2-1.png](https://qiita-image-store.s3.amazonaws.com/0/5707/eedabe7f-a51f-46e1-19ad-e89a700b8079.png)

まずは**techcircle_box**ボックスライブラリから**Record Sound for Google STT**を配置します。
このボックスは組み込みの**Record Sound**を若干Google Speech APIで扱い易いようカスタマイズしたものになります。

![2-2-3.png](https://qiita-image-store.s3.amazonaws.com/0/5707/b87b52b1-7269-a723-0991-767c5e84d98f.png)

#### **HTTP Google STT**

**techcircle_box**ボックスライブラリから、*HTTP Google STT*を配置し、変数の**GOOGLE_API_KEY**の値をあなたのAPI_KEYの値で上書きしましょう。

![2-2-4.png](https://qiita-image-store.s3.amazonaws.com/0/5707/17c26159-7390-ff1d-87d7-f8aae59b837a.png)

**HTTP Google STT** の中を少し見てみます。基本的には、①の `stt.py` の内容をボックスの中の**onInput_onStart()**に埋め込んだ形になります。

```py:HTTP_Google_STT
    def onInput_onStart(self, p):
        self.logger.info(p)
        filepath = p

        import os
        import json
        import requests
        import urllib

        try:
            timeout = int(self.getParameter("Timeout"))

            q = {"output": "json", "lang": "ja-JP", "key": self.getParameter("GOOGLE_API_KEY")}

            url = "http://www.google.com/speech-api/v2/recognize?%s" % (urllib.urlencode(q))

            self.logger.info(url)

            headers = {"Content-Type": "audio/l16; rate=16000"}
            data = open(filepath, "rb").read()

            response = requests.post(
                url,
                headers=headers,
                data=data,
                timeout=timeout
            )

            jsonunits = response.text.split(os.linesep)
            res = ""

            for unit in jsonunits:
                if not unit:
                    continue
                obj = json.loads(unit)
                alternatives = obj["result"]

                if len(alternatives) > 0:
                    breakflag = False
                    for obj in alternatives:
                        results = obj["alternative"]
                        for result in results:
                            res = result["transcript"]
                            breakflag = True
                            break

                        if breakflag:
                            break

            text = res.encode("UTF-8")
            self.logger.info("result: %s" % text)

            self.onStopped(text)

        except requests.exceptions.RequestException, message:
            self.logger.warn("Failed to open: message=%s" % (message))
            self.onFailed(message)
```

**HTTP Google STT**は外部ライブラリの**requests**に依存しています。
今回は、ベースとなるプロジェクトにあらかじめ必要なライブラリがインポートされているのでそのまま使います。

#### **Get Name** + **Say Text**

**Python**ボックスを配置して、ボックスの名前は**Get Name**にします。

![2-2-5.png](https://qiita-image-store.s3.amazonaws.com/0/5707/8e353bc0-c153-8373-d9fd-6a377afe78ef.png)

このボックスは文字列を受け取って、文字列を出力します。

私の例では、「白石です」→「こんにちは、白石さん。」の変換をしています。

**Edit input**と**Edit output**で入力と出力の型をそれぞれ「文字列」にしましょう。
以下のイメージは入力だけですが、出力も同様です。
![2-2-5-1.png](https://qiita-image-store.s3.amazonaws.com/0/5707/2ed31ba6-6cdc-ac8b-647d-327a2469de47.png)
![2-2-5-3.png](https://qiita-image-store.s3.amazonaws.com/0/5707/c29e6899-5ff1-abaa-fb7f-34ac4e3584d5.png)


**Python**ボックスの中身は以下のとおり、 **onInput_onStart()** メソッドで話者の言葉から名前を抽出して、返答文を組み立てています。（実際には、名前を抽出する処理は、かなり複雑な処理ですが、ここでは簡単のため、正規表現で置換しています。）
なお、ここで、**ALMemory**を使って`pepper_google_stt_username`という変数に名前をセット(記憶)しています。
万が一、名前を認識できない場合(聞き取れなかった)は、今日の天気について言及してごまかす仕様にしています。

```py:Get_Name_Box
    def onInput_onStart(self, p):
        #self.onStopped(p) #activate the output of the box
        pass
```

↑上記を、↓下記のように置き換えます。

```py:Get_Name_Box
    def onInput_onStart(self, p):
        import re
        name = re.sub(r'です', '', p)

        self.logger.info(name)

        memory = ALProxy("ALMemory")
        memory.insertData("pepper_google_stt_username", name)

        if name is None or name == "":
            text = "今日はいい天気ですね"
        else:
            text = "こんにちは" + name + "さん"

        self.onStopped(text)
```

最後に**Say Text**ボックスを配置して完成です。

![2-2-6.png](https://qiita-image-store.s3.amazonaws.com/0/5707/e943dbc8-b8e0-129e-1972-31cb0a3693f9.png)


### アプリケーションの実行と動作確認

以上で完成です。実行してみましょう。あなたの名前をPepperが尋ねるので答えてあげましょう。

メモリウォッチャービューから、メモリキー`pepper_google_stt_username`を追加しておくと、Pepperが名前を覚えてくれるのを確認できます。
![3-3-4-1.png](https://qiita-image-store.s3.amazonaws.com/0/5707/e0b2c7ee-d3f7-f189-fb6c-2c924dac1814.png)


どうでしょうか。正しくあなたの名前を知ってもらえたのではないでしょうか。
せっかく名前を知ってもらえたので、次のステップではあなたのことをもっと知ってもらって、おぼえてもらいましょう。

### 解答例

[shiraco/pepper_google_stt](https://github.com/shiraco/pepper_google_stt)

## ③ (おまけ) よしもとロボット研究所モーションボックスライブラリでPepperに動きを付けてみよう

まだ、Pepperに動きが無くて面白みに掛けますね。時間に余裕がある方は、以下のボックスライブラリでPepperに動きを付けてみましょう。

特に、API問い合わせは時間を要する処理です。この間にモーションを入れることで、体感時間を短くすることができるかもしれません。

**techcircle_box**同様以下からボックスライブラリをダウンロードして、プロジェクトに読み込んだ上で、適当なタイミングでモーションボックスをつないでみましょう。

[モーション作成を効率化するボックスライブラリを公開 | Pepper アトリエ秋葉原 with SoftBank](http://pepper-atelier-akihabara.jp/archives/259)

---

以上で、ハンズオン ～基本編B～ は終了です。

次のステップは以下の内容になります。
[～基本編C画像認識～ ReKognition APIを使ってPepperにあなたの見た目の印象を聞いてみる](http://qiita.com/shiraco/private/9836048e30612bb96582)

---
本ハンズオンのイベントページ
[Tech-Circle#7 Pepper ハンズオン](http://techcircle.connpass.com/event/16275/)