一、框架实现思路
使用模板匹配的思路,在程序运行的时候,使用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包中