本地部署局域网内YOLO自动识别快手图标
本地部署局域网内YOLO自动识别快手图标// =====================================================================
// AIWROK 自定义模型示例 —— 用 YOLO 自动识别快手图标并点击
// =====================================================================
// 【原理】手机截屏发到电脑 /api/detect,电脑用你训练的自定义模型
// ---------------- 类别说明(模型能认的 4 个图标) ----------------
// ┌──────────────┬────────────────────┬──────────────────────────┐
// │ 类别名 │ 是什么 │ 在快手视频页的位置 │
// ├──────────────┼────────────────────┼──────────────────────────┤
// │ dianzan │ 点赞·白色心心 │ 右侧图标列第1个(约x990,y870)│
// │ pinglun │ 评论·圆气泡 │ 右侧图标列第2个(约x990,y1060)│
// │ shoucang │ 收藏·五角星 │ 右侧图标列第3个(约x990,y1260)│
// │ fenxiang │ 分享·纸飞机箭头 │ 右侧图标列第4个(约x990,y1450)│
// └──────────────┴────────────────────┴──────────────────────────┘
//
// 【center 中心点是什么】
// 模型在截图里框住图标后,取"框的正中心"那个像素点 。
// 点中心点 = 稳定点中图标,不会点偏到边缘。
// 坐标是"电脑收到的那张截图"里的像素位置,
// 换算到你手机屏幕:sx = 中心x × 手机宽 ÷ 截图宽(脚本已自动换算成 sx/sy)。
//
// 【识别结果示例】
// { label:"dianzan", class:"dianzan", conf:0.98, ← 类别名+置信度(0~1,越高越准)
// center:, ← 截图里的中心点
// box:, ← 外接框(左上,右下)
// sx:988, sy:868 } ← 换算到手机屏幕的点击坐标
// =====================================================================
var SERVER_IP = "192.168.10.103";// ★电脑IP
var http = new okHttp();
// ---------- 核心函数:截屏识别,返回目标列表 ----------
function 识别图标(conf) {
var shot = screen.screenShotFull();
if (!shot) { print.log("截图失败"); return []; }
var body = ("b64=" + encodeURIComponent(shot.toBase64()) + "&conf=" + (conf || 0.4)).toString();
var r = JSON.parse(http.postForm(("http://" + SERVER_IP + ":8000/api/detect").toString(), body));
if (!r || !r.detections) { print.log("识别失败"); return []; }
// 给每个目标补充换算到手机屏幕的坐标
var list = [];
for (var i = 0; i < r.detections.length; i++) {
var d = r.detections;
if (d.conf < 0.5) continue;// 过滤低置信度
d.sx = Math.round(d.center * screen.getScreenWidth() / r.width);
d.sy = Math.round(d.center * screen.getScreenHeight() / r.height);
list.push(d);
}
// 同位置去重:两个类别挤在同一坐标(<100px)时只留置信度最高的
// (防止 shoucang/fenxiang 混淆导致点错按钮)
var out = [];
for (var a = 0; a < list.length; a++) {
var ok = true;
for (var b = 0; b < list.length; b++) {
if (a == b) continue;
var dx = list.sx - list.sx, dy = list.sy - list.sy;
if (Math.abs(dx) < 100 && Math.abs(dy) < 100 && list.conf > list.conf) { ok = false; break; }
}
if (ok) out.push(list);
}
return out;
}
// 按返回键收起误弹的面板
function 按返回键() {
try {
input.sendKeyCode(4);// KEYCODE_BACK
print.log("[恢复] 按返回键收起面板");
java.lang.Thread.sleep(1200);
return true;
} catch (e) { print.log("[恢复] 返回键失败: " + e); return false; }
}
// ---------- 按类别名找图标并点击(maxY=只点该高度以上的,防类别混淆点错) ----------
function 找图标点击(类别名, 说明, maxY) {
var list = 识别图标(0.4);
for (var i = 0; i < list.length; i++) {
if ((list.label == 类别名 || list.class == 类别名)
&& (!maxY || list.sy <= maxY)) {
print.log("[" + 说明 + "] 找到 " + list.label + " 置信度" + list.conf + " 点击(" + list.sx + "," + list.sy + ")");
auto.clickPoint(list.sx, list.sy);
return true;
}
}
print.log("[" + 说明 + "] 没找到 " + 类别名);
return false;
}
// ---------- 完整流程示例:点赞 → 进评论区 → 收藏 ----------
function 自动养机() {
print.log("===== 自定义模型养机开始 =====");
// 0. 状态恢复:点赞图标不在 = 被误弹的面板挡住,按返回键收起(最多2次)
for (var r = 0; r < 2; r++) {
var list = 识别图标(0.4);
var 有心心 = false;
for (var i = 0; i < list.length; i++) if (list.label == "dianzan") 有心心 = true;
if (有心心) break;
print.log("[恢复] 第" + (r + 1) + "次没看到点赞图标,按返回键收面板");
按返回键();
}
// 1. 点赞
if (找图标点击("dianzan", "点赞")) {
java.lang.Thread.sleep(1500);
}
// 2. 进评论区(找不到=可能被弹窗挡住,按返回键恢复)
if (找图标点击("pinglun", "进评论")) {
java.lang.Thread.sleep(2000);
// 这里接"输入评论+发送"逻辑(参考 快捷评论点赞\主脚本.js 步骤2~4)
} else {
按返回键();
}
// 3. 收藏(maxY=1350:收藏星在y≈1257,分享箭头在y≈1450,
// 模型偶尔把两者认混,限制高度就不会点错)
if (找图标点击("shoucang", "收藏", 1350)) {
java.lang.Thread.sleep(1000);
}
// 4. 下滑下一个视频
auto.swip(540, 1500, 540, 500, 300, 0);
print.log("本轮完成");
}
// ---------- 纯查看模式:列出当前屏幕所有识别到的图标 ----------
function 查看识别结果() {
var list = 识别图标(0.3);
print.log("当前屏幕识别到 " + list.length + " 个图标:");
for (var i = 0; i < list.length; i++) {
print.log("" + list.label + " 置信度" + list.conf + " 中心(" + list.sx + "," + list.sy + ")");
}
return list;
}
// ======================= 【执行入口】 =======================
查看识别结果(); // 先看一眼识别到什么
java.lang.Thread.sleep(2000);
// 循环养机示例:每 6 秒一轮,共 20 轮
for (var 轮 = 1; 轮 <= 20; 轮++) {
print.log("======== 第 " + 轮 + "/20 轮 ========");
自动养机();
java.lang.Thread.sleep(4000);
}
print.log("===== 全部完成 =====");
页:
[1]