提高pyautogui识图率的优化方案

—opencv-python的模板匹配算法Template Matching

(一)需求分析

​ 如今2021年,祖国发展进入了新征程,科技技术的发展,更是不可同日而语,自动化人工智能越来越普及,钢铁侠的贾维斯仍旧高科技,办公自动化,也是一个进步吧;扯远了,,,,。近日在使用quicker软件的时候,有一个动作叫按键精灵(之前也有一个软件叫这个),目的都一样,可以录制鼠标按键的过程,不足之处在于太依赖快捷键,并且鼠标的位置是绝对位置,也就是说只能录制一些位置固定的重复动作,并达不到灵活的录制效果,于是心生一个想法,利用python的图像识别 + 按键模拟实现这样灵活的动作效果。虽然pyautogui有一个函数也可以匹配图片,但是效果不理想,所以才提出的这个方案。

pyautogui.locateOnScreen(‘folder.png’)
在当前屏幕匹配folder.png文件。

总之:一句话,python的图像识别 + 按键模拟实现自动化办公

(二)pyautogui的使用

1.pyautogui简介

PyAutoGUI具有以下功能:

  • 移动鼠标,然后单击或在其他应用程序的窗口中键入。
  • 向应用程序发送击键(例如,填写表格)。
  • 截取屏幕截图,并给出图像(例如,按钮或复选框的图像),然后在屏幕上找到它。
  • 找到应用程序的窗口,然后移动,调整大小,最大化,最小化或关闭它(当前仅Windows)
  • 在GUI自动化脚本运行时,显示消息框供用户交互
  • 总结就是模拟键盘鼠标的操作

官方教程: https://pyautogui.readthedocs.io/en/latest/

网络教程: https://blog.csdn.net/weixin_43430036/article/details/84650938(推荐,讲得比较详细)

(三)opencv-python的模板匹配算法Template Matching

1.模板算法简绍

官网教程 :https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_template_matching/py_template_matching.html#

网络教程: https://www.jianshu.com/p/5f4bb5c78184

具体用途: 从一张大的背景图中,找到一张你想要的小图;

例子1:例如从足球比赛场(背景大图)中找到梅西(待找小图):

模板图片

提高pyautogui识图率的优化方案_第1张图片

例子2:从一个电路版(背景大图)中找到主控芯片(待找小图)

提高pyautogui识图率的优化方案_第2张图片

2.算法性能测试

结论: 尽量选择干扰小的背景,匹配的图尽量的丰富,优先考虑使用cv2.TM_CCOEFF_NORMED算法。

注意:这个测试并非专业测试,结果仅仅对于桌面图标的识别的简单测试,只能参考

提高pyautogui识图率的优化方案_第3张图片

3.测试代码

# 导入模块 cv2匹配算法 plt 显示图片
import cv2
from matplotlib import pyplot as plt

# 读入图片 big1.png是背景大图; small.png是需要寻找的小图(格式.jpg .png都行)
img = cv2.imread("big1.png",0) # 0 读入灰度图
img3 = cv2.imread("big1.png",1) # 1 读入彩色图
img2 = img.copy()
template = cv2.imread("small.png",0)
w, h = template.shape[::-1]


# 6种算法的列表
methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',
            'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']

# 依次使用算法匹配
for meth in methods:
    img = img2.copy()
    method = eval(meth)

    # 应用模板算法,返回一系列指标
    res = cv2.matchTemplate(img,template,method)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) # 从res中挑选最优指标

    # 注意 TM_SQDIFF 或者 TM_SQDIFF_NORMED 算法使用最小值为最优
    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
        top_left = min_loc
    else:
        top_left = max_loc
    bottom_right = (top_left[0] + w, top_left[1] + h)

    # 显示图片
    cv2.rectangle(img3,top_left, bottom_right, (0,0,255), 2) # 画出矩形框
    plt.axis('off') # 关闭坐标
    img3 = cv2.cvtColor(img3, cv2.COLOR_BGR2RGB) # 颜色转换
    plt.subplot(121),plt.imshow(res,cmap = 'gray')
    plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
    plt.subplot(122),plt.imshow(img3)
    plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
    plt.suptitle(meth)
    plt.show()

(四)图片识别的自动化办公

(1)环境安装

python版本:python3.6

第三方库:

pip install opencv-python==4.5.1.48
pip install pillow==8.2.0
pip install pyautogui==0.9.52
pip install win32gui==221.6
pip install pywin32==300

注意:pip 安装库慢,可以设置安装源,在命令行输入(永久设置)

pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

pyautogui安装失败的,可以参考:http://www.bubuko.com/infodetail-2982758.html

(2)思路:

​ 通过cv2的Template Matching算法,匹配到小图在大图的位置,使用pyautogui模拟按钮操作。

(3)代码

​ 启动顺序:事先把需要操作的图标截好图,最为小图,大图不需要准备,大图利用自动全屏截图。

具体的代码请看注释,注意的功能函数就是imgAutoCick(),其他的都是调用这个函数操作。

#  导入所需要的库 cv2:匹配图片 pyautogui:控制鼠标 os 操作文件 win32gui win32con 窗体操作
import cv2
import pyautogui
import win32gui, win32con
import os

def imgAutoCick(tempFile, whatDo, debug=False):
    '''
        temFile :需要匹配的小图
        whatDo  :需要的操作
                pyautogui.moveTo(w/2, h/2)# 基本移动
                pyautogui.click()  # 左键单击
                pyautogui.doubleClick()  # 左键双击
                pyautogui.rightClick() # 右键单击
                pyautogui.middleClick() # 中键单击
                pyautogui.tripleClick() # 鼠标当前位置3击
                pyautogui.scroll(10) # 滚轮往上滚10, 注意方向, 负值往下滑
        更多详情:https://blog.csdn.net/weixin_43430036/article/details/84650938
        debug   :是否开启显示调试窗口
    '''
    # 读取屏幕,并保存到本地
    pyautogui.screenshot('big.png')

    # 读入背景图片
    gray = cv2.imread("big.png",0)
    # 读入需要查找的图片
    img_template = cv2.imread(tempFile,0)

    # 得到图片的高和宽
    w, h = img_template.shape[::-1]

    # 模板匹配操作
    res = cv2.matchTemplate(gray,img_template,cv2.TM_SQDIFF)

    # 得到最大和最小值得位置
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

    top = min_loc[0]
    left = min_loc[1]
    x = [top, left, w, h]

    top_left = min_loc #左上角的位置
    bottom_right = (top_left[0] + w, top_left[1] + h) #右下角的位

    # 先移动再操作, 进行点击动作,可以修改为其他动作
    pyautogui.moveTo(top+h/2, left+w/2)
    whatDo(x)

    if debug:
        # 读取原图
        img = cv2.imread("big.png",1)
        # 在原图上画矩形
        cv2.rectangle(img,top_left, bottom_right, (0,0,255), 2)
        # 调试显示
        img = cv2.resize(img, (0, 0), fx=0.5, fy=0.5, interpolation=cv2.INTER_NEAREST)
        cv2.imshow("processed",img)
        cv2.waitKey(0)
        # 销毁所有窗口
        cv2.destroyAllWindows()
    os.remove("big.png")

def simple_example_baidu():
    '''这是一个例子---百度搜索图片 需要先准备好图片,截图就可以''' 
    # 调用函数-- 打开浏览器
    time.sleep(1)
    imgAutoCick("baidu_tu/test2.png", pyautogui.click)
    # 点击搜索框 百度搜图片
    time.sleep(2)
    imgAutoCick("baidu_tu/test3.png", pyautogui.click)
    # 输入内容
    time.sleep(1)
    pyautogui.typewrite("meinv1") #键盘输入
    # 点击搜索按钮
    time.sleep(1)
    imgAutoCick("baidu_tu/test4.png", pyautogui.click)
    # 点击图片按钮
    time.sleep(1)
    imgAutoCick("baidu_tu/test5.png", pyautogui.click)
    # 将鼠标移动到中间
    m, n = pyautogui.size()
    pyautogui.moveTo(x=m/2, y=n/2)
    # 将鼠标滚动
    for i in range(100):
        time.sleep(0.5)
        pyautogui.scroll(-120) # 滚轮往上滚10

if __name__=="__main__":
    # 将代码窗口最小化
    Minimize = win32gui.GetForegroundWindow()
    win32gui.ShowWindow(Minimize, win32con.SW_MINIMIZE)
    #simple_example_baidu()
    #pyautogui.alert(text='下面即将打开开始菜单', title='提示')
    pyautogui.PAUSE = 1
    pyautogui.press('winleft')
    pyautogui.PAUSE = 1
    imgAutoCick("baidu_tu/step1.png", pyautogui.click,True)

(五)不足之处:

​ 1.存在一个大问题,就是背景图改变之后,背景里的小图和需要匹配的小图,两者的尺寸不一致,导致框出来的位置不准确。但是取了中间点也就问题不是很多,再出问题的画,下次再解决。
2.pyautogui中文输入问题

你可能感兴趣的:(python,计算机视觉,opencv,算法)