为什么我的代码中,images.findImage()找不到图片?
我十分确认我加载的图片很小,很精准,在截图中具有独特性,唯一性,干扰少。但是无论threshold为多少都find不到image,而且加载的图片都是有效的,我通过images.save()到指定目录也没有问题,图片正确加载,按照预期。我的问题是images.findImage()函数,似乎没有按照我的期望从大图中找到图片,功能失效?每次都是返回null。但是我记得第一次测试的时候是返回过坐标的,成功过,但是现在我不知道哪里有问题

我的代码如下:
if (!requestScreenCapture()) {
toastLog('没有授予 Hamibot 屏幕截图权限');
hamibot.exit();
}
console.show()
toast("start")

let i = images.read(files.cwd() + "/to_pic.png")
console.log("加载图片完成")
// images.save(i, files.cwd() + "/to_pic.png")
console.log(i)

sleep(2000)

// let sc = images.captureScreen()
sleep(500)
console.log("截图完成")

// images.save(sc, files.cwd() + "/sc.png")
// console.log("sc ok")

let ret = images.findImage(images.captureScreen(), i)
sleep(1000)

console.log("找图完成")
console.log(ret)

setTimeout(()=>{
console.log("end")
}, 50000)

2042175308_RGpn · 1 天前

回答

Hamibot AI
1
· 1 天前

文档地址 https://docs.hamibot.com/

你遇到的问题 images.findImage() 返回 null,即使图片有效、截图正常、找图逻辑看似正确,这是一个常见但容易被忽略细节的问题。下面我将从多个角度分析并给出解决方案。


✅ 1. 确认截图权限已正确获取

虽然你调用了 requestScreenCapture(),但它返回 true 并不代表当前帧的截图是有效的。

你需要确保:

  • 调用 requestScreenCapture() 后,至少等待 1 秒以上再进行 captureScreen()
  • 不要在请求权限后立即截图,否则可能返回空或黑屏图像。

你的代码中用了 sleep(500) 是可以接受的,但建议改为 sleep(1000) 更稳妥。


✅ 2. 避免重复使用同一张模板图导致颜色通道问题

一个非常隐蔽的问题是:如果你多次用 images.read() 加载同一张 PNG 图片(尤其是带透明通道的),在某些设备上会因为 ARGB 与 RGB 格式不匹配而导致找图失败。

🔍 原因分析:

  • captureScreen() 返回的是 RGB 565 或 RGBA_8888 的屏幕截图。
  • 如果你的模板图 to_pic.png 是带透明通道的 PNG,在解码时可能是 ARGB 格式。
  • 找图算法对 Alpha 通道敏感,如果模板图有透明像素,而屏幕上实际显示为不透明背景,则无法匹配。

✅ 解决方案:

将模板图强制转换为与屏幕一致的颜色格式(通常是 RGB 565):

// 文档地址 https://docs.hamibot.com/
if (!requestScreenCapture()) {
  toastLog('没有授予 Hamibot 屏幕截图权限');
  hamibot.exit();
}

console.show();
toast("start");

// 正确加载并标准化模板图
let i = images.read(files.cwd() + "/to_pic.png");
if (!i) {
  console.error("模板图读取失败");
  exit();
}

// 关键步骤:将模板图转换为 RGB565,去除 alpha 通道干扰
i = images.cvtColor(i, "RGBA", "RGB");
i = images.cvtColor(i, "RGB", "RGB565");

console.log("加载并转换模板图完成");

sleep(1000); // 等待稳定

// 截图
let sc = captureScreen();
if (!sc) {
  console.error("截图失败");
  exit();
}
console.log("截图完成");

// 执行找图,设置合理的阈值
let ret = images.findImage(sc, i, {
  threshold: 0.9,
});

console.log("找图完成");
console.log(ret);

if (ret) {
  toastLog("找到目标位置: " + ret);
} else {
  toastLog("未找到目标图片");
}

setTimeout(() => {
  console.log("end");
}, 50000);

✅ 3. 检查模板图是否真的“完全一致”

即使你觉得图片“很小、精准、独特”,也要注意以下几点:

检查项 说明
缩放问题 手机系统设置了“显示大小”?比如字体变大/屏幕缩放,会导致 UI 元素尺寸变化,使模板图比例不符。
分辨率适配 模板图是在 A 设备截的,在 B 设备上运行?不同分辨率下图标位置和大小不同。
动态变化 是否是按钮按下状态、高亮、阴影等细微变化?这些都会影响像素匹配。
抗锯齿/渲染差异 Android 渲染机制可能导致相同图标每次显示略有像素级差异。

最佳实践

  • 当前设备上直接截取模板区域作为训练图。
  • 使用 images.clip() 从截图中裁剪出你要找的小图保存为模板,而不是从别的设备拷贝过来。

例如:

// 临时调试:先手动截图一次,裁剪保存模板
auto.waitFor();
home(); // 回到桌面
sleep(2000);
let img = captureScreen();
images.save(img, files.cwd() + "/debug_screen.png"); // 保存当前屏幕用于调试
// 假设你知道微信图标在 (500, 800),宽高 120x120
let wxIcon = images.clip(img, 500, 800, 120, 120);
images.save(wxIcon, files.cwd() + "/to_pic.png");
toast
ℹ️ 本回答由 AI 生成,内容仅供参考