基于paddleocr制作的截图+文字识别程序,非接口,利用自身GPU计算

一、截图与文本识别小工具的制作

  1. 工具设计

该截图与文本识别小工具的设计主要包括以下几个部分:

  • 截图模块:负责截取屏幕内容,并将截取的图片保存到本地文件夹内。
  • OCR模块:调用Paddle OCR库,对截取的图片进行文本识别,并将识别结果以文本形式输出。
  • 用户界面:提供简洁明了的操作界面,方便用户进行截图和文本识别操作。

  1. 技术实现
  • 截图模块的实现:使用第三方截图库tkinter与PIL进行截图操作,可以用鼠标自由选择截屏范围,并保存截取的图片。
  • OCR模块的实现:引入Paddle OCR库,然后调用Paddle OCR的识别进行文本识别,在第一次识别中会自动下载轻量化的OCR模型库。识别结果会输出到用户界面,结果包括txt文本。
  • 用户界面的实现:使用图形用户界面(GUI)框架Tkinter设计简洁明了的操作界面,包括截图按钮、识别按钮、结果显示框等。通过信号或事件监听器实现用户界面的交互逻辑。

  1. 部署与测试
  • 部署:条件较复杂,由于是非联网、非接口的,离线OCR模型库。需要利用机载的GPU或者CPU进行计算,要求具备计算能力在3.5以上的GPU或其它,并且安装有Paddle适配版本的CUDA与Cudnn软件,且安装有满足Paddle需求的第三方库,详情见官方文档“Paddle的Windows部署教程”。
  • 测试:在多种场景下对工具进行测试,包括不同字体、大小、布局和背景的文本识别效果测试,以及截图和识别功能的稳定性和性能测试。对于中文的识别效果较好,英文也适用,但缺乏其他语种的切换功能。

二、使用示例

假设用户需要识别一张图片中的文字内容,可以使用该截图与文本识别小工具进行如下操作:

  1. 打开工具并点击截图按钮,截取需要识别的图片区域,然后自主选择保存位置。

 

                                                                图1  工具界面示意图

  1. 点击识别按钮,会自动识别本次截屏图片,等待工具调用Paddle OCR进行文本识别。
  2. 识别完成后,工具会将识别结果以文本形式显示在结果显示框中。用户可以根据需要对识别结果进行复制、编辑或导出等操作。

 

 

图2  识字结果示意图

三、缺点与不足  

  1. 识别语种少,仅支持中文、英文和数字,后续将不断优化出切换不同语种功能的按钮。
  2. 由于调用的OCRC超轻量级模型,大小仅8.6M,所以在识别文字方面,置信度会偏低,时而会出现不准确现象。
  3. 调用模型简单,所以对图片缺乏预处理,对图片要求较高,常常会出现输出为0的情况。
  4. 由于使用机载的GPU核心计算,由于算力的不同,在识字时会出现不同程度的卡顿属于正常现象,但也无法避免。
  5. 由于截屏算法的底层逻辑有所问题,导致Windows系统在笔记本或其他设备下,在文本缩放不为100%时,截图会出现偏差BUG,后续也将会优化解决。

 

 

完整代码如下:

#程序中部分代码非原创,参考自CSDN“【Python】用Tkinter实现一个简单的任意区域截图软件”一文中截图功能的实现

#调用paddleOCR代码文字识别部分参考自Paddle官方“十分钟掌握PaddleOCR使用”一文

#AI工具“文心一言”对代码完善亦有帮助

import os
import tkinter
import tkinter.filedialog
import time
from PIL import ImageGrab
from paddleocr import PaddleOCR

a=[]
b=[]
class FreeCapture():


    def __init__(self, root, img):
        # 变量X和Y用来记录鼠标左键按下的位置
        self.X = tkinter.IntVar(value=0)
        self.Y = tkinter.IntVar(value=0)
        # 屏幕尺寸
        screenWidth = root.winfo_screenwidth()
        screenHeight = root.winfo_screenheight()
        # 创建顶级组件容器
        self.top = tkinter.Toplevel(root, width=screenWidth, height=screenHeight)
        # 不显示最大化、最小化按钮
        self.top.overrideredirect(True)
        self.canvas = tkinter.Canvas(self.top, bg='white', width=screenWidth, height=screenHeight)
        # 显示全屏截图,在全屏截图上进行区域截图
        self.image = tkinter.PhotoImage(file=img)
        self.canvas.create_image(screenWidth // 2, screenHeight // 2, image=self.image)

        self.lastDraw = None

        # 鼠标左键按下的位置
        def onLeftButtonDown(event):
            self.X.set(event.x)
            self.Y.set(event.y)
            # 开始截图
            self.sel = True

        self.canvas.bind('<Button-1>', onLeftButtonDown)

        def onLeftButtonMove(event):
            # 鼠标左键移动,显示选取的区域
            if not self.sel:
                return
            try:  # 删除刚画完的图形,要不然鼠标移动的时候是黑乎乎的一片矩形
                self.canvas.delete(self.lastDraw)
            except Exception as e:
                pass
            self.lastDraw = self.canvas.create_rectangle(self.X.get(), self.Y.get(), event.x, event.y, outline='green')

        def onLeftButtonUp(event):
            # 获取鼠标左键抬起的位置,保存区域截图
            self.sel = False
            try:
                self.canvas.delete(self.lastDraw)
            except Exception as e:
                pass

            time.sleep(0.5)
            # 考虑鼠标左键从右下方按下而从左上方抬起的截图
            left, right = sorted([self.X.get(), event.x])
            top, bottom = sorted([self.Y.get(), event.y])
            pic = ImageGrab.grab((left + 1, top + 1, right, bottom))
            # 弹出保存截图对话框
            fileName = tkinter.filedialog.asksaveasfilename(title='保存截图', filetypes=[('image', '*.jpg *.png')],
                                                            defaultextension='.jpg')
            if fileName:
                pic.save(fileName)
                a.append(fileName)
            self.top.destroy()


        self.canvas.bind('<B1-Motion>', onLeftButtonMove)  # 按下左键
        self.canvas.bind('<ButtonRelease-1>', onLeftButtonUp)  # 抬起左键
        # 让canvas充满窗口,并随窗口自动适应大小
        self.canvas.pack(fill=tkinter.BOTH, expand=tkinter.YES)


def screenShot():
    """ 自由截屏的函数 (button按钮的事件)
    """
    #    print("test")
    root.state('icon')  # 最小化主窗体
    time.sleep(0.2)
    im = ImageGrab.grab()
    # 暂存全屏截图
    im.save('temp.png')
    im.close()
    # 进行自由截屏
    w = FreeCapture(root, 'temp.png')
    button_screenShot.wait_window(w.top)
    # 截图结束,恢复主窗口
    root.state('normal')
    os.remove('temp.png')



def f():
    ocr = PaddleOCR(use_angle_cls=True, lang='ch')  # 你可以修改 'lang' 参数来适应不同的语言
    image_path = a[-1]
    result = ocr.ocr(image_path)
    s=""
    for line in result:
        line_text = ''.join([word_info[1][0] for word_info in line])
        print(line_text)
        b.append(line_text)
    a.pop(-1)
    main()
    b.clear()
    result=""
def append_to_text(text_widget, text):
    """在Text组件的末尾追加文本"""

    text_widget.insert(tkinter.END, text + '\n')  # \n用于在文本末尾添加新行


def main():
    root = tkinter.Tk()

    root.title("识字结果")

    # 创建一个Text组件作为结果输出框

    result_text = tkinter.Text(root, height=10, width=50)  # 你可以根据需要调整高度和宽度

    result_text.pack(pady=20)  # 使用pack布局管理器放置Text组件,并添加一些垂直填充

    # 示例:向Text组件中追加一些文本
    my_list_str = list(map(str, b))

    # 使用join()方法将列表转换为字符串
    result = ', '.join(my_list_str)

    append_to_text(result_text, result)


    # 开始tkinter的主事件循环

    root.mainloop()

####
root = tkinter.Tk()
root.title('截屏与识图工具by Aloha')

# 指定窗口的大小
root.geometry('500x250')
# 不允许改变窗口大小
root.resizable(False, False)

# ================== 布置截屏按钮 ====================================
button_screenShot = tkinter.Button(root, text='截屏', command=screenShot)
button_screenShot.place(relx=0.2, rely=0.35, relwidth=0.25, relheight=0.25)

button_screenShot = tkinter.Button(root, text='识字', command=f)
button_screenShot.place(relx=0.6, rely=0.35, relwidth=0.25, relheight=0.25)
# ================== 完 =============================================
label = tkinter.Label(root, text="截屏要求Windows文本缩放为100%才可正常截屏,识字利用GPU运算卡顿正常现象")
label.pack(side=tkinter.BOTTOM, fill=tkinter.X, pady=10)
try:
    root.mainloop()
except:
    root.destroy()

 

  • 19
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值