欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

荐 使用Python PyQt5实现一个简单的图像识别软件

程序员文章站 2022-03-04 09:27:56
关于图片和文字识别问题,采用Python、QT编程方法,借助百度AI提供的图像识别接口,制作出一个简单的图片文字识别软件;达到了对银行卡、身份证、植物和动物图像的识别功能,实现了对识别结果进行复制功能。...

摘要:之前学习了tkinter库,现在再学习一下python的另一个GUI库——PyQt5,本文主要介绍如何使用Python PyQt5实现一个简单的图像识别软件的步骤。

1.开发环境

语言:python3
开发工具:pycharm
工具库:
PyQt5 5.12.1
pyqt5-tools 5.11.2.1.3
注:导入上面两个库要先导入sip库

2.简介

介绍:关于图片和文字识别问题,采用Python、QT编程方法,借助百度AI提供的图像识别接口,制作出一个简单的图片文字识别软件;达到了对银行卡、身份证、植物和动物图像的识别功能,实现了对识别结果进行复制功能。

主要工作:
1.UI界面的设计
2.整个程序函数的书写(功能实现)
3.软件的测试与打包

3.效果图

我已经将程序打包成了可以执行的python.exe文件,并放到了桌面,点击即可运行。
荐
                                                        使用Python PyQt5实现一个简单的图像识别软件
点击运行后:
荐
                                                        使用Python PyQt5实现一个简单的图像识别软件

4.开发步骤

4.1导入所需的库

使用pip命令或者通过pycharm导入都可,以下是需要导入的库。

sip
PyQt5 5.12.1             
pyqt5-tools 5.11.2.1.3

4.2设计GUI界面

1.通过QtDesigner方式设计UI界面,要先在pycharm上配置好扩展工具
file——>settings——>Tools——>ExternalTools
荐
                                                        使用Python PyQt5实现一个简单的图像识别软件
要添加两个工具,一个用来设计GUI,另一个用来把设计好的GUI变成python代码文件。
用来设计GUI的工具创建如下图:
荐
                                                        使用Python PyQt5实现一个简单的图像识别软件
把设计好的GUI变成python代码文件的工具创建如下图:
设置:
第一个框 设置名称
第二个框 设置python解释器路径(就是虚拟环境下的scripts\python.exe)
第三个框

 -m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py

第四个框:

$FileDir$

荐
                                                        使用Python PyQt5实现一个简单的图像识别软件
查看是否创建成功,选中一个.py文件,右键;如下图所示,如果出现刚刚创建的即可:
荐
                                                        使用Python PyQt5实现一个简单的图像识别软件
以上是使用QtDesigner设计GUI界面的准备工作,如果你有QtDesigner基础,上面的可以直接不看。

2.正式设计软件的界面
2.1点击下图按钮
荐
                                                        使用Python PyQt5实现一个简单的图像识别软件
2.2点击后出现下面界面,这里是设计GUI的界面,这里可以拖动标签和按钮来设计自己想要的软件界面。
荐
                                                        使用Python PyQt5实现一个简单的图像识别软件
2.3设计好后的效果
荐
                                                        使用Python PyQt5实现一个简单的图像识别软件
3.把设计好的ui文件转成py文件,选中刚刚创建好的ui文件,使用第二个扩展工具,即可生成同名的.py文件
荐
                                                        使用Python PyQt5实现一个简单的图像识别软件

4.3整个程序函数的书写(功能实现)

主要在上面生成的.py文件里修改完善软件功能。添加点击事件和识别调用接口以及函数功能的完善。

值得一提的是,这里主要是调用了百度AI提供的图像文字识别接口,而我们的主要任务就是整个软件的逻辑控制和功能拼接。以及对返回数据进行解析和数据可视化。

荐
                                                        使用Python PyQt5实现一个简单的图像识别软件

网址:点击前往百度智能云

整个软件的全部代码如下,里面包含详细的注释:

# -*- coding: utf-8 -*-

"""
2020.7.8  yue AI图片识别软件

介绍:关于图片和文字识别问题,采用Python、QT编程方法,借助百度AI提供的图像识别接口,制作出一个简单的图片文字识别软件;达到了对银行卡、身份证、植物和动物图像的识别功能,实现了对识别结果进行复制功能。

主要工作:
1.UI界面的设计
2.整个程序函数的书写(功能实现)
3.软件的测试与打包

"""


# Form implementation generated from reading ui file 'imgreconition.ui'
#
# Created by: PyQt5 UI code generator 5.12.1
#
# WARNING! All changes made in this file will be lost!
import json
import sys

import requests
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

import urllib,urllib.request
import ssl

import base64

#自己申请到的 图像文字识别 文字识别
API_KEY = ' '
SECRET = ' '

# 另外获取token值 图像识别
P_KEY = '  '
P_SECRET = '  '

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(597, 471)
        self.horizontalLayoutWidget = QtWidgets.QWidget(Form)
        self.horizontalLayoutWidget.setGeometry(QtCore.QRect(90, 50, 171, 31))
        self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.label = QtWidgets.QLabel(self.horizontalLayoutWidget)
        self.label.setObjectName("label")
        self.horizontalLayout.addWidget(self.label)
        self.comboBox = QtWidgets.QComboBox(self.horizontalLayoutWidget)
        self.comboBox.setObjectName("comboBox")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.horizontalLayout.addWidget(self.comboBox)
        self.horizontalLayoutWidget_2 = QtWidgets.QWidget(Form)
        self.horizontalLayoutWidget_2.setGeometry(QtCore.QRect(40, 100, 271, 31))
        self.horizontalLayoutWidget_2.setObjectName("horizontalLayoutWidget_2")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_2)
        self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.label_2 = QtWidgets.QLabel(self.horizontalLayoutWidget_2)
        self.label_2.setObjectName("label_2")
        self.horizontalLayout_2.addWidget(self.label_2)
        self.lineEdit = QtWidgets.QLineEdit(self.horizontalLayoutWidget_2)
        self.lineEdit.setObjectName("lineEdit")
        self.horizontalLayout_2.addWidget(self.lineEdit)
        self.pushButton = QtWidgets.QPushButton(self.horizontalLayoutWidget_2)
        self.pushButton.setObjectName("pushButton")
        self.horizontalLayout_2.addWidget(self.pushButton)
        self.label_3 = QtWidgets.QLabel(Form)
        self.label_3.setGeometry(QtCore.QRect(40, 140, 271, 261))
        #self.label_3.setStyleSheet("background-color: rgb(255, 255, 127);")
        self.label_3.setStyleSheet("border-width: 1px;border-style: solid;boder-color: rgb(0,0,0);")
        self.label_3.setText("")
        self.label_3.setObjectName("label_3")
        self.label_4 = QtWidgets.QLabel(Form)
        self.label_4.setGeometry(QtCore.QRect(330, 50, 241, 321))
        #self.label_4.setStyleSheet("background-color: rgb(85, 255, 0);")
        self.label_4.setStyleSheet("border-width: 1px;border-style: solid;boder-color: rgb(0,0,0);")
        self.label_4.setText("")
        self.label_4.setObjectName("label_4")
        self.pushButton_2 = QtWidgets.QPushButton(Form)
        self.pushButton_2.setGeometry(QtCore.QRect(330, 380, 241, 23))
        self.pushButton_2.setObjectName("pushButton_2")

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "AI图片识别软件"))
        self.label.setText(_translate("Form", "选择识别类型:"))
        self.comboBox.setItemText(0, _translate("Form", "银行卡"))
        self.comboBox.setItemText(1, _translate("Form", "植物"))
        self.comboBox.setItemText(2, _translate("Form", "动物"))
        self.comboBox.setItemText(3, _translate("Form", "通用票据"))
        self.comboBox.setItemText(4, _translate("Form", "营业执照"))
        self.comboBox.setItemText(5, _translate("Form", "身份证"))
        self.comboBox.setItemText(6, _translate("Form", "车牌号"))
        self.comboBox.setItemText(7, _translate("Form", "驾驶证"))
        self.comboBox.setItemText(8, _translate("Form", "行驶证"))
        self.comboBox.setItemText(9, _translate("Form", "车型"))
        self.comboBox.setItemText(10, _translate("Form", "logo"))
        self.label_2.setText(_translate("Form", "选择要识别的图片:"))
        self.pushButton.setText(_translate("Form", "选择"))
        self.pushButton_2.setText(_translate("Form", "复制导粘贴板"))
        #为选择按钮添加点击事件
        self.pushButton.clicked.connect(self.openfile)
        #为复制按钮添加点击事件
        self.pushButton_2.clicked.connect(self.copyText)
    #复制功能函数
    def copyText(self):
        clipboard = QApplication.clipboard()
        clipboard.setText(self.label_4.text())
    #打开文件函数
    def openfile(self):
        self.download_path = QFileDialog.getOpenFileName(self.horizontalLayoutWidget_2,"选择要识别的图片","/","Image File(*.jpg *.png)")
        if not self.download_path[0].strip():
            pass
        else:
            #print(self.download_path[0])
            #把图片路径显示
            self.lineEdit.setText(self.download_path[0])
            #显示选择的图片 自动解析图片
            pixmap = QPixmap(self.download_path[0])
            #处理图片  规定大小
            scarePixmap = pixmap.scaled(QSize(271,261),aspectRatioMode=Qt.KeepAspectRatio)
            #把图片设置到控件里
            self.label_3.setPixmap(scarePixmap)
            #通过百度ai接口来识别特定类别的图片
            self.typeTp()
    #类别 识别
    def typeTp(self):
        #银行卡
        if self.comboBox.currentIndex()==0:
            #获取token值
            self.get_bankcard(self.get_token())
        #植物
        if self.comboBox.currentIndex()==1:
            #识别植物
            self.get_plant(self.img_get_token())
        #动物
        if self.comboBox.currentIndex()==2:
            # 识别动物
            self.get_animal(self.img_get_token())
        #....
        #身份证
        if self.comboBox.currentIndex()==5:
            self.get_idcard(self.get_token())

    #获取token  文字识别
    def get_token(self):
        # client_id 为官网获取的AK, client_secret 为官网获取的SK
        host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id='+API_KEY+'&client_secret='+SECRET
        response = requests.get(host)
        if response:
            #print(response.json())
            self.access_token = response.json()['access_token']
            return self.access_token

    # 获取token  图像识别
    def img_get_token(self):
        # client_id 为官网获取的AK, client_secret 为官网获取的SK
        host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id='+P_KEY+'&client_secret='+P_SECRET
        response = requests.get(host)
        if response:
            #print(response.json())
            self.access_token = response.json()['access_token']
            return self.access_token
    #身份证识别
    def get_idcard(self,access_token):
        '''
        身份证识别
        '''

        request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard"
        # 二进制方式打开图片文件
        f = open(self.download_path[0], 'rb')
        img = base64.b64encode(f.read())

        params = {"id_card_side": "front", "image": img}
        request_url = request_url + "?access_token=" + access_token
        headers = {'content-type': 'application/x-www-form-urlencoded'}
        response = requests.post(request_url, data=params, headers=headers)
        if response:
            rs = response.json()
            #print(response.json())
            #print(rs['words_result']['姓名']['words'])
            #读取数据
            strover = '识别结果:\n'
            try:
                strover += '姓名:{}\n性别:{}\n身份证号:{}\n出生年月: {}\n住址:{}'.format(rs['words_result']['姓名']['words'],
                            rs['words_result']['性别']['words'],rs['words_result']['公民身份号码']['words'],rs['words_result']['出生']['words'],rs['words_result']['住址']['words'])
            except Exception:
                strover+='解析错误'
            #把结果显示到控件
            self.label_4.setText(strover)
    #动物识别函数
    def get_animal(self,access_token):
        '''
        动物识别
        '''
        request_url = "https://aip.baidubce.com/rest/2.0/image-classify/v1/animal"
        # 二进制方式打开图片文件
        f = open(self.download_path[0], 'rb')
        img = base64.b64encode(f.read())

        params = {"image":img}
        request_url = request_url + "?access_token=" + access_token
        headers = {'content-type': 'application/x-www-form-urlencoded'}
        response = requests.post(request_url, data=params, headers=headers)
        if response:
            rs = response.json()
            #print(response.json())
            # 读取数据
            strover = '识别结果:\n'
            try:
                i = 1
                for animal in rs['result']:
                    strover += '{}.动物名称:  {}   置信度:  {:.6}\n'.format(i,animal['name'],animal['score'])
                    i += 1
            except Exception:
                strover += '解析错误'
            # 把结果显示到控件
            self.label_4.setText(strover)


    #银行卡识别函数
    def get_bankcard(self,access_token):
        request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/bankcard"
        # 二进制方式打开图片文件
        f = open(self.download_path[0], 'rb')
        img = base64.b64encode(f.read())
        params = {"image": img}
        #params = urllib.parse.urlencode(params).encode('utf-8')
        request_url = request_url + "?access_token=" + access_token
        headers = {'content-type': 'application/x-www-form-urlencoded'}
        response = requests.post(request_url, data=params, headers=headers)
        if response:
            # 解析返回的数据
            rs = response.json()
            #print(response.json())
            #读取数据
            strover = '识别结果:\n'
            try:
                if rs['result']['bank_card_type'] == 0:
                    bank_card_type = '不能识别'
                elif rs['result']['bank_card_type'] == 1:
                    bank_card_type = '借记卡'
                elif rs['result']['bank_card_type'] == 2:
                    bank_card_type = '信用卡'
                strover += '卡号:   {}\n银行:   {}\n类型:   {}'.format(rs['result']['bank_card_number'],
                                                                 rs['result']['bank_name'], bank_card_type)
            except Exception:
                strover+='解析错误'
            #把结果显示到控件
            self.label_4.setText(strover)

    #植物识别函数
    def get_plant(self,access_token):
        '''
        植物识别
        '''
        request_url = "https://aip.baidubce.com/rest/2.0/image-classify/v1/plant"
        # 二进制方式打开图片文件
        f = open(self.download_path[0], 'rb')
        img = base64.b64encode(f.read())

        params = {"image": img}
        request_url = request_url + "?access_token=" + access_token
        headers = {'content-type': 'application/x-www-form-urlencoded'}
        response = requests.post(request_url, data=params, headers=headers)
        if response:
            # 解析返回的数据
            rs = response.json()
            #print(response.json())
            # 读取数据
            strover = '识别结果:\n'
            try:
                i = 1
                for plant in rs['result']:
                    strover += '{}.植物名称:  {}   置信度:  {:.6}\n'.format(i,plant['name'],plant['score'])
                    i+=1
            except Exception:
                strover += '解析错误'
            # 把结果显示到控件
            self.label_4.setText(strover)




if __name__ == '__main__':
  app = QtWidgets.QApplication(sys.argv)
  mainWindow = QtWidgets.QMainWindow()
  ui = Ui_Form()
  ui.setupUi(mainWindow)
  mainWindow.show()
  sys.exit(app.exec_())


'''
1.QFileDialog.getOpenFileName(self.horizontalLayoutWidget_2,"选择要识别的图片","/","Image File(*.jpg *.png)")
  getOpenFileName返回一个被用户选中的文件的路径,前提是这个文件是存在的。
  第一个参数parent,用于指定父组件。注意,很多Qt组件的构造函数都会有这么一个parent参数,并提供一个默认值0;
  第二个参数caption,是对话框的标题;
  第三个参数dir,是对话框显示时默认打开的目录,"." 代表程序运行目录,"/" 代表当前盘符的根目录(Windows,Linux下/就是根目录了),也可以是平台相关的,比如"C:\\"等;例如我想打开程序运行目录下的Data文件夹作为默认打开路径,这里应该写成"./Data/",若想有一个默认选中的文件,则在目录后添加文件名即可:"./Data/teaser.graph"
  第四个参数filter,是对话框的后缀名过滤器,比如我们使用"Image Files(*.jpg *.png)"就让它只能显示后缀名是jpg或者png的文件。如果需要使用多个过滤器,使用";;"分割,比如"JPEG Files(*.jpg);;PNG Files(*.png)";
  第五个参数selectedFilter,是默认选择的过滤器;
  第六个参数options,是对话框的一些参数设定,比如只显示文件夹等等,它的取值是enum QFileDialog::Option,每个选项可以使用 | 运算组合起来。
  如果我要想选择多个文件怎么办呢?Qt提供了getOpenFileNames()函数,其返回值是一个QStringList。你可以把它理解成一个只能存放QString的List,也就是STL中的list<string>。

2.QPixmap类用于绘图设备的图像显示,它可以作为一个QPaintDevice对象,也可以加载到一个控件中,通常是标签或按钮,用于在标签或按钮上显示图像。
  QPixmap可以读取的图像文件类型有BMP、GIF、JPG、JPEG、PNG、PBM、PGM、PPM、XBM、XPM等。
  利用QImage、QPxmap类可以实现图像的显示,并且利用类中的方法可以实现图像的基本操作(缩放、旋转)。
  
3.QApplication.clipboard()

4.完善运行测试代码,如下:
if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    main = QtWidgets.QMainWindow()#创建一个主窗体(必须要有一个主窗体)
    content = SimpleDialogForm()#创建对话框
    content.setupUi(main)#将对话框依附于主窗体
    main.show()#主窗体显示
    sys.exit(app.exec_())
  
  '''

4.4把程序打包成可执行文件

1.先导入Pyinstaller库
2.打开终端
荐
                                                        使用Python PyQt5实现一个简单的图像识别软件
3.输入以下命令:

pyinstaller -F -w  文件名.py

-F 是用于将所有的支持文件全部都打包在一起,不显示其他的依赖文件(如果没有这个属性,你会发现所有生成的、所需支持的依赖文件会全部在文件夹下)
-w 在程序运行的过程中隐藏后台控制的黑窗口
4.命令执行成功后会生成多个新的文件夹,而可执行文件在dist文件夹里面。

本文地址:https://blog.csdn.net/yue200403/article/details/107247161