苹果群控 OCR 找字点击:PaddleOCR V6 四段代码拆解

节点读不到字的时候,用 OCR 读屏幕。中控 10.3.0 起内置 PaddleOCR V6,跑在中控电脑上,不联网,也不占手机性能。下面把整段流程拆成四段:初始化、截屏、找字、点击,每段都贴能跑的代码,省得你对着文档拼。

适用版本:中控 10.3.0+(内置 PP-OCRv6_small),type 为 paddleOcrOnnxV6。 走 USB HID 点击另需手机 iOS 17+;OCR 本身跑在中控电脑上。

第一段:初始化 V6 实例

function createOcrV6() {
ocr.releaseAll();
let tocr = ocr.newOcr();
let ok = tocr.initOcr({
"type": "paddleOcrOnnxV6",
"numThread": 2,
"single": 0,
"matMode": 1,
"padding": 32,
"maxSideLen": 640,
"doAngleFlag": 0,
"mostAngleFlag": 0
});
if (!ok) {
loge("OCR 初始化失败: " + tocr.getErrorMsg());
return null;
}
return tocr;
}

这一组是偏快参数,适合正立、清晰的界面截图。single 设 0 的好处是多机场景下每台设备各用一个 OCR 实例,互不打扰;matMode 设 1 是把图片直接在内存里转成 Mat,省内存。日常扫描够用,要更高检测精度再把 maxSideLen 提到 960;画面可能倒置的话,doAngleFlag 和 mostAngleFlag 也要打开。

初始化失败的话,先看中控版本是不是到了 10.3.0,再对着文档核对参数名,别自己猜。

第二段:截屏

function shot() {
let img = image.captureFullScreen();
if (!img) {
loge("截图失败");
return null;
}
return img;
}

走 USB HID 的时候别用这个,改用无自动化截图 image.captureFullScreenNoAuto()——两条链路互斥,同一台设备只能开一条。截完图记得 image.recycle 回收,群控是长跑,图片不回收内存会一直涨。

第三段:找字算中心

function ocrFind(tocr, keyword) {
let img = shot();
if (!img) return null;
let result = tocr.ocrImage(img, 30 * 1000, {
"padding": 32,
"numThread": 2,
"maxSideLen": 640,
"doAngleFlag": 0,
"mostAngleFlag": 0
});
image.recycle(img);
if (!result) {
logw("未识别到结果");
return null;
}
for (let i = 0; i < result.length; i++) {
let item = result[i];
if (item.label && item.label.indexOf(keyword) >= 0) {
return {
x: item.x + item.width / 2,
y: item.y + item.height / 2,
label: item.label,
confidence: item.confidence
};
}
}
logw("没找到关键字: " + keyword);
return null;
}

返回的数组里每一项都有 label、confidence、x、y、width、height,x 和 y 是文字框左上角,中心点就是 x+width/2、y+height/2。

关键字别写成整句。App 的文案常带空格、省略号和前后缀,用 indexOf 做包含匹配比全等稳。同一屏出现多个「确定」的时候,加个区域过滤或者置信度门槛再点,不然容易点错位置。

第四段:点击

function clickByOcr(tocr, keyword) {
let hit = ocrFind(tocr, keyword);
if (!hit) {
logw("没找到: " + keyword);
return false;
}
logd("命中「" + hit.label + "」置信度 " + hit.confidence);
let r = usbHidEvent.clickPoint(hit.x, hit.y);
if (r && r !== "") {
logw("点击失败: " + r);
return false;
}
return true;
}

走 USB HID 点之前,先 sessionStart 再 setScreenSize(完整写法见同目录那篇 USB HID 四段代码)。不走 HID 的话,换成你正在用的点击接口,坐标算法一样:得跟当前截图的像素对齐,横竖屏一变就要重新设。

四段拼起来

function main() {
let tocr = createOcrV6();
if (!tocr) {
exit();
}
let r = usbHidEvent.sessionStart(true);
if (r && r !== "") {
loge("会话开启失败: " + r);
tocr.releaseAll();
exit();
}
usbHidEvent.setScreenSize(1170, 2532); // 按机型改
clickByOcr(tocr, "发布");
sleep(800 + Math.floor(Math.random() * 400));
usbHidEvent.sessionStop();
tocr.releaseAll();
}
main();

顺序就是:初始化 OCR、开会话定屏幕、找字点、收尾释放。实际项目里还要补上失败重试、每步日志和退出前清理,少一样都可能让脚本在无人值守的时候崩掉。

常见问题

PaddleOCR V6 从哪一版中控开始用?

中控 10.3.0 起内置 PP-OCRv6,changelog 写的「新增 PPOCR-V6 文字识别模型以及函数」。低版本没有这个 type。

type 写 paddleOcrOnnxV6 还是别的?

中控侧脚本写 paddleOcrOnnxV6。脱机版 App 在手机上跑 OCR 时 type 是 paddleOnnxOcrV6,名字差一个 Ocr 的位置,别混用。

OCR 要联网吗?

不用。模型在本地,识别跑在中控电脑上,不占手机性能。

V6 和 V5 能同时用吗?

能,文档写的是与 paddleOcrOnnxV5 并存,角度分类 cls 复用 v5 的模型。旧脚本继续挂 V5 没问题。

识得慢怎么办?

用偏快参数:maxSideLen 设 640,方向检测都关成 0。要更高精度再把 maxSideLen 提到 960,画面可能倒置的话再打开方向检测。

多台设备一起跑,OCR 实例怎么配?

init 时 single 设 0,每台设备各用一个实例;CPU 吃紧就降 numThread、错开各机识别节奏。

识别结果支持哪些语言?

中文简繁、英文、日文和多种拉丁文字;西里尔文不支持。

识到字之后点偏了怎么办?

先确认 setScreenSize 和当前截图分辨率一致,转屏后重设;坐标用框中心;USB HID 和代理自动化互斥,只能开一条。


关于我们:EasyClick 做手机自动化脚本开发和群控,覆盖安卓免 ROOT、iOS 免越狱、鸿蒙。USB HID 的完整写法看 苹果群控免签名脚本实战:USB HID 四段代码拆解。

© 2026 EasyClick · 手机自动化脚本与群控,覆盖安卓免 ROOT、iOS 免越狱、鸿蒙三端。

内容面向合法用途:自动化测试、跨境电商运营与设备管理。