【Amazon Polly編】有名人認識アプリの開発に挑戦!
今回の「AWS のサービスを活用した有名人認識アプリの開発」シリーズでは、
- 画像認識
- 音声合成
- 機械翻訳
と、3つの技術を学ぶことができます。
ちなみに前回は、有名人認識アプリの開発を通して、画像認識機能を実装していきましたね!
今回は、前回開発した有名人画像認識アプリに、音声合成機能を加えていきたいと思います!
前回の記事
2021.08.24【後編】有名人認識アプリの開発に挑戦! さて、有名人画像認識アプリを開発するシリーズの「Amazon Rekognition 後編...
こちらの記事もオススメ!
2020.07.17「やってみた!」を集めました!
(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました! ※作成日が新しい順に並べ...
2020.07.28知識編
人工知能・機械学習でよく使われるワード徹底まとめ! 機械学習の元祖「パーセプトロン」とは?【人工知能】 ニューラルネッ...
音声合成って何?
先ほど、音声合成に触れていきたい、と述べました。
ただ、「音声合成ってどこで使われているのか?」といった疑問があるかもしれません。
まず、身近で言えば、
- Google Home(Nest)
- Alexa
- Siri
などが、音声合成で作られたものです。
他には、「カーナビ」や「カスタマーサービス」などの電話応対なども、音声合成の技術が使われています。
Amazon Pollyとは?
Amazon Polly とは、用意したデジタル化テキストを、簡単に音声合成してくれるサービスです。
公式サイトでは、「深層学習を使用して文章をリアルな音声に変換」と説明されていますね!
ザックリと特徴をまとめると、以下のような感じになります。
- テキスト読み上げができるアプリケーションを作成できる
- 高度なディープラーニング技術を使用したテキスト読み上げ (TTS) サービス
- 自然に聞こえるように人間の音声を合成できる
- 多言語対応である
- ニュースキャスター発話スタイルと通話発話スタイルを選択可能
- カスタム音声を使用可能
Amazon Pollyを使ってみよう!
Amazon Pollyで作成できる音声データ例
では、実際に Amazon Polly に触れていきましょう!
まず、Amazon Polly は、以下のような音声データを作成することができます。
▶ 音声例(mp3形式)
(※環境によっては、ファイル再生できない可能性もあります。)
ただのテキストを突っ込んであげるだけで、かなり自然な発音で、再生してくれます。
Amazon Pollyの基本的な使い方
では、Amazon Polly のページに移動してみましょう。
【Amazon Polly:公式サイト】
https://aws.amazon.com/jp/polly/
まず、Amazon Polly の使用を開始するボタンを押下してください。
そうすると、テキストの読み上げ機能のページが開くと思います。
注意点としては、Amazon Polly の管理コンソールで、基本的にはアジアパシフィック(東京)を選択することです。
では、実際にプレーンテキストに、何か入力してみてください。
ちなみに音声は、言語によって異なりますが、「女性」と「男性」の音声を選択できます。
また、「音声を聴く」ボタンを押下すると、Amazon Polly の音声を確認することが可能です。
「ダウンロード MP3」ボタンを押下すれば、音声合成した MP3 を、ローカルに保存することもOKです。
このように、デジタル化テキストを、音声合成することができました!
PythonでAmazon Pollyに触れる
Python で、AWS のサービスを扱うには、先ほどインストールした Boto3 を使う必要があります。
ライブラリのインポート
ではまず、ライブラリをインポートするコードを書いていきましょう!
| # ライブラリをインポートする import boto3 # Polly をつかうためのクライアントを作成 polly_client = boto3.client('polly') |
通常 boto3 を扱うためには、Session を立ち上げて、Polly のクライアントを作成するといった処理が必要です。
ですが、先ほど aws config で設定した情報を認証してくれるので、省略ができます。
そのおかげで、コード上では個人情報が書かれないので、セキュリティ的にも安全なものになります。
もし、複数のリージョンが必要となる場合、
| polly_client = boto3.Session(region_name='us-west-2').client('polly') |
上のように書くと、複数のリージョンで使用可能です。
音声の合成
では次に、音声ファイルを作成するうえで必要なコードを書いていきましょう!
| # SynthesizeSpeech API を利用 response = polly_client.synthesize_speech( VoiceId='Takumi', OutputFormat='mp3', Text = 'こんにちは。レシピを見ていただきありがとうございます!') # 返却したレスポンスから音声ファイルを作成 with open('speech.mp3', 'wb') as f: f.write(response['AudioStream'].read()) |
Amazon Polly の コンソール上で利用したように、音声ファイルを作成するためには、Amazon Polly の API である「SynthesizeSpeech」というものを利用します。
【SynthesizeSpeech:公式ドキュメント】
https://docs.aws.amazon.com/polly/latest/dg/API_SynthesizeSpeech.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # Request Syntax response = client.synthesize_speech( Engine='standard'|'neural', LanguageCode='arb'|'cmn-CN'|'cy-GB'|'da-DK'|'de-DE'|'en-AU'|'en-GB'|'en-GB-WLS'|'en-IN'|'en-US'|'es-ES'|'es-MX'|'es-US'|'fr-CA'|'fr-FR'|'is-IS'|'it-IT'|'ja-JP'|'hi-IN'|'ko-KR'|'nb-NO'|'nl-NL'|'pl-PL'|'pt-BR'|'pt-PT'|'ro-RO'|'ru-RU'|'sv-SE'|'tr-TR', LexiconNames=[ 'string', ], OutputFormat='json'|'mp3'|'ogg_vorbis'|'pcm', SampleRate='string', SpeechMarkTypes=[ 'sentence'|'ssml'|'viseme'|'word', ], Text='string', TextType='ssml'|'text', VoiceId='Aditi'|'Amy'|'Astrid'|'Bianca'|'Brian'|'Camila'|'Carla'|'Carmen'|'Celine'|'Chantal'|'Conchita'|'Cristiano'|'Dora'|'Emma'|'Enrique'|'Ewa'|'Filiz'|'Geraint'|'Giorgio'|'Gwyneth'|'Hans'|'Ines'|'Ivy'|'Jacek'|'Jan'|'Joanna'|'Joey'|'Justin'|'Karl'|'Kendra'|'Kevin'|'Kimberly'|'Lea'|'Liv'|'Lotte'|'Lucia'|'Lupe'|'Mads'|'Maja'|'Marlene'|'Mathieu'|'Matthew'|'Maxim'|'Mia'|'Miguel'|'Mizuki'|'Naja'|'Nicole'|'Penelope'|'Raveena'|'Ricardo'|'Ruben'|'Russell'|'Salli'|'Seoyeon'|'Takumi'|'Tatyana'|'Vicki'|'Vitoria'|'Zeina'|'Zhiyu' ) # Response Syntax { 'AudioStream' : StreamingBody ()、 'ContentType' : 'string' 、 'RequestCharacters' : 123 } |
Voice ID は、それぞれの言語によって、しゃべってくれる ID が異なります。
そのため、しゃべらせたい言語によって、変える必要がある部分です。
作成したファイルを確認すると、テキストから音声合成できていることが確認できると思います。
有名人認識アプリの開発!
前回までで、画像認識機能を持った、有名人認識アプリを開発することができましたね!
音声合成の基本的な使い方を理解したところで、いよいよ有名人認識アプリに、実装していきたいと思います。
今回の流れとしては、以下を想定しています。
- 画像解析を行った結果をテキスト化
- 「1」のテキストを Amazon Polly に投げて音声合成
では早速、順に実装していきましょう!
画像解析結果をテキスト化
ではまず、解析結果をテキスト化してみます。
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 | # 有名人の result_text 作成 def make_celeb_names(ans_data): for celeb in ans_data.celeb: if celeb.confidence >= CONFIDENCE: # 一致信頼度が75%以上のものを認識結果として採用する ans_data.celeb_names += celeb.name +'、' return True # 検出した人の数 def detect_face(ans_data): for celeb in ans_data.celeb: if celeb.confidence >= CONFIDENCE: # 一致信頼度が75%以上のものを認識結果として採用する ans_data.celeb_cnt += 1 else: # 一致信頼度が75%未満はUnknown ans_data.unknown_cnt += 1 ans_data.unknown_cnt += len(ans_data.unknown) return True # 検出した物体の数 def detect_object(ans_data): for info in ans_data.object: if info.name not in ans_data.object_namelist: ans_data.object_names += info.name + '、' ans_data.object_namelist.append(info.name) return True # メイン処理 def main_proc(ans_data): # 解析結果をもとに有名人の氏名 and 数を検出 detect_face(ans_data) # 有名人の result_text 作成 make_celeb_names(ans_data) # 解析結果をもとに物体数を検出 detect_object(ans_data) : : return True |
まず、前回の検出時に取得したリストから、テキスト化しやすいように整形しなおします。
次に、その整形したものを使い、解析結果テキストを作成しましょう!
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 | class GuiApp(object): # 解析結果を音声合成する def thread_polly(self): result_text = make_result_text(self.ans_data) return True def image_analysis(self): #音声出力 self.thread_polly() return True # 解析結果テキストを作成 def make_result_text(ans_data): celeb_text = 'この写真に写っている人物は、' + ans_data.celeb_names[:-1] + ' です。' unknown_text = '名前のわからない人が' + str(ans_data.unknown_cnt) + '名いました。' obejct_text = 'この写真には、' + ans_data.object_names + ' が写っています。' not_celeb_text = '有名人を認識できませんでした。' final_text = '以上、検出結果でした。' else_text = 'またのご利用お待ちしております' result_text = '' # celeb検出 if ans_data.celeb_cnt > 0: result_text += celeb_text # celeb検出なし if ans_data.celeb_cnt <= 0: result_text += not_celeb_text # Unknown検出 if ans_data.unknown_cnt > 0: result_text += unknown_text # Object検出 if len(ans_data.object_namelist) > 0: result_text += obejct_text # Object検出なし and Unknown検出なし if len(ans_data.object_namelist) <= 0 and ans_data.unknown_cnt <= 0 and ans_data.celeb_cnt <= 0: result_text += else_text # 追加 else: result_text += final_text return result_text |
上のコードの以下の部分で、解析結果のテキストを作成します。
| celeb_text = 'この写真に写っている人物は、' + ans_data.celeb_names[:-1] + ' です。' unknown_text = '名前のわからない人が' + str(ans_data.unknown_cnt) + '名いました。' obejct_text = 'この写真には、' + ans_data.object_names + ' が写っています。' not_celeb_text = '有名人を認識できませんでした。' final_text = '以上、検出結果でした。' else_text = 'またのご利用お待ちしております' |
これから有名人の名前や、認識できなかった人の数、物体の名前を示すことができます。
テキストをAmazon Pollyに投げて音声合成
次は、このテキストを使って、音声を出力してみましょう!
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 | class GuiApp(object): # 解析結果を音声合成する def thread_polly(self): text_to_sound(result_text) return True # 音声データ作成 def text_to_sound(result_text, polly_voice): # The text string can be a maximum of 3000 bytes long. if len(result_text.encode()) > 3000: result_text = result_text[:3000] try: polly = boto3.client('polly') # Request speech synthesis response = polly.synthesize_speech( Text=result_text, OutputFormat='mp3', VoiceId='Takumi') except (BotoCoreError, ClientError) as error: # The service returned an error, exit gracefully print(error) print("Can't synthesize_speech the text") messagebox.showerror('Error', "BotoCoreError, ClientError: synthesize_speech the text") sys.exit(-1) # Access the audio stream from the response if 'AudioStream' in response: TMPDIR = tempfile.TemporaryDirectory() # make musicfile dt_now = datetime.datetime.now() music_path = TMPDIR.name + f'/output_{dt_now.microsecond}_{dt_now.second}_{dt_now.minute}.mp3' with open(music_path, "wb") as file: file.write(response['AudioStream'].read()) # playing music pygame.mixer.init() if not pygame.mixer.music.get_busy(): pygame.mixer.music.load(music_path) mp3_length = mp3(music_path).info.length pygame.mixer.music.play(1) time.sleep(mp3_length + 0.4) pygame.mixer.quit() TMPDIR.cleanup() else: # The response didn't contain audio data, exit gracefully print('Could not stream audio') messagebox.showerror('Error', "Could not stream audio") sys.exit(-1) return True |
上のコードにより、作成したテキストを音声合成を行い、再生することができます。
ここまでで、Amazon Polly を使って、音声合成を行うことができましたね!
今後は、このアプリに、機械翻訳の機能を追加していきたいと思います。
Amazon Translate編へつづく!
「有名人画像認識アプリ」を開発するシリーズを読んでいただき、大変ありがとうございます!
あまり馴染みのない 「AWS」はこんなこともできるんだよ、といったことを伝えたいために、このテーマを選択しています。
さて、次回からは、いよいよ機械翻訳の使い方に入っていきます。
どんどんと完成に近づいていきますね!
では、次回もお楽しみに!
Amazon Translate編はこちら!
2021.08.27【Amazon Translate編】有名人認識アプリの開発に挑戦! 前回に引きつづき、「有名人画像認識アプリを開発する」といった...
記事を書いた人
\ 3度のメシより技術が好き /
(株)ライトコードは、WEB・アプリ・ゲーム開発に強い「好きを仕事にするエンジニア集団」です。
システム開発依頼・お見積もりは
こちらまでお願いします。
また、WEB・スマホ系エンジニアを
積極採用中です!
※現在、多数のお問合せを頂いており、返信に、多少お時間を頂く場合がございます。
こちらの記事もオススメ!
2020.07.17「やってみた!」を集めました!
(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました! ※作成日が新しい順に並べ...
2020.07.28知識編
人工知能・機械学習でよく使われるワード徹底まとめ! 機械学習の元祖「パーセプトロン」とは?【人工知能】 ニューラルネッ...
書いた人はこんな人
- ライトコード社員ブログ
- 「好きなことを仕事にするエンジニア集団」の(株)ライトコードです!
ライトコードは、福岡本社、東京オフィスの2拠点で事業展開するIT企業です。
現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。
いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。
システム開発依頼・お見積もりは大歓迎!
また、WEBエンジニアとモバイルエンジニアも積極採用中です!
ご応募をお待ちしております!