检测策略
当您的宏不再局限于简单的点击操作时,影响可靠性的最大因素往往不是点击本身,而是您如何检测目标。高级宏只有在为其所自动化的界面选择了正确的检测策略时,才能发挥最佳效果。
从最简单可靠的信号开始
在调整设置之前,请先选择最稳定的信号:
- 仅当目标位置永远不变时才使用固定坐标
- 当视觉形状稳定且独特时使用图像检测
- 当标签比图标更容易识别时使用文本检测
- 当您已经大致知道目标可能出现的位置时,使用更小的
Region()
如果多种策略都可行,请优先选择搜索区域最小、歧义最少的那一种。
Screen 与 Region
最常见的性能误区是对所有内容都进行全屏搜索。
在以下情况使用 Screen:
- 目标几乎可能出现在任何位置
- 您正在构建宏的第一个版本
- 您正在探索新的应用流程
在以下情况使用 Region:
- 目标总是出现在界面中已知的某个区域
- 屏幕上存在重复的图标或重复的文本
- 您希望获得更快、更稳定的匹配
local actionArea = Region(900, 1600, 1080, 2200)
actionArea:click("continue-button.jpg")
拟合区域(Fit Region)技巧
最实用的高级技巧之一就是所谓的 fit region(拟合区域)。
其思路是:
- 先使用
Screen:find()找到对象一次 - 使用
result:getRegion()将该匹配结果转换为拟合的Region - 如果对象尺寸保持稳定,则复用该拟合区域进行后续搜索
这在以下情况非常有效:
- 对象始终具有相同的宽度和高度
- 对象的内容可能会变化,但其容器区域保持一致
- 全屏搜索开销很大且需要频繁执行
local result = Screen:find("inventory-panel.jpg")
if result then
local fitRegion = result:getRegion()
local collectButton = fitRegion:find("collect-button.jpg")
if collectButton then
fitRegion:click("collect-button.jpg")
end
end
为什么这种方法很强大:
- 第一次全屏搜索是开销最大的步骤
- 一旦找到对象,后续所有搜索都限制在拟合的边界内
- 这可以在重复流程中显著降低 OCR 和图像匹配的开销
在以下情况使用拟合区域:
- 您有一个稳定的面板、卡片、弹窗、槽位或容器
- 宏需要反复在同一个匹配对象内部进行交互
- 同一个对象出现在不同位置但尺寸保持不变
在以下情况避免使用拟合区域:
- 对象在不同屏幕或设备之间尺寸变化较大
- 目标区域会动态展开或收起
- 第一次匹配过于宽泛,可能会绑定到错误的容器
实践中,拟合区域是将缓慢的 Screen 宏转换为快速的 Region 宏(而无需硬编码坐标)的最佳方式之一。
图像检测与文本检测
优先使用图像检测的情况:
- 目标主要是图形化的
- 界面语言可能会变化
- 文本是经过样式化处理或渲染在按钮内部的
- 由于文本过小或对比度过低,OCR 难以识别
优先使用文本检测的情况:
- 标签位置会变化但措辞保持不变
- 同一个视觉组件出现在多种主题或状态中
- 按钮形状会变化但标签仍然可读
- 您需要匹配应用动态生成的文本
逐词与逐行 OCR
使用文本检测时,检测方法很重要:
- 对于单个单词或非常短的标签,使用
setDetectionMethod(1) - 当目标是短语或整行文本时,使用
setDetectionMethod(2)
Screen:click("Login", ClickParams():setDetectionType("TEXT"):setDetectionMethod(1))
Screen:wait("Your session has expired", 5000, FinderParams():setDetectionType("TEXT"):setDetectionMethod(2))
逐步调整匹配分数
匹配分数过高会导致漏检。分数过低会导致误检。
一个实用的调整流程:
- 从默认分数开始
- 如果目标被漏检,则稍微降低分数
- 如果匹配到了错误的对象,则稍微提高分数
- 如果两种情况都出现,请先缩小搜索区域,再进一步调整分数
在大多数情况下,通过 Region() 减少歧义比过度激进地调整匹配分数更安全。
仅在有帮助时使用灰度
灰度可以提高速度,有时也能提升一致性,但它并非总是更好。
在以下情况使用灰度:
- 目标更多由形状而非颜色定义
- 光线或色彩偏移导致匹配不稳定
- 您希望在低端设备上获得更快的匹配速度
在以下情况避免依赖灰度:
- 颜色是相似目标之间的主要区别
- 您试图通过颜色区分激活和非激活状态
动态缩放
如果同一个宏要在不同分辨率的设备上运行,动态缩放可以帮助图像检测保持可用性。
在以下情况使用动态缩放:
- 模板是在一台设备上截取的,但却在另一台设备上执行
- 同一个应用布局在不同手机或平板上会被重新缩放
但如果界面在单台设备上已经高度一致,那么一个裁剪得当的模板加上一个合适的区域,通常比过度调整缩放更稳定。
大胆裁剪模板
一个好的模板应该只包含使目标独一无二的部分。
好的模板:
- 图标本身
- 独特的标签区域
- 最小且稳定的视觉模式
不好的模板:
- 大片的周围空白
- 会动的背景
- 每次运行都会变化的内容
- 不属于目标的相邻元素
对难以处理的屏幕使用两步检测
当屏幕噪声较多时,请采用分阶段的方法:
- 等待一个稳定的锚点元素
- 缩小搜索区域
- 在该区域内检测最终目标
Screen:wait("settings-title.jpg", 5000)
local footerArea = Region(0, 1700, 1080, 2400)
footerArea:click("save-button.jpg")
推荐模式
对于高级宏,这通常是最安全的顺序:
- 等待稳定状态
- 限制搜索区域
- 有意识地选择图像或文本检测
- 在减少歧义后再调整分数
- 在继续之前验证结果