实战--基于PYQT5的PaddleOCR摄像头文字识别软件搭建(附源码)

前言

OCR,即 Optical Character Recognition,是光学字符识别的简称。它是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,通过检测暗、亮的模式确定其形状,然后用字符识别方法将形状翻译成计算机文字的过程。简言之,OCR 技术可以将纸质文档中的文字转换成为黑白点阵的图像文件,并通过识别软件将图像中的文字转换成文本格式,供文字处理软件进一步编辑加工。

一、PaddleOCR简介

基于飞桨的OCR工具库,该项目名叫 PaddleOCR,是 Paddle 的一个分支;PaddleOCR 基于深度学习技术实现的, 所以使用时需要训练好的权重文件,但这个不需要我们担心,因为官方提供的有。包含总模型仅8.6M的超轻量级中文OCR,单模型支持中英文数字组合识别、竖排文本识别、长文本识别。同时支持多种文本检测、文本识别的训练算法。

二、环境搭建

1.安装pycharm

进入jetbrains官方网站,下载pycharm安装包,这里安装的是community社区版
https://www.jetbrains.com/pycharm/download/
安装的过程比较简单,网上的安装详细步骤有很多,这里不再赘述,基本上一路next即可,最后安装成功的效果如下图所示

在这里插入图片描述

2.安装QT designer,pyuic等工具包

在Python中使用PyQt这一工具包,它是Python编程语言和Qt库的成功融合。在pycharm IDE中,内置的UI界面设计工具QT designer和文件转换工具PYUIC(主要功能是将Qt Designer生成的.ui文件转换成相应的代码文件.py文件,十分高效!!),可以帮助用户更高效的基于python,开发相应的图形化界面。安装步骤网上也有很多,最终安装成功的效果如下图所示,即右击工程文件,在外部工具栏中可以看到已经安装好的插件

在这里插入图片描述

3.安装pyinstaller

pyinstaller是一个在python中用于将工程文件打包成软件的插件,打包后的软件可以复现出工程文件中实现的功能,具体安装步骤可以参考https://blog.csdn.net/qq_43703185/article/details/119342713来进行

三.代码实现

接下来进入正题,代码实现,主要分为以下几个部分

1.摄像头基本功能

这里调用的是笔记本自带的摄像头,实时拍摄画面,主要分为添加按钮,通过按钮打开摄像头,摄像头画面展示,展示图像实时更新四个部分,代码如下:

 #摄像头传入图像实时更新
    def updateFrame(self):
        ret, frame = self.cap.read()
        if ret:
            self.show_cv_img(frame)


    #开启摄像头按键功能设置
    def video_button(self,status):
        #self.flag = 0
        if(status):
        #if (self.flag == 0):
        #    self.cap_video = cv2.VideoCapture(0)
            self.cap.open(0)
            self.pushButton.setEnabled(True)
            #self.flag += 1
            ret, frame = self.cap.read()
            if not ret:
                self.cap.release()
            else:
                self.video.setText("Close")
                self.timer.start(50)
        else:
            self.pushButton.setEnabled(False)
            if self.cap.isOpened():
                if self.timer.isActive():
                    self.timer.stop()
                self.cap.release()
                self.label.clear()
                self.label.setText('<font color=red>摄像头未开启</font>')
                self.video.setText('Open')


    def show_cv_img(self,img):
        shrink = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
        QtImg = QtGui.QImage(shrink.data,
                             shrink.shape[1],
                             shrink.shape[0],
                             shrink.shape[1] * 3,
                             QtGui.QImage.Format_RGB888)
        jpg_out = QtGui.QPixmap(QtImg).scaled(self.label.width(),self.label.height())
        self.label.setPixmap(jpg_out)   

2.导入PaddleOCR文字识别模型

这一步是整个过程的核心,调用现成的文字识别模型来对文字进行识别,这里调用的是百度的PaddleOCR模型。值得一提的是,本人在整个实践的过程中遇到过联网和离线两种状态的情况。如果是联网状态,可以先申请百度云文字识别ID和密钥,然后直接调用OCR模型即可;如果是离线状态,则可以在github上下载PaddleOCR接口文件,然后在工程中实现调用(下载链接:https://github.com/hiroi-sora/PaddleOCR-json/releases)。两种方法均可实现,代码如下:

联网方法:

#对图片文字进行提取
from aip import AipOcr  #baidu-aip

config = {
    'appId':'自己的ID',
    'apiKey':'自己的key',
    'secretKey':'自己的key'
}

client = AipOcr(**config)  #创建客户类调用百度api接口

def get_file_content(file):  #获取图像内容,传入参数为图片文件
    with open(file,'rb') as f:   #二进制形式打开文件
        return f.read()

def img_to_str(image_path):  #将图片里的文字识别出来,传入参数为图片路径
    image = get_file_content(image_path)
    result = client.basicAccurate(image)  #调用百度云库以提取图像中的文字
    #print(result)
    if 'words_result' in result:   #把图片里的文字提取出来放到一个字符串里
        return '\n'.join([w['words'] for w in result['words_result']])


res = img_to_str(r'自己对应的图片路径')   #写入图片路径,r为取消转义字符以用来表示文件路径
print(res)
#print(a)   #此步为打印图片二进制数据

离线方法:

from PPOCR_api import GetOcrApi
import os
import PPOCR_api

from PyQt5.QtWidgets import *
from PyQt5 import QtCore,QtGui,QtWidgets
from PyQt5.QtWidgets import QMainWindow, QApplication



ocr = GetOcrApi(r"C:\Users\20605\Downloads\PaddleOCR-json_v.1.3.0\PaddleOCR-json.exe")   #调用PaddleOCR接口,这里需要换成自己下载的路径
print(f'初始化OCR成功,进程号为{ocr.ret.pid}')



def img_to_str(image_path):  #将图片里的文字识别出来,传入参数为图片路径
    with open(image_path, 'rb') as f: # 获取图片字节流
        imageBytes = f.read() # 实际使用中,可以联网下载或者截图获取字节流,直接送入OCR,无需保存到本地中转。
    result = ocr.runBytes(imageBytes)    #调用paddle-ocr库以识别提取文字
    ocr.printResult(result)
    #print(result)
    if 'data' in result:  # 把图片里的文字提取出来放到一个字符串里,注意参数‘data','text'是由result原始打印结果所填写
        return '\n'.join([w['text'] for w in result['data']])


res = img_to_str(r'C:\Users\20605\Desktop\1.jpg')   #写入图片路径,r为取消转义字符以用来表示文件路径
#print(res)
#print(a)   #此步为打印图片二进制数据  

3.采集图片

这一步是调用之前的功能函数,实现图片拍摄后的文字识别代码如下

    def take_picture(self):
        ret, frame = self.cap.read()
        filename = 'log'
        text_create(filename)   #创建txt文本并命名
        output = sys.stdout
        outputfile = open("C:\\Users\\20605\\Desktop\\" + filename + '.txt', 'a')  #以权限a的方式写入文件,不会覆盖掉之前的内容
        sys.stdout = outputfile

        if ret:
             # filename = "frame.jpg"   #调用百度云部分上位机打印文字代码
             # cv2.imwrite(filename, frame)
             # s = demo_recognition.img_to_str(filename)
             # print(s)
             # self.textBrowser.append(s)


             cv2.imwrite(TestImagePath, frame)
             s = demo_recognition.img_to_str(TestImagePath)   #img_to_str函数通过return返回值赋值给s
             self.textBrowser.append(s)   #将识别出的文字输出到上位机上

             print(file=outputfile)   #将识别出的文字输出到txt中
             outputfile.close()  # close后才能看到写入的数据

四.将工程打包成可执行文件并测试

最后一步,将之前实现好的工程,调用pyinstaller工具库将其打包,打包的时间可能有点长,需要耐心等待一下,最终打包后的效果以及文字识别效果展示如图
打包后的软件

最终文字识别

可以看到,文字识别的效果还是挺不错,并且可以识别大部分字体。


总结

以上就是本篇博客的全部内容。当然,需要改进的地方还有很多。比如说文字识别后文字在介面框中的排版,需要做文字拼接等后处理工作;再比方说,如果摄像头帧率过高,图片在镜头前晃动过大,可能导致软件卡崩,这需要在软件打包以及算法优化上做处理。并且,这里只是调用现成的文字识别模型,工程总体来说难度不大,还是比较容易实现,后续对于OCR模型本身的研究才是重点。总的来说,第一次写博客,肯定有许多不足之处,希望各位大佬批评指正,多多交流。

附: 部分源代码,单独创建demo_recognition脚本并添加“导入PaddleOCR文字识别模型”部分代码即可

import base64
import requests
import os
from read_img import PPOCR_api
import sys
from read_img import read_image_ui
from PyQt5.QtWidgets import *
import cv2
from PyQt5 import QtCore,QtGui,QtWidgets
from PyQt5.QtWidgets import QMainWindow, QApplication
from read_img import demo_recognition
from read_img.output_txt import text_create
from read_img.PPOCR_api import GetOcrApi


# 测试图片路径
TestImagePath = f"{os.path.dirname(os.path.abspath(__file__))}\\test.jpg"

class test_ui(QMainWindow,read_image_ui.Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.timer = QtCore.QTimer()
        self.cap = cv2.VideoCapture()   #打开摄像头
        self.timer.timeout.connect(self.updateFrame)   #更新摄像头图片
        self.video.clicked.connect(self.video_button)  #初始化开启摄像头按键功能
        self.video.setCheckable(True)
        self.pushButton.clicked.connect(self.take_picture)   #初始化拍照按键功能
        self.cap_video = 0
        self.count = 0   #计数标志位
        self.img = []

    #摄像头传入图像实时更新
    def updateFrame(self):
        ret, frame = self.cap.read()
        if ret:
            self.show_cv_img(frame)


    #开启摄像头按键功能设置
    def video_button(self,status):
        #self.flag = 0
        if(status):
        #if (self.flag == 0):
        #    self.cap_video = cv2.VideoCapture(0)
            self.cap.open(0)
            self.pushButton.setEnabled(True)
            #self.flag += 1
            ret, frame = self.cap.read()
            if not ret:
                self.cap.release()
            else:
                self.video.setText("Close")
                self.timer.start(50)
        else:
            self.pushButton.setEnabled(False)
            if self.cap.isOpened():
                if self.timer.isActive():
                    self.timer.stop()
                self.cap.release()
                self.label.clear()
                self.label.setText('<font color=red>摄像头未开启</font>')
                self.video.setText('Open')

            #self.timer.stop()
            #self.cap_video.release()
            #self.label.clear()
            #self.video.setText("Open")

    # def show_video(self):
    #     ret, self.img = self.cap_video.read()
    #     if ret:
    #         self.show_cv_img(self.img)

    def show_cv_img(self,img):
        shrink = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
        QtImg = QtGui.QImage(shrink.data,
                             shrink.shape[1],
                             shrink.shape[0],
                             shrink.shape[1] * 3,
                             QtGui.QImage.Format_RGB888)
        jpg_out = QtGui.QPixmap(QtImg).scaled(self.label.width(),self.label.height())
        self.label.setPixmap(jpg_out)



    def take_picture(self):
        ret, frame = self.cap.read()
        filename = 'log'
        text_create(filename)   #创建txt文本并命名
        output = sys.stdout
        outputfile = open("C:\\Users\\20605\\Desktop\\" + filename + '.txt', 'a')  #以权限a的方式写入文件,不会覆盖掉之前的内容
        sys.stdout = outputfile

        if ret:
             # filename = "frame.jpg"   #调用百度云部分上位机打印文字代码
             # cv2.imwrite(filename, frame)
             # s = demo_recognition.img_to_str(filename)
             # print(s)
             # self.textBrowser.append(s)


             cv2.imwrite(TestImagePath, frame)
             s = demo_recognition.img_to_str(TestImagePath)   #img_to_str函数通过return返回值赋值给s
             self.textBrowser.append(s)   #将识别出的文字输出到上位机上

             print(file=outputfile)   #将识别出的文字输出到txt中
             outputfile.close()  # close后才能看到写入的数据


if __name__ == "__main__":

    app = QApplication(sys.argv)
    win = test_ui()
    win.show()
    sys.exit(app.exec_())

参考链接:
OCR介绍部分
https://blog.csdn.net/xhmico/article/details/137671583
https://blog.csdn.net/weixin_45897172/article/details/131406224
摄像头读图部分
https://www.bilibili.com/video/BV1Pa4y147LY/?spmidfrom=333.337.search-card.all.click&vd_source=c4f360981aa4bb15debb8ab108d9956d
paddleocr接口部分
https://github.com/hiroi-sora/Umi-OCR
PYQT5上位机部分
https://www.bilibili.com/video/BV1nu411b72B/?spmidfrom=333.788&vd_source=c4f360981aa4bb15debb8ab108d9956d

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值