上期回顾:手机UI自动化之显示点触位置(触摸轨迹)
以下基于 python3.8;airtestIDE1.2.10;airtest1.2.0;pocoui1.0.82
今天我们讲一下airtest图像识别中的一个最基本、最常用的一个类Template
首先我们先看一个非常简单的脚本示例,在AirtestIDE中,显示如图:
在编辑器中点击鼠标右键菜单的‘图片/代码模式切换’,切换到代码模式,可以看到每一张图就是一个Template()类实例。
所以本质上airtest脚本还是python代码,只不过在AirtestIDE中经过特殊处理,显示成了所见即所得的图片模式。
比如下面这句,运行时会先去读取这张图片,然后在当前画面中找到最符合这张图片的坐标点,通过touch点击返回的坐标点。
touch(Template(r"tpl1630325470097.png", record_pos=(0.02, -0.071), resolution=(2400, 1080)))
在开始讲解Template类详细使用之前,先看一下其初始化源码:
# 文件位置:your_python_path/site-packages/airtest/core/cv.py
class Template(object):
"""
picture as touch/swipe/wait/exists target and extra info for cv match
filename: pic filename
target_pos: ret which pos in the pic
record_pos: pos in screen when recording
resolution: screen resolution when recording
rgb: 识别结果是否使用rgb三通道进行校验.
scale_max: 多尺度模板匹配最大范围.
scale_step: 多尺度模板匹配搜索步长.
"""
def __init__(self, filename, threshold=None, target_pos=TargetPos.MID, record_pos=None, resolution=(), rgb=False, scale_max=800, scale_step=0.005):
self.filename = filename
self._filepath = None
self.threshold = threshold or ST.THRESHOLD
self.target_pos = target_pos
self.record_pos = record_pos
self.resolution = resolution
self.rgb = rgb
self.scale_max = scale_max
self.scale_step = scale_step
根据上面的例子可以看到,在AirtestIDE中截的图,默认会带3个参数:
-
filename:文件路径。如上例中r"tpl1630325470097.png"表示当前路径下的这张图片,也可以是绝对路径,如r'/picture/1.png'
-
record_pos:图片坐标对应手机屏幕中心点的偏移值相对于手机分辨率的百分比,匹配时会优先匹配这附近的画面。这样Airtest在图像匹配时,会优化在这个坐标区域附件查找,提高查找图片的速度和精确度。如果在这个区域找不到,才会将查找范围扩大至整个画面。
-
resolution:手机分辨率。当脚本执行时的手机不是录制时的手机时,Airtest会对屏幕截图按照分辨率进行缩放,最大程度兼容跨分辨率匹配。但如果不同手机的分辨率比例相差大,仍会导致匹配不到图片,所以可能同一张图,不同手机需要准备2张或以上的图片做为查找图片。
以下为一个图片,多个不同分辨率手机截图时的查找示例:
flower_xiaomi = Template(r"flower_xiaomi.png", record_pos=(0.79, 0.32), resolution=(1024, 2000))
flower_huawei = Template(r"flower_huawei.png", record_pos=(0.81, 0.4), resolution=(800, 1600))
pic_list = [flower_xiaomi,flower_huawei]
for pic in pic_list:
pos = exists(pic) # 图片找到返回坐标,没找到返回False
if pos:
touch(pos)
break # 只要找到图片列表中的任何一张图片,就执行touch,并结束循环
除了上边3个默认的参数,我们看到源码中还有其他参数:
-
threshold:识别阈值,浮点类型,范围是[0.0, 1.0],默认0.7。
也就是当识别可信度=>0.7时就认为是匹配的。对于计算机来说,不存在2张完全一样的图片,计算机只能告诉你2张图片的相似程度。比如相似度是0.9(90%)就是比较像,相似度是0.5(50%)就是不太像。计算机只会告诉你相似度,那这2张图算不算匹配,是由人通过阈值决定的。比如我们说只要相似度70%以上,就算是一样的。
我们可以指定某个图片的阈值,如
touch(Template(r"tpl1556019871196.png", threshold=0.9))
但假如我们想让所有图片的阈值都是0.9,可以通过全局设置:
from airtest.core.api import *
# airtest.core.api中包含了一个名为ST的变量,即为全局设置
ST.THRESHOLD = 0.9 # 设置全局的匹配阈值为0.9
# 未写明图片threshold,使用上面全局的ST.THRESHOLD=0.9
touch(Template(r"1.png", record_pos=(0.79, 0.32), resolution=(107, 1164)))
# 指定图片threshold,以图片设置的0.6为准
touch(Template(r"2.png", record_pos=(0.79, 0.32), resolution=(107, 1164), threshold=0.6))
根据经验,默认的0.7是比较合理的能用的,大家可以根据自己的实际情况进行调节,总结出一个适合自己的阈值。
-
target_pos:图片点击位置,整型,默认为5,即图片的中心点。
在上面Template初始化源码中,target_pos的默认值是TargetPos.MID,我们去TargetPos类定义中可知,MID就是5
文件位置:your_python_path/site-packages/airtest/utils/transform.py
class TargetPos(object):
"""
点击目标图片的不同位置,默认为中心点5
1 2 3
4 5 6
7 8 9
"""
LEFTUP, UP, RIGHTUP = 1, 2, 3
LEFT, MID, RIGHT = 4, 5, 6
LEFTDOWN, DOWN, RIGHTDOWN = 7, 8, 9
从以上代码,可以看出点击位置的取值范围是1~9,这9个点对应下图
上图中红线圈起来的就是我们要找的图,找到图后要点击,默认是点5那个点,如果我们想点图中的升级按钮,那应该设置成8
touch(Template(r"1.png", target_pos=8))
再举一个例子,我们要点击图中的玩吧的安装按钮
我们可以这样截图
因为默认是5,不用改,如果想安装第1个app,设target_pos=2;如果想安装第3个app,设target_pos=8
-
rgb:是否开启彩色识别,Bool类型,默认False。
rgb=False时,Airtest会先将图像转为灰度图再进行识别;为True时,指定使用彩色图像进行识别。一般情况下,我们都用默认的False即可,但假如画面上有多个形状相同颜色不同图片时,就要设为True。
如上图,删除按钮形状、文字完全一样,如果不开rgb,是不会准确识别到红色按钮的。 -
scale_max:Airtest1.2.0新增图像识别算法mstpl专用参数,用于调节匹配的最大范围,默认值 800, 推荐值 740, 800, 1000 取值范围 [700 , 2000]。比如截屏为(500,2000),scale_max=1000,则在匹配前截屏会resize为(250,1000)。resize后图片大小少了一倍,理论上匹配速度也会变快,但因为缩小后,更不容易匹配较小的UI,所以如果要查找的目标UI很小的话,可以适当增大这个数值。
-
scale_step:Airtest1.2.0新增图像识别算法mstpl专用参数,用于控制搜索比例步长,在匹配时,会以截图最长边*scale_step的步长进行搜索,默认值0.005,推荐值 0.02, 0.005, 0.001 取值范围 [0.001, 0.1]。如果要查找的目标UI很小的话,可以适当减小这个数值(通常不需要调整该值,但如果有跨分辨率匹配失败,可以尝试减少,相应的匹配时间则会大大增加)
以上所有这些参数的修改、调试,在AirtestIDE中都可以通过‘图片编辑器’从UI界面上修改,可以看之前的文章:AirtestIDE高级功能
---------------------------------------------------------------------------------
关注微信公众号即可在手机上查阅,并可接收更多测试分享~