ぱにぱにぱにぱ

自分が考えた構築紹介を中心に、大会とかオフ会の感想とか書いたりします。

【配信ツール作成】ぱにぱにツールVer1の反省とソースコード

反省

  • 最初はコメントをつけていたものの途中から少なくなり可読性が低くなった。自分でも理解に時間がかかるレベル。
  • 起動部分、GUIとロジック部分のクラスは分けるべき。
  • 部品化できていない部分が多数あり冗長なコードが見られる。(特に動画モードと配信モードの部分)
  • 論理型の変数が多数あり管理できていない。まとめて扱う方が良かった。
  • OBSクラス自体いらない。
  • いまだにスレッドの停止の仕方がわからない。
  • これから実装の可能性もあるが、今がどの段階かを判定し認識箇所を減らして処理速度向上を狙ってもいいかも。

ソースコード

__init__.py

起動部分、GUI関連とメインロジックの部分

import datetime
from email.mime import image
from lib2to3.fixer_util import String
from lib2to3.tests.data.infinite_recursion import blkcnt_t
from logging import _startTime
import os
import re
import shutil
import sys
import threading
import time
import time
import tkinter
import win32gui
import cv2
import numpy as np
from PIL import Image
from PIL import ImageGrab
from future.moves.tkinter import messagebox
from obswebsocket import requests
from obswebsocket.core import obsws
from main import Obs, imageRecognition, screenshot
from main.Obs import Obs
from main.screenshot import Screenshot
from main.thread import mainThread

labelX = 30
txtboxY = 30
txtboxDY = 30
txtboxX = 100
txtboxWidth = 80
miniTxtboxWidth = 20
buttonX = 100
buttonDX = 50
buttonY = 210
kidouX = 400
blKidou = False
ws = Obs()
capName = "kakusi.bmp"

def createGui(frm):
    frm.geometry('600x260')
    frm.title('ぱにぱにツール ver 1.4')
    txtList = readConfig()
    '''
    画面配置(テキストボックス)
    '''
    sourceLabel = tkinter.Label(text="認識ソース")
    sceneLabel = tkinter.Label(text="シーン")
    windowLabel = tkinter.Label(text="表示ソース")
    sourceLabel.place(x=labelX, y=txtboxY)
    sceneLabel.place(x=labelX, y=txtboxY + txtboxDY)
    windowLabel.place(x=labelX, y=txtboxY + txtboxDY * 2)
    portLabel = tkinter.Label(text="ポート")
    passwordLabel = tkinter.Label(text="パスワード")
    portLabel.place(x=labelX, y=txtboxY + txtboxDY * 3)
    passwordLabel.place(x=txtboxX * 3 - labelX * 2, y=txtboxY + txtboxDY * 3)
    timeLabel = tkinter.Label(text="対戦時間")
    timeLabel.place(x=labelX, y=txtboxY+txtboxDY * 5)
    sourceTxt = tkinter.Entry(width=txtboxWidth)
    sourceTxt.place(x=txtboxX, y=txtboxY)
    sourceTxt.insert(tkinter.END, txtList[0])
    sceneTxt = tkinter.Entry(width=txtboxWidth)
    sceneTxt.place(x=txtboxX, y=txtboxY + txtboxDY)
    sceneTxt.insert(tkinter.END, txtList[1])
    windowTxt = tkinter.Entry(width=txtboxWidth)
    windowTxt.place(x=txtboxX, y=txtboxY + txtboxDY * 2)
    windowTxt.insert(tkinter.END, txtList[2])
    portTxt = tkinter.Entry(width=miniTxtboxWidth)
    portTxt.place(x=txtboxX, y=txtboxY + txtboxDY * 3)
    portTxt.insert(tkinter.END, txtList[3])
    passwordTxt = tkinter.Entry(width=miniTxtboxWidth)
    passwordTxt.place(x=txtboxX * 3, y=txtboxY + txtboxDY * 3)
    passwordTxt.insert(tkinter.END, txtList[4])
    timeTxt = tkinter.Entry(width=miniTxtboxWidth)
    timeTxt.place(x=txtboxX, y=txtboxY+txtboxDY * 5)
    timeTxt.insert(tkinter.END, txtList[5])
    kidochuuLabel = tkinter.Label(text="起動中")

    modeLabel = tkinter.Label(text="モード")
    modeLabel.place(x=labelX, y=txtboxY + txtboxDY * 4)
    var = tkinter.IntVar()
    var.set(txtList[6])
    rdo1 = tkinter.Radiobutton(frm,value=0,variable=var, text='動画')
    rdo1.place(x=txtboxX, y=txtboxY + txtboxDY * 4)
    rdo2 = tkinter.Radiobutton(frm,value=1,variable=var, text='配信')
    rdo2.place(x=txtboxX*2, y=txtboxY + txtboxDY * 4)

    '''
    タプルにテキストボックスの情報を入れて、スレッドインスタンスの作成
    '''
    guiInfo = (sourceTxt, sceneTxt, windowTxt, portTxt, passwordTxt,timeTxt)

    '''
    画面配置(ボタン)
    '''
    thread = threading.Thread()
    startButton = tkinter.Button(text="起動", command=lambda:clickKidou(kidochuuLabel, thread, guiInfo,var.get()))
    stopButton = tkinter.Button(text="停止", command=lambda:clickTeisi(kidochuuLabel, thread, guiInfo))
    startButton.place(x=buttonX, y=buttonY)
    stopButton.place(x=buttonX + buttonDX, y=buttonY)
    saveButton = tkinter.Button(text="設定保存", command=lambda:saveConfig(guiInfo,var.get()))
    saveButton.place(x=buttonX + buttonDX * 2, y=buttonY)
    screenShotButton = tkinter.Button(text="スクショ", command=lambda:copyScreenShot())
    screenShotButton.place(x=buttonX + buttonDX * 3 + 25, y=buttonY)

def copyScreenShot():
    filename='./screenShot/' + datetime.datetime.now().strftime('%Y-%m-%d-%H%M%S') + '.bmp'
    shutil.copy(capName,filename)

def clickKidou(label, thread, guiInfo,mode):
    global blKidou
    if not checkRegexpNum(guiInfo[5].get()):
        messagebox.showerror('エラー', '対戦時間には半角整数を入力してください')
        return
    blKidou = True
    ws.connect("localhost", guiInfo[4].get(), guiInfo[3].get())
    label.place(x=kidouX, y=buttonY)
    print(mode)
    if mode==0:
        thread = threading.Thread(target=lambda:beginMainDouga(ws, guiInfo))
        thread.start()

    elif mode==1:
        thread = threading.Thread(target=lambda:beginMain(ws, guiInfo))
        thread.start()

def checkRegexpNum(str):
    pattern='[0-9]+'
    return re.match(pattern, str)

def clickTeisi(label, thread, guiInfo):
    global blKidou
    label.place_forget()
    blKidou = False
    time.sleep(0.5)
    thread.clear()
    ws.disconnect()

def createMyPoke2(beforeCount):
    global capName
    count=0
    sensyutuPoke=[-1,-1,-1,-1]
    for banme in range(4):
        banmeResult=imageRecognition.imageRecognition.sensyutuNumRecognition(banme+1, capName)
        if banmeResult>=0:
            count=count+1
        else:
            break
        sensyutuPoke[banme]=banmeResult
    if beforeCount != count:
        imageRecognition.imageRecognition.createMyPokeImage(sensyutuPoke,returnNotCapName(capName),count)

    return count

def beginMainDouga(ws,guiInfo):
    '''
    ・相手ポケモンのキャプ
    ・自分の選出
    ・時間表示
    '''
    global capName
    startTime=datetime.datetime.now()
    nokoriTime=datetime.datetime.now()
    blCountTime=True #対戦時間機能を使うかどうか
    blCap = False  # キャプが必要かどうか
    blTime =False #時間計測の最初かどうか
    blbeforeCap = False #
    blChangeCapName=False #そのループでkakusi.bmpを切り替えるかどうか
    beforeResult2 = False #選出中の1個前
    sensyutuResult = False #選出前かどうか
    sensyutuResult2 = False #選出中かどうか
    beforeCount=0 #前の選択ポケモン数
    blCap2=False
    Obs.changeRender(ws, False, guiInfo[1].get(), "kakusi.bmp")
    Obs.changeRender(ws, False, guiInfo[1].get(), guiInfo[2].get())
    Obs.changeRender(ws, False, guiInfo[1].get(), "kakusi2.bmp")
    Obs.changeRender(ws, False, guiInfo[1].get(), "sensyutu.png")
    print(guiInfo[5].get())
    if  guiInfo[5].get() =="0":
        blCountTime=False
    if blCountTime:
        Obs.changeRender(ws, True, guiInfo[1].get(), "time")
    else:
        Obs.changeRender(ws, False, guiInfo[1].get(), "time")
    while blKidou:
        Obs.takeScreenshot(ws, guiInfo[0].get(), capName)

        '''
        時間計測
        '''
        if blTime and blCountTime:
            nokoriTime=datetime.timedelta(minutes=int(guiInfo[5].get()))-abs(startTime-datetime.datetime.now())
            minutes=str((nokoriTime.seconds//60)).zfill(2)
            seconds=str((nokoriTime.seconds%60)).zfill(2)
            strTime=(minutes+":"+seconds)
            Obs.setText(ws,"time",  guiInfo[1].get(),strTime)
        time.sleep(0.1)
        sensyutuResult = imageRecognition.imageRecognition.sensyutu1Recognition(capName)  # 選出前
        sensyutuResult2 = imageRecognition.imageRecognition.sensyutu3Recognition(capName)  # 選出中
        if sensyutuResult or sensyutuResult2 or blbeforeCap or beforeResult2:
            blTime=False
            '''
            対戦を始めますの画面
            '''
            if sensyutuResult:
                blCap = True
                blbeforeCap = True
            else:
                if blCap:
                    sensyutuResult3 = imageRecognition.imageRecognition.sensyutu2Recognition(capName, blCap)
                    if sensyutuResult3:
                        capName = returnNotCapName(capName)
                        blCap = False
            if sensyutuResult2:
                blbeforeCap = False
                if imageRecognition.imageRecognition.sensyutu4Recognition(capName):
                    blCap2=True
        else:
            intResult = imageRecognition.imageRecognition.commandRecognition(capName,blTime)
            if blTime==False and blCountTime:
                if intResult == 1:
                    startTime = datetime.datetime.now()
                    blTime=True

            '''
            勝負が終わった時
            '''
            if intResult == 5:
                blTaoreta = False
                blTime=False

        if blCap2:
            beforeCount=createMyPoke2(beforeCount)
            blCap2=False

def beginMain(ws, guiInfo):
    '''
    ・スクリーンショット
    ・画像認識
    ・OBSの操作
    '''
    global capName
    blCountTime=True #対戦時間機能を使うかどうか
    blCap = False  # キャプが必要かどうか
    blTime =False #時間計測の最初かどうか
    blbeforeCap = False #
    blTaoreta = False #倒れたの判定
    blTonbo = False #戻っていくの判定
    blRenderSentaku=False #選択中の文字とかの表示非表示
    blRenderkakusi1=False #kakusi.bmpの表示非表示
    blRenderkakusi2=False #kakusi2.bmpの表示非表示
    blRenderSensyutu=False #sensyutu.pngの表示非表示
    blSensyutuCheck=False #選出チェックが必要かどうか
    beforeResult=False #1つ前の判定
    beforebeforeResult=False #2つ前の判定
    beforeResult2 = False #選出中の1個前
    sensyutuResult = False #選出前かどうか
    sensyutuResult2 = False #選出中かどうか
    sumtime=63 #処理にかかっている時間を合計したもの
    startTime=datetime.datetime.now()
    nokoriTime=datetime.datetime.now()
    taoretaCount=0 #試合中何回倒れたか
    beforeIntResult=0 #1つ前の判定
    intResult = 0 #技選択のぶぶんの判定
    result=False #技選択中かどうか
    blsumTime=False #合計時間がたくさん経ったかどうか
    #blChangeCapName=False #そのループでkakusi.bmpを切り替えるかどうか
    Obs.changeRender(ws, False, guiInfo[1].get(), "kakusi.bmp")
    Obs.changeRender(ws, False, guiInfo[1].get(), guiInfo[2].get())
    Obs.changeRender(ws, False, guiInfo[1].get(), "kakusi2.bmp")
    Obs.changeRender(ws, False, guiInfo[1].get(), "sensyutu.png")
    if  guiInfo[5].get() ==0:
        blCountTime=False
    if blCountTime:
        Obs.changeRender(ws, True, guiInfo[1].get(), "time")
    else:
        Obs.changeRender(ws, False, guiInfo[1].get(), "time")
    timeNow = datetime.datetime.now()
    while blKidou:
        Obs.takeScreenshot(ws, guiInfo[0].get(), capName)
        if blTime:
            nokoriTime=datetime.timedelta(minutes=int(guiInfo[5].get()))-abs(startTime-datetime.datetime.now())
            minutes=str((nokoriTime.seconds//60)).zfill(2)
            seconds=str((nokoriTime.seconds%60)).zfill(2)
            strTime=(minutes+":"+seconds)
            Obs.setText(ws,"time",  guiInfo[1].get(),strTime)


        beforeResult2 = sensyutuResult2
        time.sleep(0.05)
        sensyutuResult = imageRecognition.imageRecognition.sensyutu1Recognition(capName)  # 選出前
        sensyutuResult2 = imageRecognition.imageRecognition.sensyutu3Recognition(capName)  # 選出中

        if sensyutuResult or sensyutuResult2 or blbeforeCap or beforeResult2:
            taoretaCount=0
            blTaoreta = False
            if blTime and blCountTime:
                blTime=False
                Obs.setText(ws,"time",  guiInfo[1].get(),"00:00")

            '''
            対戦を始めますの画面
            '''
            if sensyutuResult:
                capName = returnNotCapName(capName)
                blCap = True
                blSensyutuCheck=True
                blbeforeCap = True
            else:
                if blCap:
                    sensyutuResult3 = imageRecognition.imageRecognition.sensyutu2Recognition(capName, blCap)
                    if sensyutuResult3:
                        Obs.setOptions(ws,capName)
                        capName = returnNotCapName(capName)
                        blCap = False
                elif blSensyutuCheck:
                    sensyutuResult3 = imageRecognition.imageRecognition.sensyutu2Recognition(returnNotCapName(capName), blCap)
                    if not sensyutuResult3:
                        sensyutuResult3 = imageRecognition.imageRecognition.sensyutu2Recognition(capName, blCap)
                        if sensyutuResult3:
                            capName = returnNotCapName(capName)

            if sensyutuResult2:
                blbeforeCap = False


            if capName == "kakusi.bmp":
                if blRenderkakusi1==True:
                    Obs.changeRender(ws, False, guiInfo[1].get(), "kakusi.bmp")
                    blRenderkakusi1=False
                if blRenderkakusi2==False:
                    Obs.changeRender(ws, True, guiInfo[1].get(), "kakusi2.bmp")
                    blRenderkakusi2=True
            else:
                if blRenderkakusi1==False:
                    Obs.changeRender(ws, True, guiInfo[1].get(), "kakusi.bmp")
                    blRenderkakusi1=True
                if blRenderkakusi2==True:
                    Obs.changeRender(ws, False, guiInfo[1].get(), "kakusi2.bmp")
                    blRenderkakusi2=False

            if blRenderSensyutu ==False:
                Obs.changeRender(ws, True, guiInfo[1].get(), "sensyutu.png")
                blRenderSensyutu=True

        else:

            beforeIntResult=intResult
            intResult = 1
            intResult = imageRecognition.imageRecognition.commandRecognition(capName,blTime)
            print(sumtime)
            if blTime==False and blCountTime:
                if intResult == 1:
                    startTime = datetime.datetime.now()
                    blTime=True
            '''
            合計時間が多すぎる時はリセット
            '''
            if sumtime>80:
                blsumTime=False
                if sumtime >10000:
                    sumtime=80
            else:
                blsumTime=True


            '''
            たたかうの画面の時、隠す画面の更新を行う。
            '''
            if (not beforeResult) and intResult == 1 and sumtime >= 80:
                print(sumtime)
                capName = returnNotCapName(capName)

            '''
            たたかうの画面、技選択、ポケモン交代画面の時
            '''
            if intResult == 1:
                sumtime=-30

            if intResult == 1 or intResult == 2 or intResult == 6:
                blTaoreta = False
                result = True
            else:
                result = False

            '''
            技選択、ポケモン交代画面の時
            '''
            if intResult == 2 or intResult == 6:
                blTonbo = False

            if intResult == 6:
                sumtime=-60
            '''
            倒れた時、3回以上倒れた時は除く
            '''
            if intResult == 3 and taoretaCount<3:
                capName = returnNotCapName(capName)
                blTaoreta = True
                if beforeIntResult!=3:
                    taoretaCount=taoretaCount+1

            '''
            とんぼ、ボルチェンの時
            '''
            if intResult == 4:
                capName = returnNotCapName(capName)
                blTonbo = True

            '''
            勝負が終わった時
            '''
            if intResult == 5:
                blTaoreta = False
                if blCountTime:
                    blTime=False
                    Obs.setText(ws,"time",  guiInfo[1].get(),"00:00")


            '''
            技選択中の場合、合計時間を図りだす
            '''
            if result and sumtime>0:
                sumtime=0

            sumtime=sumtime+(datetime.datetime.now() - timeNow).microseconds / 10000
            timeNow = datetime.datetime.now()
            '''
            表示非表示の切り替え
            '''
            if blRenderSentaku !=((result or beforeResult or blsumTime or blTaoreta or blTonbo)) :
                Obs.changeRender(ws, (result or beforeResult or blsumTime or blTaoreta or blTonbo), guiInfo[1].get(), guiInfo[2].get())
            blRenderSentaku=(result or beforeResult or blsumTime or blTaoreta or blTonbo)
            if capName == "kakusi.bmp":
                if blRenderkakusi1==True:
                    Obs.changeRender(ws, False, guiInfo[1].get(), "kakusi.bmp")
                    blRenderkakusi1=False
                if blRenderkakusi2!=(result or beforeResult or blsumTime or blTaoreta or blTonbo):
                    Obs.changeRender(ws, (result or beforeResult or blTaoreta or blTonbo), guiInfo[1].get(), "kakusi2.bmp")
                    blRenderkakusi2=(result or beforeResult or blsumTime or blTaoreta or blTonbo)
            else:
                if blRenderkakusi1!=(result or beforeResult or blsumTime or blTaoreta or blTonbo):
                    Obs.changeRender(ws, (result or beforeResult or blsumTime or blTaoreta or blTonbo), guiInfo[1].get(), "kakusi.bmp")
                    blRenderkakusi1=(result or beforeResult or blsumTime or blTaoreta or blTonbo)
                if blRenderkakusi2==True:
                    Obs.changeRender(ws, False, guiInfo[1].get(), "kakusi2.bmp")
                    blRenderkakusi2=False
            if blRenderSensyutu ==True:
                Obs.changeRender(ws, False, guiInfo[1].get(), "sensyutu.png")
                blRenderSensyutu=False

            beforeResult = result
            beforeResult2 = False

def outputNow():
    timeNow = datetime.datetime.now()
    print(timeNow)


def readConfig():
    list = []
    count=0
    with open("config.txt") as f:
        for s_line in f:
            count=count+1
            list.append(s_line.rstrip('\n'))

    if count ==5:
        list.append('0')
        list.append('0')
    return list

def saveConfig(guiInfo,mode):
    os.remove("config_bk.txt")
    os.rename("config.txt", "config_bk.txt")
    with open("config.txt", "w") as f:
        for i in range(6):
            f.write(str(guiInfo[i].get()) + "\n")
        f.write(str(mode) + "\n")

def returnNotCapName(capName):
    if capName == "kakusi.bmp":
        return"kakusi2.bmp"

    if capName == "kakusi2.bmp":
        return "kakusi.bmp"

    return ""

def main():
    frm = tkinter.Tk()
    createGui(frm)
    frm.mainloop()

if __name__ == '__main__':
    main()

OBS.py

OBS制御に関する部分

'''
Created on 2019/11/04

@author: panipani
'''
import os
import time

from obswebsocket import requests
from obswebsocket.core import obsws
from main.screenshot import Screenshot

class Obs(object):
    '''
    classdocs
    '''

    def connect(self,server,obsId,obsPass):
        self.ws = obsws(server, obsPass, obsId)
        self.ws.connect()

    def changeRender(self,bl,obsScene,obsSource):
        '''
        画像の表示非表示の変更
        '''
        self.ws.call(requests.SetSceneItemRender(obsSource,bl,obsScene))

    def takeScreenshot(self,obsSource,capName):
        self.ws.call(requests.TakeSourceScreenshot(obsSource, saveToFilePath=os.getcwd()+"\\" + capName, width=1920, height=1080))
    def disconnect(self):
        self.ws.disconnect()
    def setOptions(self,sourceName):
        self.ws.call(requests.SetSourceSettings(sourceName, {"unload": False}))
    '''
    source=ソース名
    scene=シーン名
    str=テキスト
    '''
    def setText(self,source,scene,str):
        self.ws.call(requests.SetTextGDIPlusProperties(source,scene,text=str))

    def __init__(self):
        '''
        Constructor
        '''
        self.ws=obsws()

ImageRecognition.py

画像認識に関する部分

'''
Created on 2019/11/02

@author: panipani
'''
import sys

from PIL import Image
import cv2
from numpy.random.bounded_integers import np


class imageRecognition():
    '''
    画像認識に関するクラスs
    '''
    @staticmethod
    def isExistImage(imgName,tempImgName,accuracy,recTop,recButtom,recLeft,recRight):
        result=False
        img=cv2.imread(imgName)
        img1 = img[recTop : recButtom, recLeft: recRight]
        temp=cv2.imread(tempImgName)
        if temp is None:
            print(imgName+"が見つかりません")
            sys.exit(1)

        gray= cv2.cvtColor(img1,cv2.COLOR_RGB2GRAY)
        temp= cv2.cvtColor(temp,cv2.COLOR_RGB2GRAY)

        match=cv2.matchTemplate(gray,temp,cv2.TM_CCOEFF_NORMED)
        loc = np.where( match >=accuracy)

        for pt in zip(*loc[::-1]):
            result=True
        return result

    @staticmethod
    def createMyPokeImage(sensyutuPoke,img,count):
        imgImg=Image.open(img)
        if count==0:

            outputImg = imgImg.crop((310, 192, 311, 193))
            outputImg.save('test/myPoke2.bmp',quality=95)
        else:

            dst = Image.new('RGB', (408*count, 120))
            i=0
            for num in sensyutuPoke:
                outputImg = imgImg.crop((305, 187+120*num, 713, 299+120*num))
                dst.paste(outputImg,(0+408*i,0))
                i=i+1
            dst.save('test/myPoke2.bmp',quality=95)

    @staticmethod
    def capturePokemon(imgName):
        img=Image.open(imgName)
        outputImg = img.crop((1230, 200, 1320, 900))
        outputImg.save('test/enemyPoke.bmp', quality=95)
        outputImg = img.crop((330, 200, 420, 900))
        outputImg.save('test/myPoke.bmp', quality=95)

    @staticmethod
    def commandRecognition(imgName,blTime):
        if imageRecognition.isExistImage(imgName, "test/Temp4.jpg",0.85,880,1040,160,1750) and (not imageRecognition.isExistImage(imgName, "test/aite.bmp",0.85,880,1040,170,1750)) :
            return 3
        if imageRecognition.isExistImage(imgName, "test/temp.jpg",0.85,470,530,1660,1900):
            if blTime:
                return 1
            elif imageRecognition.isExistImage(imgName, "test/hpGauge.jpg",0.85,75,130,1430,1510):
                return 1
        if imageRecognition.isExistImage(imgName, "test/katimake.bmp",0.85,880,1040,160,380):
            return 5
        if imageRecognition.isExistImage(imgName, "test/kousan.bmp",0.85,880,1040,160,370):
            return 5
        if imageRecognition.isExistImage(imgName, "test/tonbo.bmp",0.85,880,1040,160,1750) and (not imageRecognition.isExistImage(imgName, "test/aite.bmp",0.85,880,1040,170,1750)):
            return 4
        if imageRecognition.isExistImage(imgName, "test/temp2.jpg",0.85,520,580,1660,1900):
            return 2
        if imageRecognition.isExistImage(imgName, "test/temp3.jpg",0.85,0,200,0,1000):
            return 6
        if imageRecognition.isExistImage(imgName, "test/tojiru.bmp",0.85,470,530,1660,1900):
            return 2

        return 0

    @staticmethod
    def sensyutu1Recognition(imgName):
        if imageRecognition.isExistImage(imgName, "test/searchtemp.jpg",0.85,860,1070,510,1400):
            return True
        if imageRecognition.isExistImage(imgName, "test/friendTemp.bmp",0.85,890,990,540,620):
            return True
        return False

    @staticmethod
    def sensyutu2Recognition(imgName,bl):
        if imageRecognition.isExistImage(imgName, "test/sensyututemp.jpg",0.85,70,330,480,1250):
            if bl:
                imageRecognition.capturePokemon(imgName)

            return True

        return False

    @staticmethod
    def sensyutu3Recognition(imgName):
        if imageRecognition.isExistImage(imgName, "test/sensyututemp2.jpg",0.85,0,90,0,600):
            return True

        return False

    @staticmethod
    def sensyutu4Recognition(imgName):
        if imageRecognition.isExistImage(imgName, "test/sensyututemp4.bmp",0.85,65,125,300,360):
            return True

        return False
    @staticmethod
    def sensyutuNumRecognition(banme,imgName):
        for num in range(6):
            if imageRecognition.isExistImage(imgName, "test/ban" + str(banme) +".bmp",0.85,105+num*145,175+num*145,1300,1400):
                return num
        return -1

    def __init__(self, params):
        '''
        Constructor
        '''