荐 使用Python PyQt5实现一个简单的图像识别软件
摘要:之前学习了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文件,并放到了桌面,点击即可运行。
点击运行后:
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
要添加两个工具,一个用来设计GUI,另一个用来把设计好的GUI变成python代码文件。
用来设计GUI的工具创建如下图:
把设计好的GUI变成python代码文件的工具创建如下图:
设置:
第一个框 设置名称
第二个框 设置python解释器路径(就是虚拟环境下的scripts\python.exe)
第三个框
-m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py
第四个框:
$FileDir$
查看是否创建成功,选中一个.py文件,右键;如下图所示,如果出现刚刚创建的即可:
以上是使用QtDesigner设计GUI界面的准备工作,如果你有QtDesigner基础,上面的可以直接不看。
2.正式设计软件的界面
2.1点击下图按钮
2.2点击后出现下面界面,这里是设计GUI的界面,这里可以拖动标签和按钮来设计自己想要的软件界面。
2.3设计好后的效果
3.把设计好的ui文件转成py文件,选中刚刚创建好的ui文件,使用第二个扩展工具,即可生成同名的.py文件
4.3整个程序函数的书写(功能实现)
主要在上面生成的.py文件里修改完善软件功能。添加点击事件和识别调用接口以及函数功能的完善。
值得一提的是,这里主要是调用了百度AI提供的图像文字识别接口,而我们的主要任务就是整个软件的逻辑控制和功能拼接。以及对返回数据进行解析和数据可视化。
网址:点击前往百度智能云
整个软件的全部代码如下,里面包含详细的注释:
# -*- 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.打开终端
3.输入以下命令:
pyinstaller -F -w 文件名.py
-F 是用于将所有的支持文件全部都打包在一起,不显示其他的依赖文件(如果没有这个属性,你会发现所有生成的、所需支持的依赖文件会全部在文件夹下)
-w 在程序运行的过程中隐藏后台控制的黑窗口
4.命令执行成功后会生成多个新的文件夹,而可执行文件在dist文件夹里面。
本文地址:https://blog.csdn.net/yue200403/article/details/107247161