为什么OCR截图,有些内容无法识别?是否有更好的截图OCR识别代码?

已存档
测试脚本 · 1 个月前
第 1 条补充
·
1 个月前

循环OCR识别元素点击,但是切换页面后,第一次还是会识别上一页的元素进行点击对应坐标,有什么办法避免,怎么解决??

第 2 条补充
·
1 个月前

循环及途中,能否能增加截图对比?如果截图一样就继续截图,直到不一样再往下执行,代码怎么写?

回答

Hamibot AI
1
· 1 个月前

OCR识别不成功通常有以下几个原因:

  1. 图像质量问题:截图模糊、分辨率低或有噪点会影响识别准确率
  2. 文字对比度不足:文字与背景颜色相近,缺乏足够对比度
  3. 字体特殊或太小:非常规字体或过小的文字难以被准确识别
  4. 屏幕刷新问题:截图时界面未完全渲染完成
  5. OCR引擎限制:OCR技术本身对某些语言、字体或排版支持有限

要提高OCR识别效果,你可以尝试以下改进方案:

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

// 增加等待时间确保界面稳定
sleep(2000);

// 截取屏幕
var img = captureScreen();

// 如果需要,可以先对特定区域截图提高识别率
// 例如只截取屏幕中央区域 [x, y, width, height]
// var regionImg = images.clip(img, 0, 200, device.width, device.height-400);

// 尝试使用不同的OCR方法
var result = "";
var maxAttempts = 3;
var attempt = 0;

while(attempt < maxAttempts && !result) {
    attempt++;
    // 优先尝试recognizeText获取纯文本
    result = ocr.recognizeText(img);
    
    // 如果结果为空,尝试完整的recognize方法
    if(!result) {
        var fullResult = ocr.recognize(img);
        if(fullResult && fullResult.text) {
            result = fullResult.text;
        }
    }
    
    // 如果仍然没有结果,稍等后重试
    if(!result && attempt < maxAttempts) {
        sleep(1000);
        img = captureScreen();
    }
}

if(result) {
    toastLog('识别成功,内容: ' + result.substring(0, 30) + (result.length > 30 ? '...' : ''));
    log('完整识别结果: ' + result);
} else {
    toastLog('多次尝试后仍无法识别文字内容');
    // 可以保存问题截图用于分析
    var fileName = '/sdcard/hamibot_failed_ocr_' + new Date().getTime() + '.png';
    images.save(img, fileName);
    log('问题截图已保存至: ' + fileName);
}

img.recycle(); // 释放图片资源
hamibot.exit();

额外建议:

  • 对于固定界面的文字识别,可以先截图保存模板,然后使用findImage定位文字区域再进行OCR
  • 如果识别率仍然不高,考虑对截图进行预处理(使用images模块调整对比度、二值化等)
  • 对于重要信息,可以结合图像识别和OCR,先用findColorfindImage定位关键区域再进行文字识别
  • 复杂场景建议使用Hamibot的付费OCR服务,通常比基础OCR有更高的准确率

OCR技术本身有一定局限性,对于特别重要的场景,建议设计多重验证机制确保自动化流程的可靠性。


补充回答 1

要解决循环OCR识别时切换页面后仍识别上一页元素的问题,关键在于确保每次OCR识别都基于最新的屏幕内容。以下是具体解决方案:

  1. 强制刷新屏幕截图
    在每次循环开始时重新获取屏幕截图,避免使用缓存图像:
// 文档地址 https://docs.hamibot.com/
while(true) {
  // 必须每次循环都重新截图
  const img = captureScreen();
  
  // 添加页面确认步骤(关键!)
  if (!isTargetPage(img)) {
    // 等待页面完全切换完成
    sleep(800);
    continue;
  }
  
  // 执行OCR识别
  const res = ocr.recognizeText(img);
  // ...后续处理
}

// 页面确认函数示例
function isTargetPage(img) {
  // 查找新页面特有的文字特征
  const pageIndicator = images.findColor(img, "#FF0000", {
    threshold: 4,
    region: [500, 100, 200, 100]
  });
  return pageIndicator != null;
}
  1. 添加双重确认机制
    在页面切换操作后添加明确的等待条件:
// 执行页面切换操作后
click(1000, 200);
// 等待切换动画完成
sleep(500);

// 双重确认页面是否已切换
let pageLoaded = false;
for(let i = 0; i < 5; i++) {
  const img = captureScreen();
  if(images.findColor(img, "#新页面特征色")) {
    pageLoaded = true;
    break;
  }
  sleep(300);
}

if(!pageLoaded) {
  toastLog("页面切换超时");
  hamibot.exit();
}
  1. 优化循环结构
    使用更可靠的循环控制逻辑:
// 文档地址 https://docs.hamibot.com/
function safeOcrLoop() {
  while(true) {
    // 1. 请求最新截图权限
    if(!requestScreenCapture(true)) {
      toastLog("截图权限异常");
      return;
    }
    
    // 2. 获取全新截图(关键:不使用缓存)
    const freshImg = captureScreen();
    
    // 3. 验证是否为目标页面
    if(!verifyCurrentPage(freshImg)) {
      sleep(600); // 给页面切换留出时间
      continue;
    }
    
    // 4. 执行识别和点击
    const res = ocr.recognizeText(freshImg);
    // ...处理识别结果
    
    // 5. 点击后强制等待
    sleep(300);
  }
}

// 页面验证函数(根据你的实际页面特征修改)
function verifyCurrentPage(img) {
  // 查找页面特有的标题文字
  const title = images.findColor(img, "#333333", {
    region: [0, 50, 1080, 100]
  });
  return title != null;
}

关键要点:

  • 每次循环必须调用captureScreen()获取新截图,不要复用之前的图像对象
  • 在OCR识别前添加页面确认步骤,确保当前页面是目标页面
  • 页面切换操作后添加sleep(500)以上等待时间,让界面动画完成
  • 使用requestScreenCapture(true)强制刷新截图权限
  • 对于快速切换的页面,建议添加多次确认机制

这样处理后,系统会确保每次OCR识别都是基于最新页面内容,避免误识别上一页元素的问题。


补充回答 2

要实现截图对比功能,在Hamibot中可以通过关键点颜色检测来判断页面是否已切换。以下是完整可靠的解决方案:

// 文档地址 https://docs.hamibot.com/
function waitForPageChange(maxWaitTime = 5000) {
  // 获取当前屏幕作为基准
  const baseScreen = captureScreen();
  
  // 提取5个具有代表性的关键点(根据你的应用界面调整坐标)
  const keyPoints = [
    {x: 200, y: 300, color: images.pixel(baseScreen, 200, 300)},
    {x: 500, y: 400, color: images.pixel(baseScreen, 500, 400)},
    {x: 800, y: 500, color: images.pixel(baseScreen, 800, 500)},
    {x: 300, y: 600, color: images.pixel(baseScreen, 300, 600)},
    {x: 700, y: 200, color: images.pixel(baseScreen, 700, 200)}
  ];
  
  const startTime = Date.now();
  
  while (Date.now() - startTime < maxWaitTime) {
    const currentScreen = captureScreen();
    let screenChanged = false;
    
    // 检查所有关键点是否发生变化
    for (const point of keyPoints) {
      const currentColor = images.pixel(currentScreen, point.x, point.y);
      // 颜色不一致说明页面已变化
      if (currentColor !== point.color) {
        screenChanged = true;
        break;
      }
    }
    
    if (screenChanged) {
      return true; // 页面已切换
    }
    
    // 短暂等待后再次检查
    sleep(150);
  }
  
  return false; // 超时未检测到变化
}

// 使用示例(结合OCR循环)
auto.waitFor();
if (!requestScreenCapture()) {
  toastLog('请授予屏幕截图权限');
  hamibot.exit();
}

// 执行页面切换操作
click(1000, 500);
sleep(300);

// 等待页面完全切换
if (waitForPageChange(4000)) {
  toastLog("页面切换完成,开始OCR识别");
  // 执行OCR识别逻辑
  const img = captureScreen();
  const res = ocr.recognizeText(img);
  // ...后续处理
} else {
  toastLog("等待页面切换超时");
}

优化建议:

  1. 关键点选择技巧

    • 选择页面上变化最明显的区域(如标题栏、状态栏)
    • 避免选择可能动态变化的区域(如广告、计时器)
    • 每个关键点间隔至少200px,确保覆盖不同区域
  2. 增强版等待函数(适用于复杂场景):

function waitForPageChangeAdvanced(maxWaitTime = 5000, changeThreshold = 3) {
  const baseScreen = captureScreen();
  const keyPoints = generateKeyPoints(); // 生成20个均匀分布的关键点
  
  const startTime = Date.now();
  let unchangedCount = 0;
  
  while (Date.now() - startTime < maxWaitTime) {
    const currentScreen = captureScreen();
    let changedPoints = 0;
    
    for (const point of keyPoints) {
      const baseColor = images.pixel(baseScreen, point.x, point.y);
      const currentColor = images.pixel(currentScreen, point.x, point.y);
      
      if (baseColor !== currentColor) {
        changedPoints++;
      }
    }
    
    // 如果超过阈值的关键点变化,认为页面已切换
    if (changedPoints > changeThreshold) {
      return true;
    }
    
    // 连续3次未检测到变化则增加等待时间
    unchangedCount = (baseScreen === currentScreen) ? unchangedCount + 1 : 0;
    sleep(unchangedCount > 2 ? 300 : 150);
  }
  
  return false;
}

// 生成均匀分布的关键点
function generateKeyPoints() {
  const points = [];
  const width = 1080; // 根据你的设备分辨率调整
  const height = 1920;
  
  for (let x = 100; x < width; x += 200) {
    for (let y = 100; y < height; y += 200) {
      points.push({x, y});
    }
  }
  
  // 随机打乱顺序
  return points.sort(() => Math.random() - 0.5).slice(0, 20);
}

使用注意事项:

  1. 在页面切换操作后立即调用此函数,不要添加过长的固定sleep
  2. 关键点坐标需要根据你的具体应用界面调整
  3. 对于动画过渡较长的页面,适当增加maxWaitTime(建议2000-5000ms)
  4. 如果页面变化较小(如只更新部分区域),减少changeThreshold值

这种实现方式比单纯使用固定sleep更可靠,能准确检测到页面是否真正完成切换,有效避免识别上一页元素的问题。

ℹ️ 本回答由 AI 生成,内容仅供参考