見出し画像

【Poke-Controller】青色検知で色違いカルボウ探し自動化【ポケモンSV】

色違いのカルボウがほしい!
でも色違いを探しながら移動していると画面酔いしてしまう…。
そんな思いから、Poke-Controllerを使ったポケモンSVのレッツゴー色違い探し自動化プログラムを作成しました。
プログラムは下記に格納しています。

何が出来るの?

西一番エリアの西側、風車の近くで色違いカルボウを探します。
サンドイッチ作成→カルボウ色違いチェック→ゲーム再起動の自動化です。
色違いチェックは、ゲーム画面に青色があるかどうかで判定しているため、
ご利用の環境によっては上手く認識できないかもしれません。
(キャプチャボードの種類によって色味が変わるかもしれない…?)
捕獲は手動です!レポートを忘れずに。。。

事前準備

プログラムの格納

1. ダウンロードしたファイル「SV_HLScheckKarubou.py」を格納する
下記フォルダに格納してください
パス:Poke-Controller-master\SerialController\Commands\PythonCommands

「SV_HLScheckKarubou.py」の格納場所

その他の作業

1.本体の設定で「画面のズーム」を「ON」にする
本体の設定画面で「本体」→「画面のズーム」を「ON」にします。
これで、HOMEボタン2回押しで拡大表示ができるようになります。

本体の設定画面で「本体」→「画面のズーム」を「ON」

2.サンドイッチの具材を用意する
バジル、ひでん:しおスパイス、ひでん:あまスパイスを用意します。
色違いが出なければリセットするので、1つずつあれば大丈夫です。

3.サンドイッチ作成時の具材の位置を確認する
デフォルトのプログラムでは下記の位置にあることを想定しています。
 「バジル」:下から1番目(一番下)
 「ひでん:しおスパイス」:下から4番目
 「ひでん:あまスパイス」:下から5番目

デフォルトで想定している位置です。
バジルは一番下、しおは下から4番目、あまは下から5番目

上の画像と具材の位置が違う場合、プログラムを修正してください。
プログラムの16行目~18行目で、下から何番目にあるかを設定しています。

★プログラムの1618行目:
self.mybasil = 1	#★下から何番目に「バジル」があるか。デフォルトは下から1番目(一番下)を想定
self.myshio = 4		#★下から何番目に「ひでん:しおスパイス」があるか。デフォルトは下から4番目を想定
self.myama = 5		#★下から何番目に「ひでん:あまスパイス」があるか。デフォルトは下から5番目を想定

たとえば、「ひでん:しおスパイス」が1番下にある場合は、
「 self.myshio = 4」の「4」の部分を「1」に修正します。



4.西一番エリア、風車の近くに移動する

画像を参考にしてください。語彙力がなくて上手く説明できません…

ロトムの位置を目指してください。西1番エリアの西側、風車のあたり。
※ピンは向き調整用なので目的地ではありません!

5.近くにいるサンダース(シンボル)を倒す
自動化中に突っ込んでくるので、事前に倒してください。
※プログラム実行中に日付が変わるとサンダースが復活します。(再起動の処理があるため)長時間実行する場合は、ニンテンドースイッチ本体の時間を00:00にしておくと安心かも。

風車の近くにいるサンダースを倒しておこう
日付が変わってリセットすると復活するので本体時間も注意!

6.手持ちを捕獲用ポケモン1匹だけにする
手持ちポケモン少ない方が、ピクニックの動作が安定します!

7.立ち位置、ズーム位置を調整する
(1)立ち位置を調整する
画像を参考にしてください。ピクニックができる範囲で風車の近くです。

カルボウが5匹以上、できれば7匹くらい湧くように立ち位置を微調整してみてね

(2)マップを開き、すぐ右上の小島にピンを指す
これで主人公が崖の方向を向きます。視点調整に便利。
崖の方を向く理由は、空の色が誤検知に繋がるためです。

すぐ右上にある小島にピンを指すと、良い感じに崖の方を向いてくれる

(3)レポートを書く
この後の作業が終わったら再起動するのでレポートを書きます。

(4)「そうぐうパワーLv3:ほのお」のサンドイッチを作成する
カルボウの湧き位置に合わせてズーム位置を調整するため、まずは手動でサンドイッチを作成します。
材料はバジル、ひでん:しおスパイス、ひでん:あまスパイスです。

パンにバジルを乗せたシンプルなサンドイッチ

(5)ズーム位置を調整する
十字キー↓でカメラモード起動、HOMEボタン2回押しでズームします。
ズームを最大にした後、カルボウのポップする場所が映るようにズーム位置を調整します。

ズームを最大にした後、カルボウのポップ位置が画面右側にくるよう調整

(6)準備ができたらゲームを再起動する
ゲームを再起動してもズーム位置は戻らないので大丈夫です。

※立ち位置調整のコツ
そうぐうパワーLv3の効果でカルボウしか出ないようになっています。
ピクニックを開いて閉じると、消えたカルボウが再出現します。
1回のピクニックリセットで5匹以上、7匹くらいポップする立ち位置を見つけられると効率良いです。
少し位置を変えるとポップする数が変わるので、調整してみてください。
ピクニックができるギリギリのところまで風車に近づくと良さそう。

動作の流れ

「SV_色検知カルボウ(西一番エリア西側、風車)_v1.0」を実行します。
動作の流れは下記のとおりです。

1.サンドイッチ作成(そうぐうパワーLv3:ほのお)
2.色検知でカルボウ色違いチェック、出なければピクニックリセット
3.サンドイッチ作成から30分後、効果が切れたらゲーム再起動

プログラムの実行例も載せますので参考にしてください。

★動画を貼り忘れないようにしよう

色検知ってなにしてるの?

ここはプログラム中身の紹介なので、興味ない方は読み飛ばしてください。
色検知は、取得した画像内に検知したい色があるかをチェックしています。
色の表示はRGBが一般的ですが、今回はHLSで指定しました。
(「検知したい色に近い色」を指定しやすそうだったため)

色検知のプログラム部分を下記に抜粋します。

#1.色違いを検出する閾値の設定(目の青色をHLSでこの範囲内に指定)
lower = np.array([148,100,100])
upper = np.array([153,200,255])

#上記の閾値を満たす画素数がこの値以上になったら色違いとみなす(要調整)
mythreshold = 2

#ゲーム画面の画像を取得
src = self.camera.readFrame()

#画像の切り出し(ズーム時の周囲の緑色が誤検知に影響しそうなので)
height = src.shape[0]	#画像の縦の長さを取得
width = src.shape[1]	#画像の横の長さを取得
cut = 50	#切り出す幅を指定
#上から150と、上下左右にcutの幅をカット(ズーム機能で表示される上部のバーと周囲の緑色を除去)
src_cut = src[150 + cut : height -cut, 0 + cut : width - cut]

#BGRからHLSに色空間を変換(HLSの方が色の範囲を指定しやすそう)
hls = cv2.cvtColor(src_cut, cv2.COLOR_BGR2HLS_FULL)

#2.閾値内を白、それ以外を黒色にする
mask = cv2.inRange(hls, lower, upper)

#3.白色の画素数を数える
white = cv2.countNonZero(mask)

#閾値を超えているか判定、超えていたら色違いとみなす
if white > mythreshold:
	print("色違い発見!", white)
	self.finish()	#プログラムの停止

#1の部分で、色違いと判断したい色を設定しています。

#1.色違いを検出する閾値の設定(目の青色をHLSでこの範囲内に指定)
lower = np.array([148,100,100])
upper = np.array([153,200,255])

今回は、HLSで[148,100,100]~[153,200,255]の色を対象にしています。
・H(色相):148~153 欲しい青色だけ検知するよう幅を狭めに設定
・L(輝度):100~200 黒(0)や白(255)を認識しないよう設定
・S(彩度):100~255 なんとなく設定

なお、色の範囲はペイントのESLを参考に設定しました。

ペイントのESLも、HLSとほぼ同じ色空間じゃないかなー…

ESLの値の範囲は、
E(色合い:0~239)、S(鮮やかさ:0~240)、L(明るさ:0~240)

HLSの値の範囲は、
H(色相:0~255)、S(彩度:0~255)、L(輝度:0~255)

少し値の範囲は違いますが、ペイントで色の確認ができるのは便利です。
今回はペイントのスポイトで検知したい色のESLを確認、その値を参考にHLSの上限と下限を適当に設定しました。

次に、#2でさきほど設定した範囲内の色だけを取り出します。

#2.閾値内を白、それ以外を黒色にする
mask = cv2.inRange(hls, lower, upper)

cv2.inRange()という関数を使うと、入力した画像に対して、指定した範囲内の色を白、それ以外を黒にして変換した画像を返してくれます。すごい。

上側が元画像、下側がcv2.inRange()関数で変換した画像
色違いカルボウの目の部分が白い点になっています。
白い点の数は8個あるみたいです。

最後に、#3で白い点の数を数えます。

#3.白色の画素数を数える
white = cv2.countNonZero(mask)

これで、欲しい色が画面にいくつあるか、わかるようになりました。
後は、欲しい色だけを検知するように、色の設定や、画像の切り出し範囲を調整して完成です。

色検知の注意点としては、欲しい色が、欲しい場所以外に出てこないようにする必要があります。
今回で言うと、色違いカルボウの青い目を検知するため、画面内に背青い空が映らないよう注意しました。崖の方を向けば、背景に空は映りません。
その他の例では、未来パラドックスポケモンは、色違いと通常色で使っている色が一緒なので、この方法だけでは検知することができません。残念。

色違いの色が特徴的なポケモンで、かつ背景に同系色がない場所であれば、今回の色検知を使えそうですね!

おまけ(ヒラヒナ色検知もできそう)

今回のプログラムの色検知パラメータを少し変えるだけで、ヒラヒナの色違いも見つけられました。
サンドイッチで使用する具材は下記です。
・「たまねぎスライス」×1個:上から6番目を想定
・「ひでん:しおスパイス」×2個:下から4番目を想定


あとがき

猫も走るほど忙しい年末、いかがお過ごしでしょうか。
最近は週末の空いた時間しか遊べていませんが、ポケモンSVは楽しいです。
画面をあまり動かさずに色厳選できるやり方が広まってきて、酔いやすい私には大変ありがたい…!年末にゆっくり試してみたいです。

自動化を推進してくださる方々、いつもありがとうございます。
このプログラムがなにかの役に立てばうれしいです。


この記事が気に入ったらサポートをしてみませんか?