摘要:之前学习了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文件,并放到了桌面,点击即可运行。

ios 图像识别开发 图像识别开发软件_文字识别


点击运行后:

ios 图像识别开发 图像识别开发软件_文字识别_02

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

ios 图像识别开发 图像识别开发软件_文字识别_03


要添加两个工具,一个用来设计GUI,另一个用来把设计好的GUI变成python代码文件。

用来设计GUI的工具创建如下图:

ios 图像识别开发 图像识别开发软件_ios 图像识别开发_04


把设计好的GUI变成python代码文件的工具创建如下图:

设置:

第一个框 设置名称

第二个框 设置python解释器路径(就是虚拟环境下的scripts\python.exe)

第三个框

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

第四个框:

$FileDir$

ios 图像识别开发 图像识别开发软件_文字识别_05


查看是否创建成功,选中一个.py文件,右键;如下图所示,如果出现刚刚创建的即可:

ios 图像识别开发 图像识别开发软件_python_06


以上是使用QtDesigner设计GUI界面的准备工作,如果你有QtDesigner基础,上面的可以直接不看。2.正式设计软件的界面

2.1点击下图按钮

ios 图像识别开发 图像识别开发软件_UI_07


2.2点击后出现下面界面,这里是设计GUI的界面,这里可以拖动标签和按钮来设计自己想要的软件界面。

ios 图像识别开发 图像识别开发软件_pyQt5_08


2.3设计好后的效果

ios 图像识别开发 图像识别开发软件_UI_09


3.把设计好的ui文件转成py文件,选中刚刚创建好的ui文件,使用第二个扩展工具,即可生成同名的.py文件

ios 图像识别开发 图像识别开发软件_python_10

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

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

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

ios 图像识别开发 图像识别开发软件_文字识别_11

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

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

# -*- 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)

'''
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.打开终端

ios 图像识别开发 图像识别开发软件_UI_12


3.输入以下命令:

pyinstaller -F -w  文件名.py

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

5.续

说明:2020.11.6日,为完成算法可作业棋盘覆盖问题作业,UI设计我还是采用QT5制作,发现几个问题,记录一下:
1.lineEdit输入框输入数值若是要整数型,则要进行强转为int形,否则程序会出现无法运行情况。
2.由ui设计到.py文件,需要每修改一次后进行重新生成.py文件。因此,UI设计最好一开始就设计完美,然后再进行程序逻辑的书写。
3.这里采用了plt绘制热力图的实现方式,生成图片后保存图片,然后读取图片。
4.若出现python.exe已停止工作,说明程序有bug,使用pycharm的deBug模式找到bug并且修改。
5.若出现生成的.exe文件报Failed to execute script错误,很大概率时当前虚拟环境不存在要用到的包,需在文件夹中查看,然后导入,再生成exe文件。