[Pokémon LEGENDS アルセウス] 時空の歪みをpythonで自動検知・Discordに通知 

## メニュー
* [初めに](#初めに)
* [実行画面のキャプチャ](#実行画面のキャプチャ)
* [環境](#環境)
* [プログラムの概要](#プログラムの概要)
* [ディレクトリ](#ディレクトリ)
* [ソースコード](#ソースコード)
* [参考文献](#参考文献)
# 初めに
　`Pokémon LEGENDS アルセウス`では`時空の歪み`というイベントがあるのですが、発生条件がランダムであるためイベント発生までゲーム画面を注視する必要があります。
　そこで、`python`で画像処理を行い`時空の歪み`を検知し`Discord`に通知を行うプログラムを作成しました。

# 実行画面のキャプチャ

<iframe width="560" height="315" src="https://www.youtube.com/embed/VqoMj53J2Kg?start=5" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# 環境
- 5.10.60.1-microsoft-standard-WSL2+ (Ubuntu 20.04.4 LTS)
- python 3.9.3
    - ライブラリ : opencv、discordwebhook

# プログラムの概要
　検知には、`テンプレートマッチング`を使い、`OpenCV`の関数を利用します。
　検知されると、`Webhook`を使って`Discord`の任意のチャンネルに通知されます。`Webhook`を使うことで`URL`を指定するだけで簡単にBOTの開発が行えます。([参考文献](#参考文献))

# ディレクトリ
~~~
.
├ main.py (メインのプログラム)
└ pic/
   └ temp.jpg （テンプレート画像）
~~~

- テンプレートとして使用した画像
![temp.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525418/252cb74d-39b1-90b8-0d63-28753fb372f6.jpeg)

# ソースコード
~~~python:main.py
import cv2
from discordwebhook import Discord
import datetime
import copy

# Discord Webhook URL
discord = Discord(url="your Discord Webhook URL")

temp = cv2.imread("./pic/temp.jpg") #テンプレート画像
temp = cv2.cvtColor(temp, cv2.COLOR_BGR2GRAY) #グレイスケールに変換

capture = cv2.VideoCapture(0)
capture.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)

# テンプレートマッチング
def template(img,img_color):
    h, w = temp.shape[0],temp.shape[1]
    match = cv2.matchTemplate(img, temp, cv2.TM_SQDIFF_NORMED)
    min_value, max_value, min_pt, max_pt = cv2.minMaxLoc(match)
    pt = min_pt
    temp_out = copy.deepcopy(img_color[pt[1]:pt[1]+h,pt[0]:pt[0]+w])
    # 決め打ち
    if 500<pt[0] and pt[0]<550 and 85<pt[1] and pt[1]<105 and min_value<0.1: 
        #　時空の歪みを検知
        cv2.rectangle(img_color, (pt[0], pt[1]), (pt[0] + w, pt[1] + h), (0, 200, 0), 3)
        print("detect",min_value)
        return True,img_color,temp_out
    else:
        # 時空の歪みを非検知
        cv2.rectangle(img_color, (pt[0], pt[1]), (pt[0] + w, pt[1] + h), (0, 0, 200), 3)
        return False,img_color,temp_out


if capture.isOpened() is False:
  raise IOError

while(True):
  try:
    ret, frame = capture.read()
    frame_color = copy.deepcopy(frame)
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # グレイスケールに変換
    if ret is False:
      raise IOError

    flag,frame_out,temp_out = template(frame,frame_color)
    
    if flag: # Discordに通知
        cv2.imwrite("./pic/frame_out.jpg", frame_out)
        cv2.imwrite("./pic/temp_out.jpg", temp_out)
        f1 = open("./pic/frame_out.jpg", 'rb')
        f2 = open("./pic/temp_out.jpg", 'rb')
        dt_now = datetime.datetime.now() # 現在時刻取得
        discord.post(content="@here 時空の歪み検知 " + dt_now.strftime('%Y年%m月%d日 %H:%M:%S'),file={"1": f1,"2": f2})

    cv2.imshow('frame',frame_out)
    cv2.waitKey(1)

  except KeyboardInterrupt:
    break

capture.release()
cv2.destroyAllWindows()
~~~

# 参考文献
- [Pokémon LEGENDS アルセウス 公式サイト](https://www.pokemon.co.jp/ex/legends_arceus/ja/)
- [qiita, @Takkun053, 【Python】DiscordのWebhookで遊ぶ。](https://qiita.com/Takkun053/items/88e2d86838f711fda7e5)
- [西住工房, 【Python/OpenCV】テンプレートマッチングの実装（SSD、SAD、NCC、ZNCC）](https://algorithm.joho.info/programming/python/opencv-template-matching-ssd-py/)
- [qiita, @kakinaguru_zo, （ラズパイで）USBカメラの映像をPythonのOpenCVで高速に表示する](https://qiita.com/kakinaguru_zo/items/eda129635816ad871e9d)
- [note.nkmk.me, Pythonで現在時刻・日付・日時を取得](https://note.nkmk.me/python-datetime-now-today/)