小猿口算自动PK脚本

大家好,我是小黄。
近期,众多大学生炸鱼小猿口算APP,把一众小学生都快虐哭了,小黄听闻后,也跃跃欲试。对此小黄也参考网上的资料写了一个自动Pk的脚步。
首先大家需要安装一个pytorch环境过程中,如果小伙伴对此不熟悉的话可以参考网上的相关教程。
我们需要用到Tesseract-OCR文本识别​。他的原理就是先截图,之后框选出比较大小的两个数字所在的区域,使用Tesseract-OCR识别出来后进行判断,最后模拟鼠标绘制出>,<,=号就​可以了。
Tesseract-OCR​下载地址:

https://github.com/tesseract-ocr/tesseract

这个需要科学上网,​不会科学上网的小伙伴可以关注小黄的公众号回复:小猿口算关键字获取。
在这里插入图片描述

脚本代码

import cv2
import pytesseract
import numpy as np
import re
import pyautogui
import time
import threading
from threading import Thread, Lock
import pynput
from pynput.mouse import Controller, Button
from pynput.keyboard import Listener

# 如果 Tesseract 没有在环境变量中,设置 Tesseract 可执行文件的路径
pytesseract.pytesseract.tesseract_cmd = r'D:\Program Files\Tesseract-OCR\tesseract.exe'

# 初始化鼠标控制器
mouse = Controller()


# 定义绘图函数,并限制在0.1秒左右完成
def draw_symbol(symbol):
    start_time = time.time()  # 记录开始时间

    screen_width, screen_height = pyautogui.size()
    x = int(screen_width * 0.28)  # 水平居中
    y = draw_y + 200  # 使用新的 y 坐标
    duration = 0.1  # 每条线的持续时间,设定为 0.1 秒以保持绘制时间

    print(f"当前鼠标位置: ({x}, {y})")

    mouse.position = (x, y)  # 将鼠标移动到起始位置
    mouse.press(Button.left)

    if symbol == '>':
        # 绘制 ">" 符号
        mouse.move(screen_width * 0.03, screen_height * 0.03)  # 右下斜线(缩短)
        time.sleep(duration)
        # 增加转弯处的形状
        mouse.move(screen_width * 0.01, 0)  # 横向移动
        time.sleep(duration)
        mouse.move(0, screen_height * 0.15)  # 右上斜线(缩短)
        time.sleep(duration)

    elif symbol == '<':
        # 绘制 "<" 符号
        mouse.move(-screen_width * 0.03, screen_height * 0.03)  # 左下斜线(缩短)
        time.sleep(duration)
        # 增加转弯处的形状
        mouse.move(-screen_width * 0.01, 0)  # 横向移动
        time.sleep(duration)
        mouse.move(0, -screen_height * 0.09)  # 左上斜线(缩短)
        time.sleep(duration)

    elif symbol == '=':
        # 绘制 "=" 符号
        mouse.move(-screen_width * 0.02, 0)  # 向左移动一点
        mouse.release(Button.left)
        mouse.press(Button.left)
        mouse.move(screen_width * 0.03, 0)  # 第一条横线(缩短)
        time.sleep(duration)
        mouse.release(Button.left)

        mouse.position = (x - screen_width * 0.02, y + screen_height * 0.02)  # 向下移动一点
        mouse.press(Button.left)
        mouse.move(screen_width * 0.03, 0)  # 第二条横线(缩短)
        time.sleep(duration)
        mouse.release(Button.left)
    else:
        print("无法绘制该符号")

    mouse.release(Button.left)  # 确保释放鼠标按键
    end_time = time.time()  # 记录结束时间
    print(f"绘图 '{symbol}' 完成,耗时: {end_time - start_time:.4f} 秒")


# 全局变量
running = False  # 标志变量,控制任务的运行
lock = Lock()  # 定义锁
draw_y = 970 + 100  # ROI 的底部加上 300 像素


def process_questions():
    global running
    i = 0
    previous_result = None
    previous_numbers = (None, None)  # 新增,用于存储前一题的数字
    stable_count = 0
    stable_threshold = 1  # 可以将阈值设为1,因为我们已经检测题目变化

    while running:
        start_time = time.time()  # 开始时间

        # 获取屏幕截图
        screenshot_start_time = time.time()
        image = pyautogui.screenshot()
        image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
        screenshot_end_time = time.time()

        print(f"截图耗时: {screenshot_end_time - screenshot_start_time:.4f} 秒")

        # 提取需要识别的区域(根据实际情况调整坐标)
        roi = image[850:970, 700:1200]


        # 图像预处理
        processing_start_time = time.time()
        roi_gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)
        roi_contrast = cv2.convertScaleAbs(roi_gray, alpha=2.0, beta=0)  # 增强对比度
        roi_blur = cv2.GaussianBlur(roi_contrast, (5, 5), 0)
        _, roi_thresh = cv2.threshold(roi_blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
        processing_end_time = time.time()

        print(f"图像处理耗时: {processing_end_time - processing_start_time:.4f} 秒")

        # OCR 识别
        ocr_start_time = time.time()
        custom_config = r'--oem 3 --psm 6'
        roi_text = pytesseract.image_to_string(roi_thresh, config=custom_config)
        ocr_end_time = time.time()

        print(f"OCR 识别耗时: {ocr_end_time - ocr_start_time:.4f} 秒")

        # 提取数字并判断大小
        matches = re.findall(r'\d+', roi_text)

        if len(matches) >= 2:
            num1, num2 = int(matches[0]), int(matches[1])
            print(f"第{i + 1}题识别到的数字:{num1}, {num2}")

            # 检查是否为新题目
            if (num1, num2) == previous_numbers:
                print("检测到重复的题目,跳过处理")
            else:
                # 更新前一题的数字
                previous_numbers = (num1, num2)

                # 判断大小
                if num1 < num2:
                    result = '<'
                elif num1 > num2:
                    result = '>'
                else:
                    result = '='
                print(f"判断结果:{num1} {result} {num2}")

                # 绘制符号
                draw_start_time = time.time()
                # 启动绘图线程
                draw_thread = Thread(target=draw_symbol, args=(result,))
                draw_thread.start()
                draw_thread.join()  # 等待绘图完成
                draw_end_time = time.time()
                time.sleep(0.1)
                print(f"绘图耗时: {draw_end_time - draw_start_time:.4f} 秒")

        else:
            print(f"第{i + 1}题未能识别出足够的数字")

        # 等待一小段时间以确保下一题加载
        i += 1
        end_time = time.time()
        print(f"第{i}题处理总耗时: {end_time - start_time:.4f} 秒\n")


def toggle_running(key):
    global running
    if key == pynput.keyboard.Key.enter:
        if not running:
            running = True
            print("任务已启动")
            # 启动处理线程
            t = threading.Thread(target=process_questions)
            t.start()
        else:
            running = False
            print("任务已停止")


# 监听键盘输入
with Listener(on_press=toggle_running) as listener:
    listener.join()

我们需要注意的地方是这个参数,由于屏幕大小不一样,他可能需要微调,所以小黄写了一测试的代码,来看看是否框选正确​。
在这里插入图片描述

在这里插入代码片运行完之后参数对的话可以看到刚刚好可以看到框选的就是数字的​大小就是对的。

import cv2
import numpy as np
import pyautogui
​
# 获取屏幕截图
image = pyautogui.screenshot()
image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
​
# 提取需要识别的区域,调整 Y 轴范围
roi = image[850:970, 700:1200]  # 更新 ROI 的 Y 轴范围,从 850 到 970
​
# 在原图上绘制 ROI,矩形的 Y 坐标也需要更新
cv2.rectangle(image, (700, 850), (1200, 970), (0, 255, 0), 2)  # 绘制绿色矩形
​
# 显示原图和 ROI
cv2.imshow("Original Image", image)
cv2.imshow("Region of Interest", roi)
​
cv2.waitKey(0)  # 等待按键
cv2.destroyAllWindows()  # 关闭所有窗口
​

在这里插入图片描述

OK,完事具备​,现在就有可以运行上面的代码了。我们看看具体效果。
在这里插入图片描述
由于时间比较仓储,大家可以改改绘制<,>,=号的位置,感觉小黄的绘制得不是​很准确。​
最后祝大家玩得愉快,有问题请给我留言或私信。需要软件的小伙伴记得回复关键字:小猿口算
在这里插入图片描述
不懂的小伙伴大家可以进群交流一下。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/889468.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux相关概念和易错知识点(14)(进程终止、进程退出、退出信息)

1.进程终止 &#xff08;1&#xff09;错误码 对于程序常见错误信息&#xff0c;C/C提供了信息解释&#xff0c;保存在<string.h>&#xff0c;使用strerror(错误码)就可以查询 错误信息成立的前提是错误码要和错误信息匹配&#xff0c;我们需要结合C/C给我们的错误码来…

【计算机网络 - 基础问题】每日 3 题(三十六)

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞…

Open WebUI | 自托管的类 ChatGPT 网站

Open WebUI 是一个扩展性强、功能丰富且用户友好的自托管 WebUI&#xff0c;支持 ChatGPT 网页端的大部分功能&#xff0c;支持各类模型服务&#xff0c;包括 Ollama 和 OpenAI 的 API。该项目在 GitHub 上已有 38k 星&#xff0c;非常受欢迎。 功能介绍 本篇介绍该项目的功能…

考研笔记之操作系统(四) - 文件管理

文件管理 1. 简介1.1 前情回顾1.2 文件的属性1.3 文件内部数据的组织方式1.4 操作系统向上提供的文件功能1.5 文件应如何放在外存 2. 文件的逻辑结构2.1 无结构文件2.2 有结构文件2.2.1 顺序文件2.2.2 索引文件2.2.3 索引顺序文件2.2.4 多级索引顺序文件 3. 文件目录3.1 基本概…

若依前端后打成一个JAR包部署

客户需要将项目前后端作为一个整体打包成jar&#xff0c;不使用nginx方式转发。使用框架是若依前后端分离&#xff0c;后端springboot&#xff0c;前端vue&#xff0c;目的就是把vue打入jar。 一、前端修改 ruoyi-ui/src/router/index.js文件 &#xff0c;将 mode: ‘history’…

数据结构之二叉搜索树(key模型与key_value模型)

二叉搜索树&#xff08;key模型与key_value模型&#xff09; 1. ⼆叉搜索树的概念2. ⼆叉搜索树的性能分析3. ⼆叉搜索树的插⼊4. ⼆叉搜索树的查找5. ⼆叉搜索树的删除6. ⼆叉搜索树的实现代码7. ⼆叉搜索树key和key/value使⽤场景7.1 key搜索场景&#xff1a;7.2 key/value搜…

2-118 基于matlab的六面体建模和掉落仿真

基于matlab的六面体建模和掉落仿真&#xff0c;将对象建模为刚体来模拟将立方体扔到地面上。同时考虑地面摩擦力、刚度和阻尼所施加的力&#xff0c;在三个维度上跟踪平移运动和旋转运动。程序已调通&#xff0c;可直接运行。 下载源程序请点链接&#xff1a;2-118 基于matla…

Kubernetes系列之一快速部署一套K8s集群(kubeadm方式)

最近本人在重温云原生相关的技术&#xff0c;说到云原生&#xff0c;必然绕不开Kubernetes&#xff0c;今天想跟大家聊的就是大名顶顶的Kubernetes。相信很多朋友在学习和使用Kubernetes的过程遇到各式各样不同的问题。我将从一个初学者的角度来给大家讲解一下Kubernete从安装、…

字节跳动青训营开始报名了!

关于青训营&#xff1a; 青训营是字节跳动技术团队发起的技术系列培训 &人才选拔项目;面向高校在校生&#xff0c;旨在培养优秀且具有职业竞争力的开发工程师。 本次技术训练营由掘金联合豆包MarsCode 团队主办课程包含前端、后端和 A 方向&#xff0c;在这个飞速发…

Ajax面试题:(第一天)

目录 1.说一下网络模型 2.在浏览器地址栏键入URL&#xff0c;按下回车之后会经历以下流程&#xff1a; 3.什么是三次握手和四次挥手&#xff1f; 4.http协议和https协议的区别 1.说一下网络模型 注&#xff1a;各层含义按自己理解即可 2.在浏览器地址栏键入URL&#xff0c;…

Spring Boot 进阶-详解Spring Boot整合数据库

在之前的例子中&#xff0c;我们介绍了如何在Spring Boot 框架中添加数据源配置。这篇文章我们来详细介绍一下如何整合Mybatis框架。 整合Mybatis框架 还是按照之前的套路&#xff0c;我们要整合Mybatis框架&#xff0c;首先需要加载对应的场景启动器。这里我们引入由Mybatis提…

gitlab-ci 集成 k3s 部署spring boot 应用

环境 一台ECS gitlab 16.10 一台ECS gitlab-runner docker方式 一台腾讯云服务器 k3s k3s version v1.30.5k3s1 (9b586704) go version go1.22.6 本地: idea 2024 准备开始 gitlab上创建"api"仓库,本地IDEA 创建spring boot web demo项目k8s-gitlab-demo. 确保能…

C语言-常见文件操作函数详解(fgetc,fputc,fgets,fputs,fscanf,fprintf,fread,fwrite)

&#x1f30f;个人博客&#xff1a;尹蓝锐的博客 希望文章能够给到初学的你一些启发&#xff5e; 如果觉得文章对你有帮助的话&#xff0c;点赞 关注 收藏支持一下笔者吧&#xff5e; 顺序读写数据常用函数 函数名调用形式功能返回值fgetcfgetc(fp)从指针变量fp指向的文件中读…

(五)Proteus仿真STM32单片机串口数据流收发

&#xff08;五&#xff09;Protues仿真STM32单片机串口数据流收发 – ARMFUN 1&#xff0c;打开STM32CubeMX&#xff0c;找到USART1,配置模式Asynchronous&#xff0c;此时PA9、PA10自动变成串口模式 串口默认参数:115200bps 8bit None 1stop 2&#xff0c;NVIC Settings使能…

Kafka之基本概念

1、Kafka是什么&#xff1f; Kafka是由Scala语言开发的一个多分区、多副本&#xff0c;基于Zookeeper集群协调的系统。 那这个所谓的系统又是什么系统呢&#xff1f; 回答这个问题要从发展的角度来看&#xff1a;起初Kafka的定位是分布式消息系统。但是目前它的定位是一个分布…

Pr 视频效果:元数据和时间码刻录

视频效果/视频/元数据和时间码刻录 Video/Metadata & Timecode Burn-in 元数据和时间码刻录 Metadata & Timecode Burn-in效果是一种在视频画面上叠加显示剪辑元数据或时间码的工具。它允许在导出视频时&#xff0c;将需用的元数据信息直接刻录在画面上&#xff0c;方便…

Linux操作系统小项目——实现《进程池》

文章目录 前言&#xff1a;代码实现&#xff1a;原理讲解&#xff1a;细节处理&#xff1a; 前言&#xff1a; 在前面的学习中&#xff0c;我们简单的了解了下进程之间的通信方式&#xff0c;目前我们只能知道父子进程的通信是通过匿名管道的方式进行通信的&#xff0c;这是因…

MacOS编译和安装Poco库的方法

1.从官网git下载最新的poco源代码 在/usr/local路径下创建Poco文件夹&#xff0c;克隆Poco源代码 sudo git clone -b poco-1.13.3-release https://github.com/pocoproject/poco.git2.等了一会后&#xff0c;报错啦&#xff01;&#xff01;&#xff01; error: RPC failed…

Unity3D 单例模式

Unity3D 泛型单例 单例模式 单例模式是一种创建型设计模式&#xff0c;能够保证一个类只有一个实例&#xff0c;提供访问实例的全局节点。 通常会把一些管理类设置成单例&#xff0c;例如 GameManager、UIManager 等&#xff0c;可以很方便地使用这些管理类单例&#xff0c;…

<Project-8 pdf2tx-MM> Python Flask应用:在浏览器中翻译PDF文件 NLTK OCR 多线程 指定翻译器 改进后的P6

项目概述 名字解释 缩写&#xff1a; pdf2tx-MM pdf file transfer to text content with Multi-threads and Multi-translators pdf2tx-MM 是一个基于 Flask 的 Web 应用程序&#xff0c;提供将 PDF 文件中的内容提取、翻译并展示。使用者上传 PDF 文件&#xff0c;应用程序…