一、框架實現思路
使用模板匹配的思路,在程序運行的時候,使用python pillow模塊
進行截圖,獲取當前程序運行的大圖,提前准備好模板圖片,進行匹配驗證
1.模板匹配
a.需要安裝cv2就是安裝OpenCV
pip install opencv-python
b.OpenCV中使用matchTemplate函數來實現模板匹配
cv2.matchTemplate(image, templ, method, result=None, mask=None)
image:待搜索圖像
templ:模板圖像
result:匹配結果
method:計算匹配程度的方法
c.匹配方法
關於匹配方法,使用不同的方法產生的結果的意義可能不太一樣,有些返回的值越大表示匹配程度越好,而有些方法返回的值越小表示匹配程度越好。
關於參數 method:
CV_TM_SQDIFF 平方差匹配法:該方法采用平方差來進行匹配;最好的匹配值為0;匹配越差,匹配值越大。 CV_TM_CCORR 相關匹配法:該方法采用乘法操作;數值越大表明匹配程度越好。 CV_TM_CCOEFF 相關系數匹配法:1表示完美的匹配;-1表示最差的匹配。 CV_TM_SQDIFF_NORMED 歸一化平方差匹配法 CV_TM_CCORR_NORMED 歸一化相關匹配法 CV_TM_CCOEFF_NORMED 歸一化相關系數匹配法 #本次使用
d.通過MinMaxLoc獲取最后的最佳匹配結果
利用OpenCV minMaxLoc 傳入的參數就是matchTemplate的返回值,minMaxLoc自己的返回值是一個元素,分別為(最小值,最大值,最小值所在點坐標,最大值所在點坐標)
2.截圖
使用pillow模塊,安裝:
pip install pillow
截圖代碼如下:
from PIL import ImageGrab #截取當前屏幕圖片,並保存 ImageGrab.grab().save(圖片路徑以及名字)
3.調用鼠標鍵盤事件
需要安裝python鼠標鍵盤模塊
pip install PyUserInput
導入模塊
#鼠標事件
from pymouse import PyMouse
#鍵盤事件 from pykeyboard import PyKeyboard
二、實例代碼
以完成win10自帶計算器中計算功能為例:
1.封裝圖像識別核心算法,創建ImageTemplate.py文件,內容如下:
import os from PIL import ImageGrab import cv2 class ImageTemplate: def find_image(self, tmplate_image): #構造圖片路徑 base_path = os.path.join(os.getcwd(), "source") #截圖文件保存路徑 Screenshot_file = os.path.join(base_path, "screen.png") #截取當前屏幕圖片,並保存 ImageGrab.grab().save(Screenshot_file) #使用opencv庫的imread方法分別讀取需要匹配的原始大圖和模板圖片 screen = cv2.imread(Screenshot_file) #使用截取的圖片為原始大圖 template = cv2.imread(os.path.join(base_path, tmplate_image)) #傳入模板圖片 #使用opencv庫的matchTemplate方法靜態模塊匹配,如果模板圖片在原始大圖上匹配時,則返回模板左頂點在每一個位置的匹配度,它是一個二維列表數據。 result = cv2.matchTemplate(screen, template, cv2.TM_CCOEFF_NORMED) #參數分別是 元素大圖、模板圖片、匹配算法 #利用OpenCV minMaxLoc 傳入的參數就是matchTemplate的返回值,minMaxLoc自己的返回值是一個元素,分別為(最小值,最大值,最小值所在點坐標,最大值所在點坐標) min, max, min_loc, max_loc = cv2.minMaxLoc(result) if max <= 0.95: return -1,-1 else: #此時意味着找到了匹配位置,需要計算中心點的坐標(后邊點擊,以及其他操作都是根據中心的坐標點擊的) #由max_loc可獲得匹配度最高的左頂點 #中心點坐標計算公式:左頂點坐標分別加上模塊的寬高除以2 #模板的寬高需要從模板對象template中獲取,具體template.shape屬性,這個屬性得到的是一個元素數據(高、寬) #中心點x坐標 = 左頂點x坐標 + int(template.shape[1]/2) #中心點y坐標 = 左頂點y坐標 + int(template.shape[0]/2) x = max_loc[0] + int(template.shape[1]/2) y = max_loc[1] + int(template.shape[0]/2) return x,y #斷言查找的圖片是否存在, def assertion(self, image): x,y = self.find_image(image) #如果x y都不等於-1則匹配上了,返回true,測試通過 if x != -1 and y != -1: return True else: return False
2.封裝日常操作如點擊、雙擊、下拉、輸入等方法,創建MethodOperation.py文件,內容如下:
import os import time from pymouse import PyMouse from pykeyboard import PyKeyboard from imagetemplate import ImageTemplate class MethodOperation: def __init__(self): self.keyboard = PyKeyboard() #鍵盤事件 self.mouse = PyMouse() #鼠標事件 self.imagemath = ImageTemplate() #啟動程序 def start_app(self, cmd): os.system(cmd) time.sleep(2) #點擊 def click(self, image): #傳入需要點擊的圖片,獲取中心點的坐標,然后點擊 x, y = self.imagemath.find_image(image) #如果x y 有一個為-1,則表示沒有匹配上 if x == -1 or y == -1: print(f"沒有找到圖片{image}") return x, y #點擊圖片 self.mouse.click(x, y) print(f"點擊了圖片{image},中心點坐標為{x}/{y}") time.sleep(0.5) def double_click(self, image): #傳入需要點擊的圖片,獲取中心點的坐標,然后點擊 x, y = self.imagemath.find_image(image) #如果x y 有一個為-1,則表示沒有匹配上 if x == -1 or y == -1: print(f"沒有找到圖片{image}") return x, y #點擊圖片中心點 n=2 代表點擊2次 self.mouse.click(x, y, n=2) time.sleep(1) return x,y #輸入內容 def input_text(self, image, content): x, y = self.double_click(image) #type_string輸入內容,這里內容必須是字符串 self.keyboard.type_string(str(content)) print(f"在坐標為{x}/{y},輸入了內容:{content}") time.sleep(2) #測試方法 def testmeth(self): #啟動計算器 self.start_app("calc.exe") #點擊 self.click("5.png") self.click("multiplication.png") self.click("1.png") self.click("0.png") self.click("equal.png") #斷言 if self.imagemath.assertion("51.png"): print("測試通過") else: print("斷言失敗,計算結果錯誤") #關閉計算器 self.click("close.png")
注意:
上面將模板圖片都放在了source包中