基於OpenCV圖像識別實現UI自動化測試


一、框架實現思路

使用模板匹配的思路,在程序運行的時候,使用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包中


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM