どうも。まっきーです!ラズパイで、Siri風のスマートスピーカーを作成してみました。
とりあえずどんなものか説明するのは大変なので、完成したものをご覧ください。
今まで学んだことを復習するために「Siri風ラズパイ」を作成してみました!
— まっきー@駆け出しエンジニア (@makky_study) November 8, 2020
[使用した機能]
・顔認識
・音声出力/認識
・温湿度測定
・LED点灯
人生初の動画編集にも挑戦してみましたので、よかったら見みてください☺️作り方についてはブログの方に書きました~ pic.twitter.com/ZcW0x28cwt
こんな感じで、言った言葉に反応して何かしらのアクションをするという仕組みです。実際、Siriの足元にも及ばないですが、何かを作った!という達成感は得られるのではないでしょうか。
この記事を見るだけで実装できるように説明していきます!詳しく知りたい方は、各機能の参考リンクも貼っておくのでそちらを参考にしてください!
目次
目的
作成する前に立てた目的は、
「話しかけたことに反応して写真撮影などをしてくれる機能」
の実装です。
今まで学習してきた様々な機能を使用したいと考えました。
- Juliusを用いた音声認識
- OpenJtalkによる音声発信
- OpenCvによる顔認識
- LED点灯・消灯
- DHT11 を用いた温湿度測定
音声認識を主軸とし、これらの機能全てを盛り込みました(笑)
使用したもの
今回使用したものを以下に記載します。基本的にはAmazonで手に入ります。スピーカーは100均で買いました。
- RaspberryPi 3B+
- ラズパイカメラモジュール
- USBマイク
- USBスピーカー(100均で300円で買えます)
- LED1つ
- DHT11 温湿度センサー
- ジャンパー線5本(オス・メス)
- 抵抗(1kΩ)
全体フロー図
全体のフロー図です。

特定の言葉に反応して各機能を開始する仕組みにしました。では実際に作成していきます!
スマートスピーカー作成の手順
ディレクトリ構想
ディレクトリの階層は以下のようになっています。
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 |
$ tree SiriPJT │ ├── FacialRecognition │ ├── datasets │ │ ├── User.1.1.jpg │ │ ├── User.1.2.jpg │ │ ├── User.1.3.jpg │ │ : │ │ (他の人を付け加えるならここに追加される) │ ├── face_cap.py#写真を撮る │ ├── train.py#訓練する │ ├── face_detect.py#顔を認識する │ ├── haarcascade_frontalface_default.xml#顔を取るための特徴量(OpenCvからダウンロード) │ └── trainer │ └── trainer.yml#訓練後のデータ ├── julius#音声認識エンジン(過去記事参照) │ ├── julius-4.5 │ └── julius-kit │ └── dictation-kit-4.5 ├── dht11#温湿度測定プログラム │ └── __init__.py ├── main.py#メインプログラム ├── led.py#LED点灯のクラス ├── temp_humi.py#温湿度測定 ├── date.py#日付測定 ├── camera.py#カメラ撮影 ├── julius.py#ジュリアスを起動 ├── voice.py#音声を出力 └── open_jtalk.wav#音声ファイル作成時に作られます |
少し複雑ですが簡単に言うと、「SiriPJT」というディレクトリの中に
- FacialRecognition 顔認識のためのディレクトリ
- Julius Juliusを使用するためのディレクトリ
- dht11 温湿度のためのディレクトリ
- その他機能ごとのスクリプトファイル
が入っているということです。それぞれのソースコードは後述します。
回路図
LEDとDHT11で簡単な回路を作成します。

必要なモジュール・ライブラリ等のインストール
ディレクトリ移動があるのはJuliusのみです。その他はpi直下で行ってください。
音声発信・音声認識はマイクやスピーカーの設定も必要ですので、以下の2つを参照することをおすすめします。
Julius
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
mkdir julius cd julius #Juliusバージョン4.5をダウンロード wget https://github.com/julius-speech/julius/archive/4.5.tar.gz tar xvzf 4.5.tar.gz cd julius-4.5 #Makeファイルを作成 ./configure --with-mictype=alsa #コンパイル make #インストール sudo make install #Juliusディレクトリに戻る cd .. #Julius-kitディレクトリを作成 mkdir julius-kit #Julius-kitに移動 cd julius-kit #ディクテーションキットダウンロード・解凍 wget https://osdn.net/dl/julius/dictation-kit-4.5.zip unzip dictation-kit-4.5.zip |
OpenJTalk
1 2 3 4 5 |
sudo apt-get update #アップデート sudo apt-get install open-jtalk #インストール #推奨されているパッケージ #音声合成のエンジン、辞書、音声データ sudo apt-get install open-jtalk open-jtalk-mecab-naist-jdic hts-voice-nitech-jp-atr503-m001 |
OpenCV
1 2 3 4 5 6 7 8 9 10 |
sudo apt update sudo apt upgrade #必要なライブラリをインストール sudo apt-get install libatlas-base-dev sudo apt-get intall libjasper-dev sudo apt-get intall libqtgui4 sudo apt-get intall python3-pyqt5 sudo apt install libqt4-test #バージョン指定でOpenCVをインストール sudo pip3 install opencv-python==4.1.0.25 |
カスケード分類器のインストールは図を使って説明していますので「ラズパイ OpenCVインストール方法」をご覧ください。
GPIO・DHT11
1 2 3 4 |
#GPIO制御のモジュールインストール sudo pip3 install RPi.GPIO #DHT11の元ソースコードをクローン(複製) git clone https://github.com/szazo/DHT11_Python.git |
ソースコード一覧
全て表示すると長くなるので、main.py以外のファイルは折りたたんであります。クリックしたら見ることができます。
julius.py
Juliusのモジュールモードを起動するための関数です。
詳しくは「音声認識を使ってラズパイと会話をする(Julius,OpenJtalk使用)」を参考にしてください。
voice.py
音声を出力する関数です。引数にt(テキスト)をとり、そのテキストの文字を読み上げます。
詳しくは「ラズパイで音声を出力する方法(OpenJTalkとAquesTalk)」を参考にしてください。
led.py
LEDを点灯・消灯させるためのクラスです。ただ光らせたり、消したりするだけなのでクラスにする必要は0ですが、自分の練習のためにクラスにしてみました。
LEDの点灯消灯については「ラズパイでLチカをやってみよう(Python)」を参考にしてください。
temp_humi.py
温度と湿度をリアルタイムで取得する関数です。
戻り値は温度と湿度の入ったテキストです。
温湿度センサーについて詳しく知りたい方は「ラズパイとDHT11で温湿度測定 with Python」を参考にしてください。
date.py
今日の日付と時間を返す関数です。
戻り値は月、日付、時間、分の書いてあるテキストです。
camera.py
カメラを撮影する関数です。撮影するまでに3,2,1という音声を発信するためにvoice.pyをインポートして使用しています。
撮影された画像はSiriPJTの下に「pi日付.jpg」という形で保存されます。
facedetect.py
知っている顔か、知らない顔かを判別して、その人の名前を返す関数です。
戻り値は、名前の入ったテキストと、信頼度を表す数字の2つです。(id:名前,conf:信頼度)
今回は私まっきーと千鳥のノブ、小池徹平をnamesリストに格納しています。
idと対応付けて名前を設定する必要があります。
顔を識別するためには
- 写真撮影(face_cap.py)
- 訓練データの作成(train.py)
の操作が必要です。少しだけ他のものと比べて難易度が上がりますので「ラズパイカメラとOpenCvを使って女優の顔認識してみた」を参照することをおすすめします。
main.py
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 |
#coding: utf-8 import socket import julius import date import temp_humi as temp import camera import voice from led import LedOnOff from FacialRecognition import face_detect as detect if __name__ == "__main__": julius.julius_on() led = LedOnOff(23)#LED点灯・消灯クラスのインスタンスを作成 GPIO番号を引数に取ります host = '127.0.0.1' # juliusサーバーのIPアドレス port = 10500 # juliusサーバーの待ち受けポート data_size = 1024 # 受信データバイト数 # socket通信でjuliusサーバーに接続(接続要求) with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.connect((host, port)) strtemp = ""#話した言葉を格納する変数 fin_flag = False #話終わりのフラグ while True: # juliusサーバからデータ受信 data = s.recv(data_size).decode('utf-8') for line in data.split('\n'): # 受信データから、<WORD>の後に書かれている言葉を抽出して変数に格納する。 # <WORD>の後に、話した言葉が記載されている。 index = line.find('WORD="') if index != -1:#認識した文字列があれば #strtempに話した言葉を格納 strtemp = strtemp + line[index+6:line.find('"',index+6)] # 受信データに</RECOGOUT>'があれば、話終わり ⇒ フラグをTrue if '</RECOGOUT>' in line: fin_flag = True if '<RECOGFAIL/> ' in line: print("聞き取れませんでした") fin_flag = False if fin_flag == True: if "つけて" in strtemp: led.ledon() elif "消して" in strtemp: led.ledoff() elif "温度" in strtemp: voice.jtalk(temp.dht(14))#戻り値のテキストデータを使って音声出力 elif "日付" in strtemp: voice.jtalk(date.rdate())#戻り値のテキストデータを使って音声出力 elif "写真" in strtemp: camera.shoot() elif "誰です" in strtemp: name,conf = detect.recog()##戻り値のテキストデータを使って音声出力 voice.jtalk(name) print(conf)#信頼度 else: voice.jtalk("もう一度行ってください") fin_flag = False strtemp = "" |
メイン関数の流れは以下の通りです
- 上記で作成した関数やクラスをインポートする
- 音声認識データを取得するため、Juliusのモジュールモードとの接続を行う
- 認識した音声に特定に文字が含まれているかを確認し、実行
- ループ
コードが複数あり、ごちゃごちゃしていますがifを使ってそれぞれ分岐させているだけです。
1 |
python3 main.py |
上記のコマンドを実行すると初めの動画のように動いてくれると思います。
動かない!という方はディレクトリが違ったりする可能性が高いです。カメラやUSBなどの物理的接続なども、エラーコードを見ながら確認していきましょう!
一番CPU占有率の高いと思われる「顔認識」は以下のような結果になりました。

結構使用していることがわかると思います。音声認識などは40%ほどの使用率でした。
反省点
それらしいものを作ることができたので、個人的には満足です!
改善点・問題点として
- コードがぐちゃぐちゃなので、クラスなどを用いてまとめる必要がある
- 顔認識の精度が低い(良くて40%)
- あまり実用的ではない(連続で話しかけたパターンのテストを忘れた)
などが考えられます。
もし、「ここを直すと良い」などのご意見がありましたらコメントで教えて頂けると嬉しいです。
関連サイト
これらの記事に記載されていることを参照していただければ、コードの理解が深まると思います。
【音声認識(Julius)・音声発信(OpenJTalk)】
- ラズパイで音声認識(Juliusインストールからソケット通信まで解説)
- 音声認識を使ってラズパイと会話をする(Julius,OpenJtalk使用)
- ラズパイで音声を出力する方法(OpenJTalkとAquesTalk)
【顔認識(OpenCV)】
- ラズパイ OpenCVインストール方法 (カスケード分類器のダウンロードもします)
- ラズパイカメラとOpenCvを使って女優の顔認識してみた
- 顔認証のソースコードを解説!(調べるのが面倒くさい人はこれを見ればわかる!)
【LED、温湿度】
最後までありがとうございました!
次は実用的な監視カメラの作成をしていきたいと思っています!