AutoJs6 icon indicating copy to clipboard operation
AutoJs6 copied to clipboard

能否讲一下images.matchFeatures怎么用吗?研究很多天还是不会用。

Open realcsnake2023 opened this issue 8 months ago • 2 comments

新增 images.matchFeatures/detectAndComputeFeatures 方法, 支持全分辨率找图 (Ref to Auto.js Pro)

我自以为是跟images.matchTemplate(img, template, options)的用法相似,所以写了个代码:

requestScreenCapture();
sleep(1000);
var img = images.read("/sdcard/脚本/res/JD/领水滴1.jpg");
console.log(img);
var cpt = captureScreen();
console.log(cpt);
var fndimg = images.matchFeatures(cpt,img);
console.log(fndimg);
img.recycle();

但是报错了。

方法 "images.matchFeatures" 调用失败. Argument sceneFeatures org.autojs.autojs.core.image.CapturedImage@b8dddd0 (JavaObject) for images.matchFeatures must be a ImageFeatures.
java.lang.IllegalArgumentException: Argument sceneFeatures org.autojs.autojs.core.image.CapturedImage@b8dddd0 (JavaObject) for images.matchFeatures must be a ImageFeatures
    at $remote/test1.js:7:0

请问正确的用法是什么?非常感谢! @SuperMonster003

realcsnake2023 avatar Jun 01 '25 16:06 realcsnake2023

已经查到。

// 读取小图
let hellokitty = $images.read('/sdcard/脚本/res/hellokitty.jpg');
// 计算小图特征
let objectFeatures = $images.detectAndComputeFeatures(hellokitty);
// 请求截图权限
requestScreenCapture();

// 打开HelloKitty图片
$app.openUrl('https://baike.baidu.com/item/Hello%20Kitty/984270')

let n = 3;
for (let i = 0; i < n; i++) {
    sleep(3000);
    let capture = captureScreen();

    // 若要提高效率,可以在计算大图特征时调整scale参数,默认为0.5,
    // 越小越快,但可以放缩过度导致匹配错误。若在特征匹配时无法搜索到正确结果,可以调整这里的参数,比如\{scale: 1\}
    // 也可以在这里指定\{region: [...]\}参数只计算这个区域的特征提高效率
    let sceneFeatures = $images.detectAndComputeFeatures(capture);
    // 最后一次匹配时,我们将特征和匹配绘制出来,在调试时更容易看出匹配效果,但会增加耗时
    let drawMatches = (i === n - 1 ? '/sdcard/脚本/res/JD/matches.jpg' : undefined);
    let result = $images.matchFeatures(sceneFeatures, objectFeatures, { drawMatches });
    // 打印结果和中心点,可使用click(reuslt.centerX, result.centerY)点击
    console.log(result, result ? result.center : null);

    //result是一个对象,如果result存在,则打印result中的所有属性和对应的值。
    if (result) {
        for (let key in result) {
            console.log(key, result[key]);
        }
    }

    // 回收特征对象
    sceneFeatures.recycle();

    if (drawMatches) {
        // 可以在当前目录查看matches.jpg图片,会绘制详细匹配详情
        app.viewFile('/sdcard/脚本/res/JD/matches.jpg');
    }
}
// 回收小图特征对象
objectFeatures.recycle();
hellokitty.recycle();

realcsnake2023 avatar Jun 08 '25 12:06 realcsnake2023

是的, 上述 Hello Kitty 示例, 即为网络流行的 Auto.js Pro 可用的特征匹配经典示例代码. AutoJs6 在源码层面与 Rhino 脚本层面, 都尽可能贴近 Auto.js Pro 的原始设计, 因此理论上来讲, AutoJs6 也应该可以使用相同的 JavaScript 代码实现相同 (或至少相似) 的功能和效果. 不过, 特征匹配功能涉及到 C++ 层面的非开源代码, 因此 AutoJs6 只能尽量模拟其内部实现, 无法做到完全一致, 也无法保证最终的功能实现效果与 Auto.js Pro 完全相同.

特征匹配需要传入两个特征, 而不是两个图像. 因此有 detectAndComputeFeatures 方法. 特征匹配还涉及到两个关键术语, scene 与 object, 即场景与目标. 可以理解为 "大图" 和 "小图", 在 scene 中查找 object.

如有其他问题, 可继续反馈.

SuperMonster003 avatar Jul 01 '25 05:07 SuperMonster003