YOLOv3を用いてポケモンGOの黒卵の出現を自動検出してGoogle-Homeに喋らせる
はじめに
みなさんはポケモンGOというゲームをご存知でしょうか.ポケモンGOは位置情報を利用し,実際に現実世界に繰り出し様々な土地で出現するポケモンをゲットし収集するゲームです.
このポケモンGOの中に『レイド』なるものがあります.レイドでは,ポケモンGOの世界で『ジム』と呼ばれる場所に45分間出現する特別なポケモンをみんなで協力して倒すことができ,ポケモンを倒した人は報酬としてそのポケモンをゲットするチャンスが与えられます.ジムでレイドが行われる場合,一時間前にそのジム上に『卵』が出現します.出現する卵の色によって,出現する特別なポケモンの強さが変わり,黒卵の場合は『伝説のポケモン』が出現します.
伝説のポケモンは黒卵のレイドでしか入手できないため,ポケモンGOをプレイするポケモンマスターは日々黒卵が出現しているかをチェックし,黒卵が出現したジムの周りに集まる習性があります.私も土日はポケモンGOの画面を開き黒卵が出現しているかをチェックしています.
しかし,常にポケモンGOの画面を開き黒卵の出現をチェックするのは大変で,出現に気づかないことが多々あります.
そこでふと『黒卵が出現しているかのチェックを自動化できないか』と思い,やってみました.
どうやって作るか
YOLOv3を用いてMacbookPro上に出力したポケモンGO内のレイド一覧画面を認識し,黒卵を検出 → 黒卵を検出した場合,google-home-notifierを用いてGoolgleHomeに喋らせる,という方法で自動化したいと思います(無理矢理感あふれる)
YOLOv3の導入
cd 任意の場所 git clone https://github.com/pjreddie/darknet.git
認識させたい物体(黒卵)の学習準備
下記サイトを参考に黒卵の画像を学習させます.黒卵の画像の水増し,画像内の検出させたい物体の位置とラベルの出力を行います.
認識させたい物体(黒卵)の学習
Google Colaboratory(無料でGPUを利用できる環境が提供されている)を用いて学習を行います.
- Google Colab上にYolo v3動作環境を用意する
!apt update !nvcc -V !ln -sf /usr/local/cuda-9.2 /usr/local/cuda !apt-get install gcc-4.8 g++-4.8 !update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 40 --slave /usr/bin/g++ g++ /usr/bin/g++-4.8 !update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 50 --slave /usr/bin/g++ g++ /usr/bin/g++-7 !update-alternatives --config gcc # 入力欄が出てくるのでg++-4.8のインデックスを入力
import os import google.colab import googleapiclient.discovery import googleapiclient.http google.colab.auth.authenticate_user() drive_service = googleapiclient.discovery.build('drive', 'v3') upload_filename = 'darknet.zip' file_list = drive_service.files().list(q="name='" + upload_filename + "'").execute().get('files') file_id = None for file in file_list: if file.get('name') == upload_filename: file_id = file.get('id') break if file_id is None: print(upload_filename + ' is None.') else: with open(upload_filename, 'wb') as f: request = drive_service.files().get_media(fileId=file_id) media = googleapiclient.http.MediaIoBaseDownload(f, request) done = False while not done: progress_status, done = media.next_chunk() print(100*progress_status.progress(), end="") print("complete")
- GoogleDriveからダウンロードしたzipを解凍
!unzip darknet.zip
%%bash cd darknet make
- 学習を開始.darknet53.conv.74は重みの初期値ファイル.
%%bash cd darknet ./darknet detector train cfg/obj.data cfg/yolov3-voc-obj.cfg darknet53.conv.74
学習が開始されると,あらかじめ設定されている試行回数(ここでは100)毎に重みファイルが出力されます.試したところ,だいたい試行回数1000の重みファイルで物体はある程度検出可能であったため,試行回数1100で学習を終えました.重みファイルは随時ダウンロードしておきます.
- 黒卵を検出できるかの確認
./darknet detector test cfg/obj.data cfg/yolov3-voc-obj.cfg backup/yolov3-voc-obj_1100.weights iOS.png
YOLOv3によるポケモンGO画面の監視方法
ポケモンGOの画面をミラーリングソフト(iPad/iPhone画面録画ソフト)を利用してMacbookProに出力し,MacbookProのスクリーンショット画像をYOLOv3で認識します.
screencapture ./test.jpg ./darknet detector test cfg/obj.data cfg/yolov3-voc-obj.cfg backup/yolov3-voc-obj_1100.weights test.jpg > result.txt
GoogleHomeへの通知
google-home-notifierを利用する.下記サイトにmacOSでのgoogle-home-notifier導入について解説されているので,指示に従って行います.
- main.jsの作成
const googlehome = require('google-home-notifier') const language = 'ja'; googlehome.device('Google-Home', language); googlehome.notify('ポケモンGOで星5レイドが出現しました。', function(res) { console.log(res); });
コマンドを実行すると,GoogleHomeMiniが独特の声で喋ります.
YOLOv3の黒卵検知とGoogleHomeへの通知の自動化
Pythonとlaunchdで自動化を行う.
import os import subprocess cmd = 'screencapture ./pokemongo_raid.jpg' cmd_darknet = './darknet detector test cfg/obj.data cfg/yolov3-voc-obj.cfg backup/yolov3-voc-obj_1100.weights pokemongo_raid.jpg > result.txt' subprocess.call(cmd,shell=True) subprocess.call(cmd_darknet,shell=True) test_data = open("result.txt", "r") contents = test_data.read() fd = contents.find('black_eggs') test_data.close() if fd > 0: notification_cmd = './notification_gh.sh' subprocess.call(notification_cmd.split(),shell=True) print('end')
- launchdでsearch_black_eggs.pyを自動実行させる 下記サイトを参考に行います. banmian.hatenablog.com
結果
こんな感じになりました.
ポケモンGOの黒卵を通知するGoogleHomeくん... pic.twitter.com/CAQKYEfqgw
— ykmrt@社会人になりました (@ykmrt_) April 7, 2019
これでゲームに熱中していてもGooleHomeが教えてくれます,やったね!
感想
初めてこうして記事を書きましたが,文字に起こしてアウトプットすることは非常に大変でした.ただ,継続は力なりと言いますので今後も何かネタがあったら書きたいと思います.