一种定位目标图片坐标的图像识别技术交底书
0、缩略语和关键术语定义
缩写 | 全称 | 描述 |
Opencv | Open Source Computer Vision Library | 是一个开源的计算机视觉库。 |
RGB | 红(R)、绿(G)、蓝(B) | RGB即是代表红、绿、蓝三个通道的颜色, 强度值为0~255,比如:白色(0 0 0),黑色(255 255 255) |
Dogtail | Dogtail | 一个使用Accessibility定位Qt应用中元素控件坐标的工具,是一个基于Python的开源三方库。 |
Accessibility | Accessibility | 即辅助功能,在应用中提供Accessibility接口,使得外部软件可以操作相应的功能,技术诞生的初衷是为了让身体残疾的人能使用计算机。 |
1、相关技术背景(背景技术),与本发明最相近似的现有实现方案(现有技术)
元素的定位是自动化测试的核心内容,无论是web自动化测试还是app自动化测试都会存在元素定位不到的问题,此时可以考虑采用图像识别实现,通常采用Opencv提供的模板匹配技术,通过对比目标小图和屏幕大图,即可计算出小图在屏幕中的位置。
1.1、与本发明相关的现有技术一
1.1.1、现有技术一的技术方案
基于Accessibility对Qt应用的元素控件添加ObjectName,使用Dogtail工具提供的方法去定位元素控件。
1.1.2、现有技术一的缺点
(1)定位速度慢,对于元素控件继承的层级太多,在树形结构里面层级就会很深,Dogtail寻找元素的时候会去遍历树形结构里面所有的东西,导致元素定位速度慢。
(2)Dogtail工具本身存在不稳定性,在寻找元素的时候,存在找不到的情况,比如右键菜单里面的选项,使用Dogtail定位时,返回坐标始终为(0, 0)。
(3)如果应用中某些元素无法添加ObjectName时,只能通过索引的方式去找,不利于自动化测试用例的维护性。
1.2、与本发明相关的现有技术二
1.2.1、现有技术二的技术方案
基于Opencv提供的模板匹配功能,对比目标小图和屏幕大图,计算出在屏幕中的位置。
1.2.2、现有技术二的缺点
(1)使用Opencv的模板匹配函数,需要通过Opencv提供的imread函数读取图片,而imread函数只能传入图片的路径,也就是说必须要有目标小图和屏幕大图的本地文件,在自动化测试用例中,目标小图是提前截好的,放到一个固定位置,而屏幕大图是在用例执行的过程中实时截取的,这样就必须要将实时截取的屏幕大图保存为本地文件,这点就会有一些问题。
在AMD平台上由于计算机处理速度相对较快,实时保存图片文件的动作不会有明显的感觉,而在ARM和MIPS平台上计算机处理速度相对较慢,用例执行的过程中,屏幕大图保存的文件相对于要识别的时间点是滞后的,最主要原因就在于要生成本地图片文件。
(2)Opencv在ARM和MIPS上没有对应的官方包,无法使用pip安装Opencv的问题,在搭建自动化测试环境的时候,比较费时间。
2、本发明技术方案的详细阐述
2.1、本发明所要解决的技术问题
(1)在国产化平台UI自动化测试过程中,定位元素控件时不稳定,且速度较慢。
(2)自动化测试操作步骤中,需要准确获取元素控件的坐标。
(3)在UI自动化测试过程中,UI界面变化大,且容易受到环境影响,断言的准确性问题。
2.2、本发明提供的完整技术方案
在自动化测试的过程中,通常将需要识别的按钮或控件区域截取为一个小图,然后在整个屏幕中对小图进行匹配。为了实现识别图像的目的,我们可以通过将图片的每个像素的RGB值,与整个屏幕中的RGB进行对比,如果小图上的RGB值与对应大图位置的RGB都相等,则匹配成功,即可返回小图在大图中的中心坐标点。
图1 图像识别流程图
2.2.1 读取小图和大图的RGB值
(1)小图的RGB值
small_data = small_pic.load() # load()会将图片的RGB值获取到,数据格式为一个二维列表,赋值给一个变量small_data。
(2)大图的RGB值
big_data = big_pic.load()
2.2.2 将小图与大图的RGB值进行匹配
(1)匹配从大图的坐标(0,0)开始匹配,匹配小图里面所有的坐标点(0,0)—(small_pic.width,small_pic.height)
图2 匹配启始位置
(2)如果在大图的(0,0)对应的所有小图的RGB值不相等,则移动到下一个坐标点(1,0),同样匹配小图里面所有的坐标点(0,0)—(small_pic.width,small_pic.height)
图3 逐个像素点移动
(3)按照这样的规律将这一行每移动一个坐标点,都将小图所有的RGB与对应大图的值进行匹配。
图4 移动到一行的最右边
(4)如果在大图的其中一个坐标点上匹配到了小图的所有RGB值,则此时返回小图在大图中的坐标点。
图5 找到在屏幕中的位置
(5)如果匹配了大图所有的坐标点,都没有匹配到,则说明大图中不存在小图,匹配失败。
图6 移动到最右下角都没有找到
2.2.3 关键技术
根据以上的设计思路,代码实现如下:
import pyscreenshot
import random
from PIL import Image
def check_match(x, y, small_pic, big_data, small_data):
'''设置匹配度0.9'''
same = 0
diff = 0
for i in range(small_pic.width):
for j in range(small_pic.height):
if big_data[x + i, y + j] == small_data[i, j]:
same = same + 1
else:
diff = diff + 1
# 设置匹配度0.9
similarity = same / (same + diff)
if similarity >= 0.9:
return True
else:
return False
def random_point(small_pic):
''' 每次随机取10-20个点,并在小图中随机取坐标
'''
point_list = []
count = random.randrange(10, 16)
for i in range(count):
sx = random.randrange(0, small.width)
sy = random.randrange(0, small.height)
point_list.append([sx, sy])
return point_list
def random_match(x, y, point_list, big_data, small_data):
'''在小图中随机取几个点进行匹配,随机点同样设置匹配度0.9'''
same = 0
diff = 0
for point in point_list:
if big_data[x + point[0], y + point[1]] == small_data[point[0], point[1]]:
same = same + 1
else:
diff = diff + 1
if same / (same + diff) >= 0.9:
return True
else:
return False
def match_image(pic_name):
'''通过一张小图,找到对应当前屏幕中的位置'''
# 打开小图和大图,获取RGB值
file_path = "/home/uos/Documents/" + pic_name
small_pic = Image.open(file_path)
samll_data = small_pic.load()
big_pic = pyscreenshot.grab()
big_data = big_pic.load()
point_list = random_point(small_pic)
# 遍历大图和小图的横纵坐标
for x in range(big_pic.width - small_pic.width):
for y in range(big_pic.height - small_pic.height):
# 判断随机点
if random_match(x, y, point_list, big_data, small_data):
# 判断匹配度
if check_match(x, y, small_pic, big_data, small_data):
# 返回中心坐标
return (x + small_pic.width / 2, y + small_pic.height / 2)
return False
通过match_image()这个函数,传入目标小图的文件名称,即可返回在当前屏幕中的中心坐标。
在UI自动化测试项目中,测试用例如果需要通过图像识别去获取目标控件的坐标,只需调用这个函数即可。
2.2.3.1 小图在大图中匹配的逻辑算法
$$ smallRGB[i, j] = bigRGB[x + i, y + j] $$
其中,x是大图的横坐标的遍历的值,y是大图的纵坐标的遍历的值,i是小图的横坐标的遍历的值,j是小图的纵坐标的遍历的值,RGB的取值是在(0, 0 ,0)~(255, 255, 255)之间。
2.2.3.2 快速匹配
在小图中随机选取一些坐标点,如果选取的这些坐标点存在与大图中RGB值不相等的情况,则直接跳出本次匹配,进行大图的下一个坐标点的匹配,如果选取的坐标点都匹配成功,再进行剩余坐标点的匹配,这样可以实现小图在大图中快速匹配的效果,提升图像识别的速度。
2.2.3.3 匹配度
在实际应用中,我们需要对错误匹配的坐标点有一定的容忍度,这里我称为”匹配度“。比如,匹配度为90%,也就是说,只要小图中90%的坐标点的 RGB,与大图中对应位置能匹配上,那么就判定为匹配成功。
同时,我们对随机选取做”预匹配“的几个点也设置一个匹配度,这样可以进一步提升匹配效率。
在实际项目中,我将匹配度设置为90%时,在近三个月的自动化用例执行过程中,每天执行857条用例,没有出现误报的情况。
2.2.3.4 在UI自动化测试中的应用
(1)获取到元素控件的坐标之后,使用 xdotool 或者 pyautogui 等工具,对元素进行点击、双击、拖拽、输入等动作,实现 UI 自动化测试中的操作步骤。
(2)通过判断屏幕中是否存在元素,用于 UI 自动化测试中的断言。
(3)由元素控件的定位及操作,以及在关键步骤的断言,构成了 UI 自动化测试的完整解决方案。
2.3、本发明技术方案带来的有益效果
(1)解决了 UI 自动化测试中,在国产化平台系统资源不足的情况下,快速实现元素控件定位。
(2)降低了自动化测试环境搭建的复杂度,同时减少了自动化测试环境搭建的时间,从而提升测试效率。
(3)在 UI 自动化测试中,能准确对自动化用例执行结果进行断言。
2.4、针对上述技术方案,是否还有替代方案同样能完成发明目的
暂无
3、本发明的技术关键点和欲保护点是什么
(1)将屏幕大图的RGB值保存到内存中,然后通过算法:$smallRGB[i, j] = bigRGB[x + i, y + j]$ 对比目标图片与屏幕大图 RGB
值,从而获取到目标图片在屏幕中的坐标位置。同时,在对比图像的过程中,通过随机选取一些点进行预匹配,提高图像识别的的速度,解决了在图像对比过程中,消耗大量 CPU 资源的问题。通过设置匹配度,提供图像识别的成功率,提高在 UI
自动化测试中使用图像识别的稳定性,同时提升了自动化测试脚本的健壮性和稳定性,解决了在图像识别的过程中,国产化架构平台生成本地图片文件速度慢的问题,实现了在国产化平台上执行UI自动化测试过程中,快速、稳定的定位目标元素控件的效果。
(2)通过获取到元素控件的坐标,再配合使用 xdotool
或者 pyautogui
等工具,控制鼠标和键盘进行操作,从而实现 UI 自动化测试中模拟人工测试的操作步骤的技术方案运用。
(3)通过获取到元素控件的坐标,进而可以判断目标元素是否存在,可用于UI自动化测试中的关键位置的断言方案运用。
4、附件:
参考文献(如专利/论文/标准等)
l random:
n https://docs.python.org/zh-cn/3/library/random.html
l pyscreenshot:
n https://github.com/ponty/pyscreenshot/tree/2.3
l PIL