Airtest图像识别

Airtest是一款网易出品的基于图像识别面向手游UI测试的工具,也支持原生Android App基于元素识别的UI自动化测试。主要包含了三部分:Airtest IDE、Airtest(用截图写脚本)和 Poco(用界面UI元素来写脚本)。来自Google的评价:Airtest 是安卓游戏开发最强大、最全面的自动测试方案之一。

图示为AirtestIDE中脚本运行范例

本文重点是针对Airtest中的图像识别进行代码走读,加深对图像识别原理的理解(公众号贴出的代码显示不全仅供参考,详细代码可以在github查看)。

一、准备工作

下载好源码:

https://github.com/AirtestProject/Airtest导入IDE,我这里用的是Pycharm。

二、我们从图示中touch方法入手

如图示所示,从touch图片开始,即为点击某个传入的图片,源码在api.py里面:

这个函数执行点击操作的是 G.DEVICE.touch(pos, **kwargs),而pos就是图片匹配返回的坐标位置,重点看loop_find这个函数是怎样识别并返回坐标数据的:

解读下这个loop_find这个方法:

1、首先会获取手机屏幕截图;

2、然后对比脚本传入图片获取匹配上的位置;

3、一直重复上面两步骤直到匹配上或者超时。

跟脚本传入图片进行匹配的代码在这一行 match_pos = query.match_in(screen)

在cv.py 里面找到 Template类的 match_in方法:

解读下 match_in方法:

1、调用自己的_cv_math方法,找到匹配到的坐标结果;

2、根据图片坐标返回点击坐标,默认点击图片中心位置。

接下来看 self._cv_match(screen) 也在cv.py 里面:

解读下_cv_match代码:

1、将用例传入的截图进行缩放(写用例设备与运行用例设备可能不一致);

2、遍历配置项里面的方法,进行匹配,如果是 tpl 则执行_find_template;

如果是sift,先执行_find_sift_in_predict_area 如果还没结果就再执行_find_sift。

这里的可以在settings.py 里面找到默认的定义:

CVSTRATEGY = ["tpl", "sift"]

如果某个方法匹配上了,就返回匹配结果,而_find_sift_in_predict_area 也会调用到 _find_sift,通过方法名可以理解,前者就是在指定区域进行_find_sift。所以我们接下来看cv.py 中的_find_template 和 _find_sift方法:

三、重点分析 aircv.find_template

aircv.find_template 具体实现在 template.py:

概括来说aircv.find_template 主要做了这几件事情:

1、校验图像输入;

2、计算模板匹配的结果矩阵res;

3、依次获取匹配结果;

4、求取可信度;

5、求取识别位置。

confidence 可信度可以简单理解为相似度,这里默认的阈值是threshold=0.8 如果匹配的结果大于这个0.8就把最佳匹配的坐标返回,否则认为没有匹配上返回None,在写脚本的时候可以传入threshold这个参数来提高或降低匹配精度。best_match 就是最佳匹配的坐标,重点看 _get_template_result_matrix是怎样得到匹配结果的:

这里可以看到,Airtest也没有自研一套很牛的图像识别算法,直接用的OpenCV的模板匹配方法。

四、接着看另外一个方法 aircv.find_sift

定义在sift.py里面:

概括来说aircv.find_sift主要做了这几件事情:

1、检验图片是否正常;

2、获取特征点集并匹配出特征点对;

3、根据匹配点对(good),提取出来识别区域;

4、根据识别区域,求出结果可信度。

接下来看如何找到特征点集:

matches = FLANN.knnMatch(des_sch, des_src, k=2) 这就是在对图像的特征点进行匹配,FLANN 是快速最近邻搜索包(Fast_Library_for_Approximate_Nearest_Neighbors)的简称,它是一个对大数据和高维特征进行最近邻搜索算法的集合。至于这个sift是什么对象,就是通过这个对象获取到图像特征点:

可以看到,用到的也是OpenCV的方法,如果是OpenCV3则查找图像特征点集的方法就是:

cv2.xfeatures2d.SIFT_create(edgeThreshold=10).detectAndCompute() 

五、最终用到的就是OpenCV的两个方法:模版匹配和特征匹配

1.模板匹配: 

cv2.matchTemplate(i_gray, s_gray, cv2.TM_CCOEFF_NORMED)

2.特征匹配:

cv2.FlannBasedMatcher(index_params,search_params).knnMatch(des1,des2,k=2)

哪个优先匹配上了,就直接返回结果,可以看到用的都是OpenCV的图像识别算法。

六、总结

1、图像识别,对不能用ui控件定位的地方的,使用图像识别来定位,对一些自定义控件、H5、小程序、游戏,都可以支持; 2、支持多个终端,使用图像识别的话可以一套代码兼容android和ios哦,用ui控件定位的话需要兼容一下; 3、缺点:对于背景透明的按钮控件,或写用例和跑用例设备分辨率相差较大都会造成识别难度加大。

后期我们会根据每个维度陆续写相关的测试文章,如果你有兴趣,请关注我们哦。


长按指纹识别图中的二维码,获取更多测试干货分享!将我们公众号置顶 

 不会漏掉我们的原创干货哦!

原文发布于微信公众号 - 腾讯移动品质中心TMQ(gh_2052d3e8c27d)

原文发表时间:2019-01-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券