吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2361|回复: 19
收起左侧

[讨论] 用AI写了一个自动识别题目并给出答案的程序

  [复制链接]
西北玄天一片云 发表于 2025-7-17 09:57
有兴趣的大神,一起讨论优化一下。可以将源码或者成品共享学习学习。

python源码

import tkinter as tk
from tkinter import filedialog, simpledialog
from tkinter import ttk
from PIL import ImageGrab, Image
import pytesseract
import requests
import json
import threading
import time
import os
import pytesseract
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'

# OCR 文字识别
def extract_text_from_image(image):
    text = pytesseract.image_to_string(image, lang='chi_sim')
    return text.strip()

# Kimi API 查询
def query_kimi(question, api_key, callback=None):
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }
    data = {
        "model": "qwen-plus",
        "prompt": f"请回答以下问题:{question}"
    }
    try:
        response = requests.post("https://api.kimi.ai/v1/chat/completions", json=data, headers=headers)
        response.raise_for_status()
        answer = response.json().get("choices", [{}])[0].get("message", {}).get("content", "无法获取答案")
        if callback:
            callback(answer)
    except Exception as e:
        if callback:
            callback(f"API 请求失败: {str(e)}")

# 加载题库
def load_question_bank(file_path):
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            return json.load(f)
    except Exception as e:
        print(f"加载题库失败: {str(e)}")
        return {}

# 加载题库(txt 格式)
def load_question_bank_from_txt(file_path):
    """TXT文件加载题库,每行格式为 '问题:答案'"""
    question_bank = {}
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            for line in f:
                if ":" in line:
                    question, answer = line.strip().split(":", 1)
                    question_bank[question] = answer
    except Exception as e:
        print(f"加载TXT题库失败: {str(e)}")
    return question_bank

# 截图功能
def capture_screen(region=None):
    if region:
        x1, y1, x2, y2 = region
        return ImageGrab.grab(bbox=(x1, y1, x2, y2))
    return ImageGrab.grab()

class FullScreenApp:
    def __init__(self, master, on_capture):
        self.master = master
        self.on_capture = on_capture
        self.root = tk.Toplevel(master)
        self.root.attributes('-fullscreen', True)
        self.root.attributes('-alpha', 0.3)
        self.root.configure(bg='black')
        self.canvas = tk.Canvas(self.root, cursor="cross", highlightthickness=0)
        self.canvas.pack(fill=tk.BOTH, expand=True)
        self.rect = None
        self.start_x = self.start_y = 0
        self.end_x = self.end_y = 0
        self.setup_bindings()

    def setup_bindings(self):
        self.canvas.bind("<ButtonPress-1>", self.on_button_press)
        self.canvas.bind("<B1-Motion>", self.on_mouse_drag)
        self.canvas.bind("<ButtonRelease-1>", self.on_button_release)

    def on_button_press(self, event):
        self.start_x = self.end_x = event.x
        self.start_y = self.end_y = event.y
        if not self.rect:
            self.rect = self.canvas.create_rectangle(0, 0, 0, 0, outline='red', width=2)

    def on_mouse_drag(self, event):
        self.end_x = event.x
        self.end_y = event.y
        self.canvas.coords(self.rect, self.start_x, self.start_y, self.end_x, self.end_y)

    def on_button_release(self, event):
        self.root.destroy()
        x1 = min(self.start_x, self.end_x)
        y1 = min(self.start_y, self.end_y)
        x2 = max(self.start_x, self.end_x)
        y2 = max(self.start_y, self.end_y)
        if (x2 - x1) > 5 and (y2 - y1) > 5:
            self.on_capture((x1, y1, x2, y2))

# 主界面类
class AutoAnswerApp:
    def __init__(self, root):
        self.root = root
        self.root.title("自动答题助手")
        self.root.geometry("600x400")
        self.root.resizable(False, False)
        self.style = ttk.Style()
        self.style.theme_use('clam')
        self.style.configure("TButton", padding=6, relief="flat", background="#4CAF50")
        self.style.map("TButton", background=[('active', '#45a049')])
        
        self.question_bank = {}
        self.kimi_api_key = os.getenv("KIMI_API_KEY", "your_kimi_api_key_here")

        # 创建菜单栏
        menubar = tk.Menu(root)
        filemenu = tk.Menu(menubar, tearoff=0)
        filemenu.add_command(label="设置 Kimi API 密钥", command=self.set_api_key)
        filemenu.add_separator()
        filemenu.add_command(label="退出", command=root.quit)
        menubar.add_cascade(label="文件", menu=filemenu)
        root.config(menu=menubar)

        # 主框架
        main_frame = ttk.Frame(root, padding="20")
        main_frame.pack(fill=tk.BOTH, expand=True)

        # 选择题库文件按钮
        self.select_button = ttk.Button(main_frame, text="选择题库文件", command=self.select_file, style="TButton")
        self.select_button.pack(pady=10, fill=tk.X)

        # 截图识别题目按钮
        self.capture_button = ttk.Button(main_frame, text="截图识别题目", command=self.start_fullscreen_capture, style="TButton")
        self.capture_button.pack(pady=10, fill=tk.X)

        # 题目显示区域
        self.question_label = tk.Label(main_frame, text="识别到的题目:", justify=tk.LEFT, wraplength=500, font=("微软雅黑", 12))
        self.question_label.pack(pady=10)

        # 答案显示区域
        self.answer_label = tk.Label(main_frame, text="答案将在这里显示:", justify=tk.LEFT, wraplength=500, font=("微软雅黑", 12), fg="blue")
        self.answer_label.pack(pady=10)

    def set_api_key(self):
        new_key = simpledialog.askstring("输入", "请输入 Kimi API 密钥:", initialvalue=self.kimi_api_key)
        if new_key:
            self.kimi_api_key = new_key

    def select_file(self):
        file_path = filedialog.askopenfilename(filetypes=[("支持的文件格式", "*.json;*.txt")])
        if file_path:
            _, ext = os.path.splitext(file_path)
            if ext == ".json":
                self.question_bank = load_question_bank(file_path)
            elif ext == ".txt":
                self.question_bank = load_question_bank_from_txt(file_path)

    def start_fullscreen_capture(self):
        FullScreenApp(self.root, self.process_capture)

    def process_capture(self, region):
        image = capture_screen(region)
        question = extract_text_from_image(image)
        self.question_label.config(text=f"识别到的题目:\n{question}")

        # 异步查询 AI 答案
        if question and self.kimi_api_key != "your_kimi_api_key_here":
            threading.Thread(target=query_kimi, args=(question, self.kimi_api_key, self.update_answer_label)).start()

        # 查找题库答案
        answer_db = search_answer_in_db(question, self.question_bank)
        self.answer_label.config(text=f"题库答案:\n{answer_db or '未找到'}...")

    def update_answer_label(self, answer):
        self.answer_label.config(text=f"AI 答案:\n{answer}")

# 启动程序
def main():
    root = tk.Tk()
    app = AutoAnswerApp(root)
    root.mainloop()

if __name__ == "__main__":
    main()

免费评分

参与人数 6吾爱币 +3 热心值 +5 收起 理由
xiaofeng4929 + 1 谢谢@Thanks!
qjlfl + 1 + 1 我很赞同!
ykr + 1 用心讨论,共获提升!
wyangdh + 1 + 1 谢谢@Thanks!
给别人可惜了 + 1 我很赞同!
andy833john + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

jubaicc 发表于 2025-7-17 10:15
浏览器直接勇敢油猴插件比较方便。
zpwz 发表于 2025-7-17 10:32
qzquzhou 发表于 2025-7-17 10:41
naixubao 发表于 2025-7-17 10:45
楼主,你好。你分享的源码应该怎么使用啊?是把源码复制到文本文件里还是有专门的工具呢。
sutramusic 发表于 2025-7-17 11:51
naixubao 发表于 2025-7-17 10:45
楼主,你好。你分享的源码应该怎么使用啊?是把源码复制到文本文件里还是有专门的工具呢。

要安装python的客户端,
在那里面运行,这是源码。
jian19950220 发表于 2025-7-17 12:25
和小米高考ocr识别类是吧
51cbb 发表于 2025-7-17 13:25
这个想法很有趣!
top777 发表于 2025-7-17 13:55
建议将代码放入论坛帖子的“添加代码文字”中(在MD按钮旁边)
cick 发表于 2025-7-17 13:58

楼主考虑下我们小众用户改造下呗,搞成mac也可以ocr识别就好了image

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-4-18 06:59

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表