旅先で便利に使える!? 外国語読み取り自動翻訳メガネ!
第1回:Google AIYを使って、日本語対応スマートスピーカーをサクッと作る
第2回:部品を自作して、押したらGoogleがしゃべり出すPush to Talkを完成させる
第3回:会話をリアルタイムに記録、自動でテキスト化するスマート議事録デバイス!
第4回:遂に夢の翻訳こんにゃく?スマートほんやくイヤフォン
こんにちは、ヨシケンです!ここまでラズパイを使って、音声聞き取りや翻訳などをやってきました。
今回は更にカメラによる画像解析を使って、旅先などで知らない言葉が出てきた時に読み取り、日本語に翻訳してくれるメガネを作りたいと思います。前回の翻訳イヤフォンと合わせれば、旅先で見て、聞いて、いつでも日本語にしてくれる夢のデバイスになるはずです!
今回の記事で必要な物一覧
・ラズパイ・カメラモジュール
(ラズパイ公式カメラです。これと同形状で夜間撮影が可能なPiNoIRカメラもあります。)
・スイッチ付きブレイクアウト基盤
(Adafruit 2ピンJST-PHコネクタ)
・小型バッテリー
(リチウムイオンポリマー電池
※注意:取り扱いに充分気を付けて自己責任でお使いください)
・ケース
(フリスクなどの空き箱を流用しています)
・だてメガネ
(100円ショップなどで購入。必要に応じて。)
今回の記事の流れ
1.Google AIY、ReSpeakerのセットアップ
2.カメラの接続、Google Visionの設定
3.Google Translateの設定、Visionへの組み込み
4.メガネ型デバイスにする
5.まとめ
1.Google AIYとReSpeakerのセットアップ
今回も小型ラズパイのRasPi Zeroと、ReSpeaker 2-MicにGoogle AIYをインストールして使っていきます。これまでの記事を参照して、Google AIYのインストール、ReSpeakerのセットアップをしておいてください。
写真のようにZeroとReSpeakerをセットし、スピーカーから音が出力できるよう、確かめておいてください。
またZero用のカメラケーブルを使って、カメラとラズパイをつなぎます。
ReSpeakerに付いているボタンを利用し(ラズパイとはGPIO17番につながっています)、以下のようなプログラムで機能を切り替えるようにします。ボタン長押しで写真撮影、押した回数により音声聞き取り、発話などを行ってみます。
[button_action.py]
このように1回押しで録音、2回でそれを出力、そして長押しで写真を撮るアクションをボタンで操作しています。
2.カメラ、Google Visionの設定
ラズパイZeroで、写真撮影、音声の入出力といった基本的な事ができるようになったら、GoogleのAPIを使って、そこに何が写っているのかを解析できるようにしましょう。
Googleの画像解析機能として、Google Vision APIがあります。これは画像検索などに使われている機能を、ラズパイで使いやすいPythonから簡単に呼び出す事ができるようになっています。Visionには、ラベル(物や風景など)、顔検出やロゴ判別と共に、テキスト読み込みの機能があります。
Pythonでカメラが扱えるpicameraをインストールします。これまでのようにsmartフォルダを使っていき、その中に画像を格納するimageフォルダを作ります。また翻訳イヤフォンの設定のように、Googleのサービスアカウントキーが必要ですので、取得して、exportしておきます。
$ cd ~/AIY-projects-python/src/smart
$ sudo mkdir image
$ sudo chmod 755 image
$ export GOOGLE_APPLICATION_CREDENTIALS=”/home/pi/[FILE_NAME].json”
$ sudo vi vision.py
Google Visionを使った画像解析プログラムを作ります。
[vision.py]
# -*- coding: utf-8 -*- | |
import argparse | |
import base64 | |
import httplib2 | |
import picamera | |
import os | |
import re | |
from datetime import datetime | |
from googleapiclient import discovery | |
from oauth2client.client import GoogleCredentials | |
import aiy.audio | |
import aiy.voicehat | |
default_detect= ["FACE", "LABEL", "LOGO"] | |
default_max = 3 | |
dir_image = '/home/pi/AIY-projects-python/src/smart/image/' | |
DISCOVERY_URL = "https://{api}.googleapis.com/$discovery/rest?version={apiVersion}" | |
def camera(): | |
now = datetime.now() | |
dir_name = now.strftime('%Y%m%d') | |
dir_path = dir_image + dir_name + '/' | |
file_name= now.strftime('%H%M%S') + '.jpg' | |
fname = dir_path + file_name | |
try: | |
os.mkdir(dir_path) | |
except OSError: | |
print('Date dir already exists') | |
camera = picamera.PiCamera() | |
camera.resolution = (640, 480) | |
camera.capture(fname) | |
return fname | |
def main(detect="", photo_file=""): | |
if photo_file == "": | |
photo_file = camera() | |
credentials = GoogleCredentials.get_application_default() | |
service = discovery.build('vision', 'v1', credentials=credentials, | |
discoveryServiceUrl=DISCOVERY_URL) | |
with open(photo_file, 'rb') as image: | |
image_content = base64.b64encode(image.read()) | |
if detect == "": #No parameter | |
DETECT = default_detect | |
else: #Paremater specified | |
DETECT = [detect.upper()] | |
result = "" | |
for DET in DETECT: | |
service_request = service.images().annotate(body={ | |
'requests': [{ | |
'image': { | |
'content': image_content.decode('UTF-8') | |
}, | |
'features': [{ | |
'type': DET+'_DETECTION', | |
'maxResults': default_max | |
}] | |
}] | |
}) | |
response = service_request.execute() | |
annotation = DET.lower()+'Annotations' | |
try: | |
results = response['responses'][0][annotation] | |
for res in results: | |
if DET in ["LABEL", "LOGO"]: #ラベル、ロゴ検出 | |
if res["score"] > 0.7: | |
result += res["description"]+", " | |
elif DET in ["TEXT"]: #テキスト検出 | |
result += res["description"]+", " | |
elif DET in ["FACE"]: #顔検出 | |
if res["joyLikelihood"] == "VERY_LIKELY" or res["joyLikelihood"] == "LIKELY": | |
result += "Smile " | |
if res["angerLikelihood"] == "VERY_LIKELY" or res["angerLikelihood"] == "LIKELY": | |
result += "Angry " | |
if res["headwearLikelihood"] == "VERY_LIKELY" or res["headwearLikelihood"] == "LIKELY": | |
rsult += "Capped " | |
result += DET + ", " | |
except: | |
result += "No " + DET + ", " | |
print('Result: ' + result) | |
aiy.audio.say(result, 'en-US') | |
if __name__ == '__main__': | |
parser = argparse.ArgumentParser() | |
parser.add_argument('--detect', nargs='?', default='', help='LABEL, FACE, LOGO and TEXT_DETECTION') | |
parser.add_argument('--image', nargs='?', default='', help='Image file name') | |
args = parser.parse_args() | |
main(args.detect, args.image) |
このプログラムをpython3 vision.pyと流すと、カメラで写真が撮られ、それをラベルや顔認識などを行い、英語で話してくれるはずです。

また–detect textとすれば、言語の読み取りを行います。(この時点だと英語読み取り、発話のみ)

3.Google TranslateのVisionへの組み込み
このデバイスは旅先で外国語を読み取るのを目的としているので、Google Translateを使って、読み取った情報を日本語に変換します。前回の翻訳イヤフォンの記事を参照して、Translateをアクティベートしておきます。また日本語発話のためのAquestTalkも、導入が済んでいない方は、下記のようにインストールしておいてください。
(ラズパイにログオンして) $ tar zxvf ~/AIY-projects-python/src/aquestalkpi-20130827.tgz
先ほどのvisionプログラムにtranslate機能を追加します。以下の黄色の部分が追加部分です。
[vision_trans.py]
# -*- coding: utf-8 -*- | |
… | |
default_trans = 'ja-JP' | |
aiy_lang = ['en-US', 'en-GB', 'de-DE', 'es-ES', 'fr-FR', 'it-IT'] | |
import urllib.request, urllib.parse, urllib.error | |
DEVICE = 0 | |
CARD = 0 | |
VOLUME = 50 | |
aquest_dir = '/home/pi/AIY-projects-python/src/aquestalkpi/AquesTalkPi' | |
from google.cloud import translate | |
def translate_text(text, trans_lang): | |
if trans_lang == '': | |
return text | |
else: | |
target_lang = trans_lang.split("-")[0] | |
translate_client = translate.Client() | |
result = translate_client.translate(text, target_language=target_lang) | |
return result['translatedText'] | |
… | |
def main(detect="", photo_file="", trans_lang=""): | |
… | |
print('Result: ' + result) | |
if trans_lang: | |
trans_text = translate_text(result, trans_lang) | |
trans_text = trans_text.replace("'","") | |
print('Trans: ' + trans_text) | |
if trans_lang in aiy_lang: | |
aiy.audio.say(trans_text, trans_lang) | |
elif trans_lang == "ja-JP": | |
os.system(aquest_dir + ' -g {} {} | aplay -D plughw:{},{}'.format(VOLUME, trans_text, CARD, DEVICE)) | |
else: | |
aiy.audio.say('Nothing to trans!', 'en-US') | |
else: #trans_lang = null then default en-US | |
aiy.audio.say(result, 'en-US') | |
if __name__ == '__main__': | |
parser = argparse.ArgumentParser() | |
parser.add_argument('--detect', nargs='?', default='', help='LABEL, FACE, LOGO and TEXT_DETECTION') | |
parser.add_argument('--image', nargs='?', default='', help='Image file name') | |
parser.add_argument('--trans', nargs='?', default='', help='If null no trans (en-US) or trans lang like ja-JP') | |
args = parser.parse_args() | |
main(args.detect, args.image, args.trans) |
このプログラムをpython3 vision_trans.py –detect text –trans ja-JPという形で流してみましょう。対象とする画像中の言語を指定する必要はなく、自動的に中国語やイタリア語などを読み取ってくれます。
4.ウェアラブルVisionめがねを作り上げる
それでは最後にそれぞれをまとめて、ウェアラブル機器にします。
ReSpeakerにはラジオジャックだけでなく、スピーカー対応のコネクタもあるので、こちらにミニスピーカーをつなぎます。
電源は前回のようにリチウムイオンポリマー電池を使います。充電や電源としての使用は自己責任で充分注意して使ってくださいね。RasPi Zeroの電源裏側にスイッチをハンダ付けします。そこにリポ電池をつないで、電源が入るか確認します。
ZeroとReSpeakerの間にぴったり電池が入るようにします。外装にはフリスクのケースを加工して、本体、カメラ、電池などが収まるようにします。カメラはこの写真の向きが正面になります。
スピーカー、スイッチも使いやすい位置にセットします。
今回はメガネの横に付けて、カメラの方向を固定し、何となく未来のメガネっぽくしています。好みに合わせて形作ってみてください。
最後に先程のbuttonプログラムを改造して、機能をコントロールします。
ボタン長押しで、対象物の写真を撮り、そこに写ったテキスト(外国語)を日本語に変換するようにします。
ボタン一回押しで、外国語を聞いてそれを日本語にして返してくれる機能も付けます。これは前回のcloudspeech_trans.pyを使います。
また二回押しで自分が話した日本語を外国語に翻訳するようにします。
[button_trans.py]
これだけやれば外国語の看板などを訳し、話し声を日本語にし、そして自分の言葉を外国語に変換してくれるという万能の(?)メガネのできあがりです!
では、やってみましょう。外で使うときもWi-Fiなどのネットワーク接続は必要ですので、ポケットWi-Fiやテザリングなどを用意してくださいね。
まずはこのような中国の列車の表示を訳してみましょう。button_trans.pyには、–trans ja-JPと付けます。
また例えばタイの田舎のレストランに行った時に、こんなタイ語だけのメニューがあった時に役立つかもしれません。
また、イタリア旅行に行ったとして、鉄道の駅の看板やイタリアの人に行き方を聞くシチュエーションでも使ってみましょう。この時は、–speech it-IT –trans ja-JPを付けています。
まず1回押して、イタリア語で喋った内容(il treno diretto ~の部分をパソコンから発音させています)を、見事「ローマ行きの列車は~」と日本語に訳してくれています。
また2回押して、日本語で「ローマの行き方を教えて」と言うと、それをイタリア語「Dimmi come arrivare~」と発音してくれています。
最後にボタンを長押しで画像を見せて(イタリアの鉄道の標識)、それを解読し、なんとか日本語にしてくれています。
こちらが実際使っている時の動画です。
見て、聞いて、喋るメガネデバイス、これからの旅行シーズンに便利に使えるのではないでしょうか!?
5.まとめ
今回は、RasPi Zeroにカメラを付け、Googleの画像解析機能Vision APIを使い、文字読み取りを行いました。Google Translateと合わせて、外国語の看板などを日本語に訳してくれるようにし、旅行などに使えるウェアラブル機器になっています。
Google Visionはこのテキスト読み取り以外にも、定番の顔検出やラベル検出(物や風景の読み取り)もあり、今回のvision_trans.pyに、–detect faceやlabelと付けるとさまざまなものを読み取ってくれますので、試してみてください。
これまで、ラズパイとGoogleのAPIを組み合わせて、話題のGoogle Homeのようなものや、自動議事録機、そして翻訳マシーンなどを作ってきました。
ラズパイがあれば市販品やびっくりするような機能が、安価に、そして自分の手で作れてしまいます。
これからも自由な発想に任せて、モノ作りしていきましょう!
(ヨシケン)
今回の連載の流れ
第1回:Google AIYを使って、日本語対応スマートスピーカーをサクッと作る
第2回:部品を自作して、押したらGoogleがしゃべり出すPush to Talkを完成させる
第3回:会話をリアルタイムに記録、自動でテキスト化するスマート議事録デバイス!
第4回:遂に夢の翻訳こんにゃく?スマートほんやくイヤフォン
第5回:旅先で便利に使える!? 外国語読み取り自動翻訳メガネ!(今回)