利用Python开发图像识别测试框架(三)
作者:强哥   类别:Python开发    日期:2019-07-31 16:47:57    阅读:2615 次   消耗积分:0 分

本次分享《利用Python开发图像识别测试框架》实验教材中模板匹配的代码实现。

回顾前期内容请点击

教材连载:利用Python开发图像识别测试框架(一)

教材连载:利用Python开发图像识别测试框架(二)


由于Python的默认库中并没有带有专门处理图像的程序,所以我们需要下载Pillow库来专门进行图像处理。使用“pip install pillow”下载并完成库的安装。然后使用如下代码完成模板匹配功能。


from PIL import Image, ImageGrab
import os 
class ImageMatch:
    def __init__(self):
        self.screen = None  # 定义全屏大图对象
        self.target = None  # 定义模板图片对象
        self.screendata = None  # 定义全屏大图数据用于存储像素数据
        self.targetdata = None  # 定义模板小图数据用于存储像素数据
    # 定义一个简单的对比,由于匹配过程中的判断t1, t2的参数代码每个像素点的RGBA值
    def compare(self, t1, t2):
        if t1[0]==t2[0] and t1[1]==t2[1] and t1[2]==t2[2] and t1[3]==t2[3]:
            return True
        else:
            return False
    # 模板匹配的核心程序
    def find_image(self, image_name):
        image_dir = os.path.abspath('.') + "\\source\\"     # 定义图像的默认目录
        # 截取当前屏幕图像并加上Alpha通道数据
        self.screen = ImageGrab.grab().convert("RGBA")      
        self.target = Image.open(image_dir + image_name)    # 打开模板图像
       screenwidth, screenheight = self.screen.size        # 得到大图的宽和高
        targetwidth, targetheight = self.target.size        # 得到小图的宽和高
        self.screendata = self.screen.load()    #加载大图像素数据
        self.targetdata = self.target.load()    #加载小图像素数据
        posx, posy = -1, -1         # 定义目标位置,默认为-1,-1,表示没有找到元素
        # 遍历每一个像素点,注意不需要遍历到screenheight或者screenwidth这么多
        # 需要减少掉小图的宽和高,否则小图就会滑动到大图之外,没有任何意义,并且还会越界
        for y in range(0, screenheight-targetheight):
            for x in range(0, screenwidth-targetwidth):
                # 比较小图的5个顶点与大图的对应区域的5个像素点是否匹配,
                # 匹配才遍历小图的每一个点,不匹配可以直接跳过,滑动到下一个像素点。
                if (self.compare(self.screendata[x, y], self.targetdata[0, 0])   

and   #左上角
                    self.compare(self.screendata[x + targetwidth-1, y],

self.targetdata[targetwidth-1, 0]) and      # 右上角
                    self.compare(self.screendata[x, y + targetheight - 1],

self.targetdata[0, targetheight - 1]) and    # 左下角
                    self.compare(self.screendata[x + targetwidth - 1, y + targetheight - 1], self.targetdata[targetwidth - 1, targetheight - 1]) and  # 右下角
                    self.compare(self.screendata[x + targetwidth / 2, y + targetheight / 2], self.targetdata[targetwidth / 2, targetheight / 2]) # 中心点):
                    is_matched = self.check_match(x, y)
                    if is_matched:

# 计算得到模板图片中心点位置的精确坐标
                        posx, posy = x + int(targetwidth / 2),

y + int(targetheight / 2)
        return (posx, posy)
    # 针对模板图片的全像素匹配,看是否能够成功匹配(此处暂时不考虑匹配度,即100%匹配)
    def check_match(self, x, y):
        targetwidth, targetheight = self.target.size
        for smally in range(0, targetheight):
            for smallx in range(0, targetwidth):
                if not self.compare(self.screendata[x+smallx, y+smally],

self.targetdata[smallx, smally]):
                    return False
        return True
    # 判断是否匹配到一个成功的元素(用于测试断言)
    def check_exist(self, imagepath):
        result = self.find_image(imagepath)
        if (result[0] == -1 and result[1] == -1):
            return False
        else:
            return True



上述代码严格实现了前一节内容当中的算法。但是并没有考虑匹配度的问题。不过只要界面风格,色彩没有发生变化,目前的上述脚本已经可以正常识别且唯一定位到一个元素的坐标位置。当然,我们也可以利用像素点的占比进行一个相对简单的匹配度算法实现,重构check_match方法如下:


# 通过传递参数similarity来定义一个0~1之间的匹配度,默认设置为1,表示完全匹配

def check_match(self, x, y, similarity=1):
    targetwidth, targetheight = self.target.size
    total_count = targetheight*targetwidth
    not_matched_count = 0
    for smally in range(0, targetheight):
        for smallx in range(0, targetwidth):
            if not self.compare(self.screendata[x+smallx, y+smally], self.targetdata[smallx, smally]):
                not_matched_count += 1
    if not_matched_count / total_count <= 1-similarity:
        return True
    else:
        return False

 

下面我们来对上述代码进行简单的测试,假设全屏截图如下:



20190731_162649_423.png


再截取当中的模板图片“确认”按钮如下并保存到指定的目录中,命名为“confirm.png”:

测试代码如下所示:


im = ImageMatch()
time.sleep(3)
x,y = im.find_image("confirm.png")
print(x,y)


最后运行成功将打印出当前确认按钮在屏幕中的准确位置。当然,针对某些特定情况有可能5个顶点的算法对查找过程依然会显得比较漫长,那么我们可以继续增加新的特征点用于第一次匹配。比如增加如下一些点(根据宽和高的坐标比例计算点的位置即可):


20190731_162739_806.png


下期推送:实现自动化测试框架


为了答谢大家对蜗牛学院的支持,蜗牛学院将会定期对大家免费发放干货,敬请关注蜗牛学院的官方微信。


20190320_095757_834.jpg


   
版权所有,转载本站文章请注明出处:蜗牛笔记, http://www.woniunote.com/article/346
上一篇: 软件工程师的面试指导,助你拿高薪!
下一篇: 转行7个月,月薪4K到16K,他说“仍需努力”!
提示:登录后添加有效评论可享受积分哦!
最新文章
    最多阅读
      特别推荐
      回到顶部