YouQu使用手册【元素定位】
元素定位
文章目录
- 前言
- 一、气泡识别
- 二、不依赖OpenCV的图像识别方案
- 三、动态图像识别
- 四、背景
- 五、sniff(嗅探器)使用
- 六、元素操作
- 七、框架封装
- 八、背景【OCR识别】
- 九、实现原理
- 十、使用说明
- 十一、RPC服务端部署
- 十二、负载均衡
- 十三、链式调用
- 十四、背景【相对坐标定位】
- 十五、实现原理
- 十六、使用方法
- 十七、现有右键菜单定位的方案及问题【去干扰识别】
- 十八、去干扰识别


前言
图像识别在 UI 自动化中是不可缺少的,市面上甚至有完全基于图像识别的自动化测试框架,比如 Airtest、Sikuli 等,在游戏等特定领域也有不错的效果,这些工具实际上也是用的 OpenCV 进行了封装,YouQu 框架基于 OpenCV 开发了自己的图像识别功能,它可以方便的用于界面元素的定位和断言;
YouQu 的图像识别功能几乎满足了你的所有要求,我们在长时间的思考和摸索中,针对常规场景及一些特殊场景探索出了一些实用且有效的方案,且听我慢慢道来。
常规识别
【背景】
常规识别很好理解,一句话讲就是,要获取到目标元素在屏幕中的位置。
【原理实现】
在测试过程中需要获取的坐标是相对于整个屏幕的坐标,我们可以截取到整个屏幕的图片(screen);
在元素识别的过程中,我们需要截取某个元素的小图进行识别,比如截取播放按钮:

那么实际上,元素定位的问题就转换为,将截图的小图(play_btn)拿到整个屏幕的大图(screen)中去做匹配,如果匹配成功,返回小图在大图中的坐标( x, y )即可。
为了方便描述,以下我将整个屏幕的截图称为:大图,某个元素图片的截图称为:小图。
基于 OpenCV 的模板匹配 cv.matchTemplate() 功能,我们实现了图像定位的功能,框架提供了一个图像识别的底层接口(一般不对上层提供调用):
def _match_image_by_opencv(image_path: str, rate: float = None, multiple: bool = False, picture_abspath: str = None, screen_bbox: List[int] = None
):"""图像识别,匹配小图在屏幕中的坐标 x, y:param image_path: 图像识别目标文件的存放路径:param rate: 匹配度:param multiple: 是否返回匹配到的多个目标:param picture_abspath: 大图,默认大图是截取屏幕,否则使用传入的图片;:param screen_bbox: 截取屏幕上指定区域图片(仅支持X11下使用);[x, y, w, h]x: 左上角横坐标;y: 左上角纵坐标;w: 宽度;h: 高度;根据匹配度返回坐标"""# 详细代码太长不贴了,感兴趣请查看源码
【参数介绍】
(1)image_path
image_path 是小图的绝对路径;
-
通常在 AT 工程里面,我们约定将用于元素定位的图片资源放到 widget/pic_res 目录下,图片的名称以实际的元素名称命名,如:play_btn.png ;
-
用于用例断言的图片资源放到 case/assert_res 目录下,图片的名称以用例的名称命名,如:music_001.png ;
这样是为了方便管理和维护。
(2)rate
图像识别的的匹配度或者说相似度,框架默认的配置为 0.9,也就是说小图在大图中存在一个相似度 90% 的图标即返回其在大图中的坐标;
如果你在用例中需要调整识别度,你可以在调用函数的时候,传入不同的识别度的值。
(3)multiple
默认情况下 multiple=False,表示只返回识别到的第一个,如果 multiple=True 返回匹配到的多个目标,因为大图中可能存在多个相同的小图,在某些场景下你可能需要全部获取到所有匹配到的坐标。
(4)picture_abspath
默认情况下 picture_abspath=None 表示大图为截取的屏幕截图,如果你不希望大图是屏幕的截图,而是你自定义传入的某个图片,你只需要将你的图片路径传递给这个参数就行,比如: picture_abspath=“~/Desktop/big.png” ;
(5)screen_bbox
大图默认情况下是截取整个屏幕,screen_bbox = [x, y, w, h] 可以指定截取屏幕中的固定区域,某些场景下,可以排除部分区域对识别结果的影响。
【隐式等待】
用例执行过程中进行图像识别时,有时候页面跳转有延时,有可能存在识别的那一刻页面也没有跳转出来,或者或者识别的那一刻;
因此我们需要一种等待机制,即在一定的时间内,如果识别不到,重复去识别:
def find_image(cls,*widget, rate: [float, int] = None,multiple: bool = False,match_number: int = None,picture_abspath: str = None,screen_bbox: List[int] = None
):"""在屏幕中区寻找小图,返回坐标,如果找不到,根据配置重试次数,每次间隔1秒:param widget: 模板图片路径:param rate: 相似度:param multiple: 是否返回匹配到的多个目标:param match_number: 图像识别重试次数:return: 坐标元组"""if rate is None:rate = float(GlobalConfig.IMAGE_RATE)try:for element in widget:for _ in range((match_number or int(GlobalConfig.IMAGE_MATCH_NUMBER)) + 1):locate = cls._match_image_by_opencv(element,rate,multiple=multiple,picture_abspath=picture_abspath,screen_bbox=screen_bbox)if not locate:sleep(int(GlobalConfig.IMAGE_MATCH_WAIT_TIME))else:return locateraise TemplateElementNotFound(*widget)except Exception as e:raise e
参数 match_number 用于控制重复识别的次数,默认不传参,取全局配置 setting/globalconfig.ini 里面的 IMAGE_MATCH_NUMBER 配置项的值,默认IMAGE_MATCH_NUMBER = 1,即重试 1 次;
find_image 是框架提供的常规图像识别函数接口,这个函数提供了隐式等待的功能,且包含上面介绍的 _match_image_by_opencv 函数的所有功能。
一、气泡识别
【背景】
气泡识别指的是,某些场景下要定位的元素是一些会消失的小弹窗,这类场景在用例执行过程中进行图像识别时就可能存在不稳定性,有可能图像识别的时候气泡已经消失了,也有可能气泡出现的时间太短了,不容易捕捉到,就像气泡一样,出现一下就消失,因此我们形象的称之为 “气泡识别”;

【原理实现】
为了能稳定的识别气泡类场景,我们采用的方案是:
在一段时间内(包含气泡从出现到消失),不停的截取这段时间内的大图,以此确保在截取的一堆图片中,肯定有至少一张图片能捕捉到气泡,最后再对这一堆图片逐个进行图像识别;

代码示例:
def get_during(cls,image_path: str,screen_time: [float, int],rate: float = None,pause: [int, float] = None,max_range: int = 10000
):"""在一段时间内截图多张图片进行识别,其中有一张图片识别成功即返回结果;适用于气泡类的断言,比如气泡在1秒内消失,如果用常规的图像识别则有可能无法识别到;:param image_path: 要识别的模板图片;:param screen_time: 截取屏幕图片的时间,单位秒;:param rate: 识别率;:param pause: 截取屏幕图片的间隔时间,默认不间隔;:param max_range: 截图的最大次数,这是一个预设值,一般情况下不涉及修改;"""
【参数介绍】
(1)screen_time
截取屏幕图片的时间,在此时间内会不断的进行截图操作,就像录制视频一样;
(2)pause
每次截取图片的间隔时间,默认情况下是一刻不停的截图,如果你想每次截图存在一些间隔时间传入对应的时间间隔即可,单位是秒,比如:pause = 0.03,表示 30 ms,相当于帧率为 30 帧;
二、不依赖OpenCV的图像识别方案
- 自研图像识别技术
【原理】
为了实现识别图像的目的,我们可以通过将图片的每个像素的RGB值,与整个屏幕中的RGB进行对比,如果小图上的RGB值与对应大图位置的RGB都相等,则匹配成功,即可返回小图在大图中的中心坐标点。

读取小图和大图的RGB值
(1)小图的RGB值
small_data = small_pic.load()
# load()会将图片的RGB值获取到,数据格式为一个二维列表,赋值给一个变量small_data。
(2)大图的RGB值
big_data = big_pic.load()
将小图与大图的RGB值进行匹配
(1)匹配从大图的坐标(0,0)开始匹配,匹配小图里面所有的坐标点(
相关文章:
YouQu使用手册【元素定位】
元素定位 文章目录 前言一、气泡识别二、不依赖OpenCV的图像识别方案三、动态图像识别四、背景五、sniff(嗅探器)使用六、元素操作七、框架封装八、背景【OCR识别】九、实现原理十、使用说明十一、RPC服务端部署十二、负载均衡十三、链式调用十四、背景【相对坐标定位】十五、…...
Spark RDD sortBy算子什么情况会触发shuffle
在 Spark 的 RDD 中,sortBy 是一个排序算子,虽然它在某些场景下可能看起来是分区内排序,但实际上在需要全局排序时会触发 Shuffle。这里我们分析其底层逻辑,结合源码和原理来解释为什么会有 Shuffle 的发生。 1. 为什么 sortBy 会…...
机器视觉相机重要名词
机器视觉相机的重要名词包括: • 工业数字相机:又称工业相机,是机器视觉系统中的关键组件。 • 电荷偶合元件(CCD):一种图像传感器,能将光学影像转换为数字信号。 • 互补金属氧化物半导体&…...
Django:从入门到精通
一、Django背景 Django是一个由Python编写的高级Web应用框架,以其简洁性、安全性和高效性而闻名。Django最初由Adrian Holovaty和Simon Willison于2003年开发,旨在简化Web应用的开发过程。作为一个开放源代码项目,Django迅速吸引了大量的开发…...
android viewpager2 嵌套 recyclerview 手势冲突
老规矩直接上代码, 不分析: import android.content.Context import android.util.AttributeSet import android.view.MotionEvent import android.view.View import android.view.ViewConfiguration import android.view.ViewGroup import android.widg…...
依赖管理(go mod)
目录 各版本依赖管理的时间分布 一、GOPATH 1. GOROOT是什么 定义: 作用: 默认值: 是否需要手动设置: 查看当前的 GOROOT: 2. GOPATH:工作区目录 定义: 作用:…...
Apple Vision Pro开发001-开发配置
一、Vision Pro开发硬件和软件要求 硬件要求软件要求 1、Apple Silicon Mac(M系列芯片的Mac电脑) 2、Apple vision pro-真机调试 XCode15.2及以上,调试开发和打包发布Unity开发者账号&&苹果开发者账号 二 、开启无线调试 1、Apple Vision Pro和Mac连接同…...
android 动画原理分析
一 android 动画分为app内的view动画和系统动画 基本原理都是监听Choreographer的doframe回调 二 app端的实现是主要通过AnimationUtils来实现具体属性的变化通过invilate来驱动 wms来进行更新。这个流程是在app进程完成 这里不是我分析的重点 直接来看下系统动画里面的本地动…...
Elasticsearch 6.8 分析器
在 Elasticsearch 中,分析器(Analyzer)是文本分析过程中的一个关键组件,它负责将原始文本转换为一组词汇单元(tokens)。 分析器由三个主要部分组成:分词器(Tokenizer)、…...
实验室资源调度系统:基于Spring Boot的创新
2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统,它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等,非常…...
实验三:构建园区网(静态路由)
目录 一、实验简介 二、实验目的 三、实验需求 四、实验拓扑 五、实验任务及要求 1、任务 1:完成网络部署 2、任务 2:设计全网 IP 地址 3、任务 3:实现全网各主机之间的互访 六、实验步骤 1、在 eNSP 中部署网络 2、配置各主机 IP …...
3. SQL优化
SQL性能优化 在日常开发中,MySQL性能优化是一项必不可少的技能。本文以具体案例为主线,结合实际问题,探讨如何优化插入、排序、分组、分页、计数和更新等操作,帮助你实现数据库性能的飞跃。 一、索引设计原则 索引是MySQL优化的…...
web——upload-labs——第十一关——黑名单验证,双写绕过
还是查看源码, $file_name str_ireplace($deny_ext,"", $file_name); 该语句的作用是:从 $file_name 中去除所有出现在 $deny_ext 数组中的元素,替换为空字符串(即删除这些元素)。str_ireplace() 在处理时…...
AWS CLI
一、AWS CLI介绍 1、简介 AWS CLI(Amazon Web Services Command Line Interface)是一个命令行工具,它允许用户通过命令行与 Amazon Web Services(AWS)的各种云服务进行交互和管理。使用 AWS CLI,用户可以直接在终端或命令行界面中执行命令来配置、管理和自动化AWS资源,…...
springboot:责任链模式实现多级校验
责任链模式是将链中的每一个节点看作是一个对象,每个节点处理的请求不同,且内部自动维护一个下一节点对象。 当一个请求从链式的首段发出时,会沿着链的路径依此传递给每一个节点对象,直至有对象处理这个请求为止。 属于行为型模式…...
CentO7安装单节点Redis服务
本文目录 一、Redis安装与配置1.1 安装redis依赖1.2 上传压缩包并解压1.3 编译安装1.4 修改配置并启动1、复制配置文件2、修改配置文件3、启动Redis服务4、停止redis服务 1.5 redis连接使用1、 命令行客户端2、 图形界面客户端 一、Redis安装与配置 1.1 安装redis依赖 Redis是…...
FreeRTOS学习14——时间管理
时间管理 时间管理FreeRTOS 系统时钟节拍FreeRTOS 系统时钟节拍简介FreeRTOS 系统时钟节拍处理FreeRTOS 系统时钟节拍来源 FreeRTOS 任务延时函数vTaskDelay()vTaskDelayUntil() 时间管理 在前面的章节实验例程中,频繁地使用了 FreeRTOS 提供的延时函数,…...
统⼀数据返回格式快速⼊⻔
为什么会有统⼀数据返回? 其实统一数据返回是运用了AOP(对某一类事情的集中处理)的思维。 优点: 1.⽅便前端程序员更好的接收和解析后端数据接⼝返回的数据。 2.降低前端程序员和后端程序员的沟通成本,因为所有接⼝都…...
Python学习------第十天
数据容器-----元组 定义格式,特点,相关操作 元组一旦定义,就无法修改 元组内只有一个数据,后面必须加逗号 """ #元组 (1,"hello",True) #定义元组 t1 (1,"hello") t2 () t3 tuple() prin…...
Win11 24H2新BUG或影响30%CPU性能,修复方法在这里
原文转载修改自(更多互联网新闻/搞机小知识): 一招提升Win11 24H2 CPU 30%性能,小BUG大影响 就在刚刚,小江在网上冲浪的时候突然发现了这么一则帖子,标题如下:基准测试(特别是 Time…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
WebRTC调研
WebRTC是什么,为什么,如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...
深入理解 React 样式方案
React 的样式方案较多,在应用开发初期,开发者需要根据项目业务具体情况选择对应样式方案。React 样式方案主要有: 1. 内联样式 2. module css 3. css in js 4. tailwind css 这些方案中,均有各自的优势和缺点。 1. 方案优劣势 1. 内联样式: 简单直观,适合动态样式和…...
十二、【ESP32全栈开发指南: IDF开发环境下cJSON使用】
一、JSON简介 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,具有以下核心特性: 完全独立于编程语言的文本格式易于人阅读和编写易于机器解析和生成基于ECMAScript标准子集 1.1 JSON语法规则 {"name"…...
