+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2020-03(49)

2020-04(67)

2020-05(28)

2020-06(46)

2020-07(42)

结合图像特征检测实现简单的GUI自动化任务

发布于2020-07-25 22:55     阅读(798)     评论(0)     点赞(3)     收藏(1)


0

1

2

3

4

5

6

7

8

导读:
使用opencv检测桌面快捷方式,打开应用。再次进行检测,然后执行相关操作,依次检测执行下去,完成一系列自动化操作。

结合图像特征检测实现简单的GUI自动化任务

I. 准备工作:

导入必要的库,如果没有要去安装

import cv2
import matplotlib.pyplot as plt
import numpy as np
import pyautogui

由于需要使用到opencv中的SIFT算法,要安装3.4.2的版本,之后的版本由于涉及到专利权的问题可能没有SIFT算法(听说SIFT算法的专利权到期了,不过还不清楚最新版本的opencv里有没有SIFT算法)

print(cv2.__version__)
cv2.xfeatures2d.SIFT_create()
'''
3.4.2
<xfeatures2d_SIFT 000001A2B1671B10>
'''

注:我们要做的是在桌面上查找出预先指定的图标,为后面查找桌面应用打下基础。比如查找下图中的Google图标

img_whole = cv2.imread('images/whole.png')
img_part = cv2.imread('images/google.png')
plt.figure(figsize=(10,10))
plt.subplot(121)
plt.imshow(cv2.cvtColor(img_whole, cv2.COLOR_BGR2RGB))
plt.subplot(122)
plt.imshow(cv2.cvtColor(img_part, cv2.COLOR_BGR2RGB))
plt.show()

在这里插入图片描述

II 检测图标

这一步用到的是SIFT算法进行特征匹配,算法直接从opencv库中调用。

'''检测特征点'''
def detect(image):
    gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
    descriptor = cv2.xfeatures2d.SIFT_create()
    kps, features = descriptor.detectAndCompute(image,gray)
    return (kps,features)

我们可以看下检测出的特征点

def show_point(image):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    descriptor = cv2.xfeatures2d.SIFT_create()
    kps,features = descriptor.detectAndCompute(image, gray)
    img_src_points = cv2.drawKeypoints(image, kps,image)
    plt.figure(figsize=(10,10))
    plt.imshow(img_src_points)
show_point(img_whole)

在这里插入图片描述

关于下面这个函数又不太明白的地方,可以看下我之前opencv拼接图像的博客

'''knnMatch特征点匹配,ransac筛选'''
def match_keypoints(whole_kps, part_kps, whole_features, part_features, threshold):
    matcher = cv2.DescriptorMatcher_create('BruteForce')
    raw_matches = matcher.knnMatch(whole_features, part_features, 2)

    matches = []  # 存放匹配点index
    good = []
    for m in raw_matches:
        if len(m) == 2 and m[0].distance < m[1].distance * threshold:
            good.append(m[0])
            matches.append((m[0].queryIdx, m[0].trainIdx))
    whole_img = np.float32([kp.pt for kp in whole_kps])
    part_img = np.float32([kp.pt for kp in part_kps])
    print(len(matches))
    if len(matches) >= 4:
        # 获取匹配点坐标,单应性矩阵
        whole_pts = np.float32([whole_img[i] for (i, _) in matches])
        part_pts = np.float32([part_img[i] for (_, i) in matches])
        H, status = cv2.findHomography(part_pts, whole_pts, cv2.RANSAC, 0.99)
        return matches, H, good
    else:
        print('未检测到图标')
        # sys.exit(0)
        return False, False, False

看下H,这才是我们要的

print(H)
'''
[[ 1.04332796e+00 -2.56433864e-03  7.42950595e+02]
 [ 5.73777880e-02  9.96911440e-01  1.03397176e+03]
 [ 5.46298357e-05 -4.72211766e-06  1.00000000e+00]]
'''

下面我们开始检测logo

'''检测屏幕中的logo'''
def detect_logo(screen_img, logo_img, threshold):
    # img_part => logo_img
    # img_whole => screen_img
    img_whole, img_part = screen_img, logo_img
    # detect keypoints and features
    whole_kps, whole_features = detect(img_whole)
    part_kps, part_features = detect(img_part)
    # knnmatch ,构造单应性矩阵
    matches, H, good = \
        match_keypoints(whole_kps, part_kps, whole_features, part_features, threshold)
    if matches:
        # logo_img 四角坐标
        height, width = img_part.shape[:2]
        logo_pts = [[0, 0, 1], [width, 0, 1], [width, height, 1], [0, height, 1]]
        screen_rect = []
        # 将logo_img的四角坐标通过单应性矩阵变换到screen_img图像中的对应位置
        try:
            for pt in logo_pts:
                # 变换
                pt_trans = np.dot(H, pt)
                pt_ = list(pt_trans.astype(int)[:2])
                screen_rect.append(pt_)
        except:
            return False
        return screen_rect
    else:
        return False

将logo_img的四角坐标通过单应性矩阵变换到screen_img图像中的对应位置,像这样
在这里插入图片描述
这一步,我们已经实现了在再一幅图片中查找指定目标,后面我们可以控制鼠标到指定位置,点击打开应用,在通过logo进行定位完成其他操作。

III 控制鼠标

这是针对我电脑上的应用写的自动化操作,下面的工作就是控制下鼠标,看下官方文档就知道怎么写了: PyAutoGUI’s documentation

def click(img_part, imgpart2=None, click2=True):
	# 获取全屏截图
    img = pyautogui.screenshot()  # x,y,w,h
    # 图片格式转换 PIL => 
    img = cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
    # img_whole = cv2.imread('images/whole2.png')
    img_whole = img
    n = detect_logo(img_whole, img_part, 0.7)
    if n is False:
        img_part = imgpart2
        n = detect_logo(img_whole, img_part, 0.7)
    p1, p2 = n[0], n[2]
    x, y = int((p1[0] + p2[0]) / 2), int((p1[1] + p2[1]) / 2)
    # 移动鼠标到logo中心位置
    pyautogui.moveTo(x, y, duration=0.5)
    # 双击或单击
    if click2:
        pyautogui.doubleClick()
    else:
        pyautogui.click(button='left')

注意:

这里的特征匹配要求目标logo中需要有四个及以上的有效特征点,才能构造出单应性矩阵。这对logo形状的复杂程度就有所要求。
在这里插入图片描述

原文链接:https://blog.csdn.net/qq_44019424/article/details/107522683

0

1

2

3

4

5



所属网站分类: 技术文章 > 博客

作者:天青色等烟雨

链接: https://www.pythonheidong.com/blog/article/463904/36e40a585fe00872ad0d/

来源: python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

3 0
收藏该文
已收藏

评论内容:(最多支持255个字符)