【DQX】私のベルト整理術 pythonテンプレートマッチング

DQXには、戦神のベルトという色々な効果がつく腰装備があります。

効果は1つのベルトに2~5個つき、ハイエンドコンテンツでは高性能はベルトが求められます。

付く効果は、かなりの数の候補があるため、狙った効果のベルトを入手するのは非常に困難です。

なので、日ごろから有用そうなベルトは保管しておく。という人は多いかと思います。

しかし、種類の多さから、その管理が非常に大変で、エクセルにまとめるなどしないと、把握するのは困難です。

今回は、python OpenCVのテンプレートマッチングを使用したベルトの整理術をご紹介します。

※これは、python+OpenCVを使用した事例の紹介であり、一定の知識を持った人向けの情報になります。

目次

手順1 動画の撮影

まずは、ベルトの効果画面を撮影します。

Windows10であれば、Win+Gボタンで起動できるゲームバーから録画することができます。

録画した動画をpythonを使って解析して、CSVとして出力するのが今回の本題です。

録画を開始して、ベルトの効果画面を順番に表示していきます。

手順2 動画の解析

ベルト参考画像1

動画を読み込み、一定のフレーム毎に画像を抜き出します。

抜き出した画像が戦神のベルトの効果を表示している画面か判定を行います。

戦神のベルトであれば、効果が書いてある部分を切り抜きます。

ベルトは最大5個効果がつくので、5個分切り抜くことになります。

ベルト参考画像2

切り抜いた画像に対して、大きく分けて3つの分類でテンプレートマッチングを行います。

1枠目は武器種類や〇〇系、2枠目は属性、3枠目は効果数値 です。

あらかじめ全種類のテンプレート画像を用意しておき、各枠で一致する画像を探すわけです。

私の設定だと、ブーメラン:27 土属性:7 +12%:7 の結果を出力するようにしているので、

[27,7,7,0,0] というデータが出力されます。効果リスト

このルールに当てはめると、上記の画像のベルトは、

[6, 0, 4][27, 7, 7][18, 4, 7][18, 1, 5][14, 6, 6]

と出力されます。

手順3 解析

出力されたCSVファイルをエクセルで開き、重複削除します。

エクセルVBAを使用して、データの分解を行います。

例えば、[6,0,4] であれば、まず 6 , 0 , 4 と分解します。

そして、6→植物系 0→空白 4→+9.0% と変換し、結合した結果 植物系+9.0%の文字列ができます。

この変換は、私はVlookupで行っています。

ベルトリスト

このようにして、ベルトの一覧を作成することができました。

ベルト保管場所は、動画撮影した順になっているはずなので、手動で記入しています。

テンプレートマッチングでは、+8%を+6%と誤認識してしまうことがあります。

あくまで参考ということで、重複するベルトを破棄するときは、残したい方のベルトの効果が正しいかちゃんと確認してから破棄してます。

pythonコード

私はpython初心者なので、綺麗なコードを書けませんが、参考のために一部抜いたコードを掲載します。

このコードのまま実行しても、当然ながらエラーになります。

あくまで考え方の紹介なので、自身で試したい場合は、pythonやOpenCVの知識を勉強する必要がありますので、ご注意ください。

import cv2
import time
import csv
import numpy as np

#変数の宣言・初期化
*****************

#テンプレート用の画像の読み込み
*****************

#画像をグレースケールで読み込む
cap = cv2.VideoCapture('ベルト.mp4')

cvt = cv2.cvtColor
bgrgray = cv2.COLOR_BGR2GRAY

while(cap.isOpened()):

   ret, frame = cap.read()

   #動画終了
   if ret == False :
      break

   img = cvt(frame, 1)
   img_R = img.copy()
   img_R[:, :, (1, 2)] = 0

   img = cv2.cvtColor(img_R, cv2.COLOR_RGB2GRAY)

   if cv2.waitKey(1) & 0xFF == ord('q'):
      break

   if count % 20 == 0: #20フレーム毎に処理する
      #戦神のベルトか判定を行う
      result = cv2.matchTemplate(img, 戦神の画像, cv2.TM_CCORR_NORMED)

      loc = np.where(result >= threshold)
      if len(loc[0]) > 0:

         #ここから戦神のベルトの処理

         #各効果の領域を抜き出す
         cut_img = []
         cut_img.append(img[417:470, 720:1360]) #環境によって値は変わる
         cut_img.append(img[453:505, 720:1360])
         cut_img.append(img[490:544, 720:1360])
         cut_img.append(img[525:582, 720:1360])
         cut_img.append(img[563:619, 720:1360])

         belt_data = [[0 for i in range(3)] for j in range(5)]#ベルトデータの配列

         for i in range(0,5):
            for j in range(1,33): #効果数だけループ
               if belt_data[i][0] == 0:
                  result = cv2.matchTemplate(cut_img[i], 効果画像1, cv2.TM_CCORR_NORMED,mask=マスク画像)
                  loc = np.where(result >= threshold)
                  if len(loc[0]) > 0:
                     belt_data[i][0] = j
            for j in range(1,15): #効果数だけループ
               if belt_data[i][1] == 0:
                  result = cv2.matchTemplate(cut_img[i], 効果画像2, cv2.TM_CCORR_NORMED,mask=マスク画像])
                  loc = np.where(result >= threshold)
                  if len(loc[0]) > 0:
                     belt_data[i][1] = j
            for j in range(1,17): #効果数だけループ
               if belt_data[i][2] == 0:
                  result = cv2.matchTemplate(cut_img[i], 効果画像3, cv2.TM_CCORR_NORMED,mask=マスク画像)
                  loc = np.where(result >= threshold)
                  if len(loc[0]) > 0:
                     belt_data[i][2] = j

         output_data.append(belt_data)
         print(belt_data)
   count += 1

f = open('beltdata.csv', 'w')
writer = csv.writer(f, lineterminator='\n')
writer.writerows(output_data)
f.close()

 

目次
閉じる