使用pyqt5搭建yolo3目标识别界面的方法

由于这是我第一次写这种博客,其目的也不是为了赚取积分,主要是为了记录我的学习过程中的一些方法,以便以后我再次需要用的时候可以知道我当时是怎么做的。所以文中会有很多地方并不会解释其原理(主要是我自己压根也没搞明白,当时只想知道怎么用就行了,遇到需要用其他的再百度),主要着重于怎么运用。如有不当之处,请指出我当改正。

搭建pyqt5环境

我用的IDE是PyCharm,深度学习环境搭建可以参考其他博主的教程。
pyqt5的环境搭建流程参考的是b站up主@刘金玉编程。

  1. 安装Anaconda3,搭建好虚拟环境,在虚拟环境里配置好yolo3所需的库,并在这个虚拟环境里安装pyqt5。
  2. 用win + R打开快速运行,搜索cmd打开命令行窗口。

打开命令提示符窗口,输入'activate'+空格+所在虚拟环境的名称。然后输入'pip install pyqt5'+回车,就会开始安装pyqt5。

在PyCharm中配置好pyqt5。首先打开设置,在'External Tool'中添加ptqt5组件。点击 ‘+‘号,

点击 ‘+‘号,创建工具,工具名字是自己设定的,第一个可以命名为'QTDesinger',Program路径选择Anaconda安装路径下的'Ananconda3\Library\bin\designer.exe',因为我是直接装在D盘的,所以完整路径为'D:\Ananconda3\Library\bin\designer.exe'。点击Program这一行末尾的'+‘号即可选择路径。选择好之后,Argument不用填,Working directory会自己填好。

然后再添加一个工具,名字可以命名为'PyUIC',Program选择路径为虚拟环境的路径,一般都安装在Ananconda3下的evns文件夹里,下一级文件夹就是虚拟环境的名称,找到你创建的虚拟环境文件夹,在里面找到 python.exe文件,完整路径为'D:\Ananconda3\envs\python3-6\python.exe',Argument填入

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

Working directory填入

$FileDir$

完成以上步骤,即可配置好所需工具,开始设计界面了。

可以右键项目名称选择External Tool里的QTDesinger可以直接开始设计界面,最后需要保存在项目根目录里,会生成一个后缀为'ui'的文件,然后右键点击这个文件选择External Tool里的PyUIC即可将其转换为'py'文件,就可以从代码中对界面进行调用和编辑。

我没有从直接设计界面开始,而是从代码中设计界面。

程序流程

主界面

子界面

设计界面

1.主函数

需要导入以下常用的库:

from PyQt5.QtWidgets import *					#这两个是pyqt5常用的库
from PyQt5.QtGui import QIcon, QPixmap			#可以满足小白大多数功能
import os					#这两个是其他的库
import sys					#可以完成一些打开文件保存文件的功能
from yolov3 import train, predict			#这是我自己将yolov3模型整体放在我项目的子文件夹中,从中调用我的训练和预测函数

下面是主程序:

# 创立一个主界面,并保持它,从各种按钮或者组件中接受信号完成界面功能,相当于无限循环
# 只有选择退出后才会关掉程序退出循环
if __name__ == '__main__':
 app = QApplication(sys.argv)
 mc = MyClass()		#这里相当于实例化一个主界面,myclass是自己定义的主界面类
 sys.exit(app.exec_())		#监听退出,如果选择退出,界面就会关掉

2.定义主界面的类

(1)主界面

首先是初始化,需要继承父类。

class MyClass(QWidget):
 def __init__(self):
 super().__init__()		#继承父类
 self.initUI()			#自己定义的函数,初始化类界面,里面放着自己各种定义的按钮组件及布局
 self.child_window = ChildClass()		#子界面的调用,本质和主界面一样是一个类,在这里将其声明为主界面的成员

(2)主界面布局

功能实现在代码注释都有详细说明,关于self.TModelSelectSignal = [0, 0]self.TModel= [1, 0],可以理解为一种主界面和子界面的信号传递,由于我对深层次的参数传递不清楚,所以只能采用一种的最笨的方法,在主界面的类里活得已训练好模型的序号,放在数组self.TModel里,数组的第一位为1表示第一个模型已训练,为0表示未训练。同理第二位则表示第二个模型,如果有更多模型,可以设置更多位。数组的设置实在模型训练之后,因此将赋值数组的代码放在训练函数里。

 def initUI(self):
 self.setWindowTitle("COC缺陷检测")		#设置界面名称
 # self.setWindowIcon(QIcon("iconimg/zhou.png"))		#设计界面的图标,图片放在项目文件夹的子文件夹里就不会出错,名字也要对应
 self.resize(350, 200)		#设置界面大小
 self.TModelSelectSignal = [0, 0] #选择按钮对应的模型
 self.TModel= [0, 0]   #表示已经训练好的模型编号

 myframe = QFrame(self) #实例化一个QFrame可以定义一下风格样式,相当于一个框架,可以移动,其内部组件也可以移动
 btn2 = QPushButton("开始训练模型", self)		#定义一个按钮,括号里需要一个self,如果需要在类内传递,则应该定义为self.btn2
 btn2.clicked.connect(self.TestModel)	#将点击事件与一个函数相连,clicked表示按钮的点击事件,还有其他的功能函数,后面连接的是一个类内函数,调用时无需加括号
 btn3 = QPushButton("上传数据集", self)
 btn3.clicked.connect(self.DataExplorerSelect) #连接一个选择文件夹的函数
 btn5 = QPushButton("退出程序", self)
 btn5.clicked.connect(self.close)	#将按钮与关闭事件相连,这个关闭事件是重写的,它自带一个关闭函数,这里重写为点击关闭之后会弹窗提示是否需要关闭
 btn6 = QPushButton("检测", self)
 btn6.clicked.connect(self.show_child) #这里将联系弹出子界面函数,具体弹出方式在函数里说明

 combol1 = QComboBox(myframe) #定义为一个下拉框,括号里为这个下拉框从属的骨架(框架)
 combol1.addItem("   选择模型")	#添加下拉选项的文本表示,这里因为没有找到文字对齐方式,所以采用直接打空格,网上说文字对齐需要重写展示函数
 combol1.addItem("   YOLOv3")
 combol1.addItem("   YOLOv4")
 combol1.activated[str].connect(self.TModelSelect)	#|--将选择好的模型序号存到模型选择数组里
 													#|--后面的训练函数会根据这个数组判断需要训练哪个模型
															#|--[str]表示会将下拉框里的文字随着选择信号传过去
															#|--activated表示该选项可以被选中并传递信号
 vlo = QVBoxLayout() #创建一个垂直布局,需要将需要垂直布局的组件添加进去
 vlo.addWidget(combol1) 	#添加相关组件到垂直布局里
 vlo.addWidget(btn3)
 vlo.addWidget(btn2)
 vlo.addWidget(btn6)
 vlo.addWidget(btn5)
 vlo.addStretch(1)	#一个伸缩函数,可以一定程度上防止界面放大之后排版不协调
 hlo = QVBoxLayout(self)	#创建整体框架布局,即主界面的布局
 hlo.addLayout(vlo)	#将按钮布局添加到主界面的布局之中
 hlo.addWidget(myframe)	#将框架也加入到总体布局中,当然也可以不需要这框架,直接按照整体框架布局来排版
 #之所以这里有这个myframe,是因为尝试过很多种布局,其中一个布局就是将其他组件都放到这个myframe中,移动这个myframe
 #其里面的组件布局相对位置不会改变,后面又尝试了多种布局,所以这个myframe最后里面其实就剩下一个下拉框
 self.show() #显示主界面

(3)主界面的功能函数(槽函数)

选择数据上传,其本质是打开一个文件夹,然后将相关照片按照规定排列好。这里采用的是绝对路径,按理来说相对路径较好,但是没有找到具体实现方法,一般的相对路径方法打不开对应的文件夹,所以暂时选择用这个。

 def DataExplorerSelect(self):
 path = r'D:\pycharm\QTYOLOV3\yolov3\VOCdevkit\VOC2007'
 os.system("explorer.exe %s" % path)

打开子界面函数

 def show_child(self):
 TModel1 = self.TModel					#|--这是子界面的类内函数
 self.child_window.GetTModel(TModel1)	#|--将训练好的模型序号传到子界面的类内参数里面
 self.child_window.show()		#|--子界面相当于主界面的一个类内成员
 								#|--但是本质还是一个界面类,也有show函数将其展示

选择需要训练的模型序号
如果这里报错,有可能是下拉框中文本信息与这里的判断文本信息不同。

 def TModelSelect(self, s):		#s是形参,表示传回来的选中的选项的文字
 if s == '   YOLOv3':
  self.TModelSelectSignal[0] = 1		#如果选中的是YOLOv3-COC就将第一位置1
  # print(self.TModelSelectSignal[0])
 elif s == '   YOLOv4':
  self.TModelSelectSignal[1] = 1		#如果选中的是YOLO-Efficientnet就将第二位置1
  # print(self.TModelSelectSignal[1])

训练函数。因为这里只导入一个训练函数,所以只有一个判别选项,训练完之后会将self.TModelSelectSignal的对应位置零以便下一次可以继续训练。

 def TestModel(self):
 if self.TModelSelectSignal[0] == 1:
  train.run()
  self.TModelSelectSignal[0] = 0
 else:
  print("没有该模型")

关闭函数。这里是将其重写,多了一个关闭时会有弹窗出现的功能。前一个文本参数时弹出框的名字,后一个文本参数是显示在窗口的文本。

 def closeEvent(self, event):
 result = QMessageBox.question(self, "提示:", "您真的要退出程序吗", QMessageBox.Yes|QMessageBox.No, QMessageBox.Yes)
 if result == QMessageBox.Yes:
  event.accept()
 else:
  event.ignore()

3.定义子界面

(1)子函数

同样需要初始化并继承父类。

class ChildClass(QWidget):
 def __init__(self):
 super().__init__()
 self.initUI()
 self.TModel = []	#用来接收主界面的训练好的模型的序号
 self.openfile_name_image = ''	#存储原始图像的地址
 self.result_name_image = ''		#存储检测好的图像的地址

(2)子界面布局

 def initUI(self):
 self.resize(1100, 450)	#缩放界面大小
 self.setWindowTitle("目标检测")	#设置界面标题
 # self.setWindowIcon(QIcon("iconimg/zhou.png"))		#设置界面图标
 self.PModelSelectSignal = [0, 0]	#设置需要预测模型的序号,在下拉框里选择

 myframe = QFrame(self)
 self.label1 = QLabel("检测模型", self)
 combol1 = QComboBox(myframe)
 combol1.addItem("选择检测模型")
 combol1.addItem("YOLOV3")
 combol1.addItem("YOLOV4")
 combol1.activated[str].connect(self.PModelSelect)	#链接预测模型序号选择函数
 btn1 = QPushButton("选择检测图片", self)
 btn1.clicked.connect(self.select_image)		#链接检测图片选择函数,本质是打开一个文件夹

 btn2 = QPushButton("开始检测", self)
 btn2.clicked.connect(self.PredictModel)		#链接预测模型函数

 self.label2 = QLabel("", self) 			#创建一个label,可以存放文字或者图片,在这里是用来存放图片,文本参数为空就会显示为空,留出空白区域,选择好图片时会有函数展示图片
 self.label2.resize(400, 400)
 self.label3 = QLabel("", self)
 self.label3.resize(400, 400)
 label4 = QLabel("      原始图片", self)		#用来放在图片底部表示这是哪一种图片
 label5 = QLabel("      检测图片", self)
 vlo2 = QHBoxLayout()		#创建一个子布局,将图片水平排放
 vlo2.addWidget(label4)
 vlo2.addWidget(label5)

 vlo = QHBoxLayout()		#创建一个子布局,将按钮水平排放
 vlo.addStretch()
 vlo.addWidget(self.label1)
 vlo.addWidget(combol1)
 vlo.addWidget(btn1)
 vlo.addWidget(btn2)
 vlo.addStretch(1)

 vlo1 = QHBoxLayout()	#创建一个水平布局,将两个提示标签竖直排放
 vlo1.addWidget(self.label2)
 vlo1.addWidget(self.label3)

 hlo = QVBoxLayout(self)		#创建一个总的垂直布局,将三个子布局垂直排放
 hlo.addLayout(vlo)
 hlo.addLayout(vlo1)
 hlo.addStretch(1)
 hlo.addLayout(vlo2)
 hlo.addStretch(0)
 hlo.addWidget(myframe)

(3)子界面功能函数(槽函数) 一个赋值函数,在外部调用给类内成员赋值

 def GetTModel(self, a):
 self.TModel = a

关闭事件,和主界面一样是重写之后的。

 def closeEvent(self, event):
 result = QMessageBox.question(self, "提示:", "您真的要退出程序吗", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
 if result == QMessageBox.Yes:
  event.accept()
 else:
  event.ignore()
 def select_image(self):
 self.openfile_name_image, _ = QFileDialog.getOpenFileName(self, "选择照片文件",
        r"./yolov3/imgtest/")
 	#弹出一个对话窗,是一个文件夹,可以选择一个文件然后返回地址到 self.openfile_name_image中
 print('加载照片文件地址为:' + str(self.openfile_name_image))
 self.label2.setPixmap(QPixmap(str(self.openfile_name_image))) #将选中的文件名字传入QPixmap()中,括号内为文件地址,就会读取这个图片
 self.label2.resize(300, 400)
 self.label2.setScaledContents(True)	#表示这个label可以可以自适应窗口大小,可以让图片随窗口大小而变化

选择需要预测的模型,s是形参,传回的是下拉框中的文本信息。

 def PModelSelect(self, s):
 if s == 'YOLOV3':
  if self.TModel[0] == 1:
  self.PModelSelectSignal[0] = 1
  self.PModelSelectSignal[1] = 0
  print(self.PModelSelectSignal[0])
  else:
  print("模型YOLOV3未训练")	##如果已经训练好的模型数组里对应的位置为0,则表示该模型未训练
  self.PModelSelectSignal[1] = 0		#同时也要讲模型选择信号清零,以便下次可以继续选择赋值
 elif s == 'YOLOV4':
  if self.TModel[1] == 1:
  self.PModelSelectSignal[1] = 1
  self.PModelSelectSignal[0] = 0
  print(self.PModelSelectSignal[1])
  else:
  print("模型YOLOV4未训练")
  self.PModelSelectSignal[0] = 0

图像预测。由于只导入了一个模型,所以只有一个判别程序,我写的预测函数是可以读取文件路径的图片,所以我只需将需要预测的图片的路径传入预测函数,就会将预测好的图片保存在指定文件夹,然后后面用程序将其读出展示在界面里。

 def PredictModel(self):
 if self.PModelSelectSignal[0] == 1:
  predict.predict(self.openfile_name_image)	#将需要预测的图片传入导入的预测函数
 elif self.PModelSelectSignal[1] == 1:
  print('YOLOV4正在检测') #这里应该放入另外一个模型
 else:
  print('没有该模型')
 a = self.openfile_name_image
 a = a.split('/')	#将预测图片里的编号分离出来
 a = './yolov3/imgtestresult/' + a[-1]	#将指定路径与图片编号组合,即可得到预测好的图片的路径
 self.label3.setPixmap(QPixmap(a))	#直接读取预测好的图片
 self.label3.resize(300, 400)
 self.label3.setScaledContents(True)
 print(a)

界面展示


一些尚未解决的问题

由于保存图片路径变量覆盖的问题,会导致选择第二张检测图片之后,检测图片的结果仍然展示的是第一张,可以在选择检测图片的函数里加上每当选择一张新的图片,即可清除上一张图片。
另外一个问题就是无法连续两次检测,具体原因还没有查明,可能是用的同一个保存图片文件的变量,最后并没有传入预测函数。

另外一个还没有实现的功能就是实时展示训练进程,在原始训练函数里,是会实时打印出训练进程,所以应该可以做到读取训练函数里的打印的文本,然后传递到界面类里的一个函数,然后展示在界面里。

到此这篇关于使用pyqt5搭建yolo3目标识别界面的方法的文章就介绍到这了,更多相关pyqt5搭建yolo3识别界面内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python3+Pycharm+PyQt5环境搭建步骤图文详解

    搭建环境: 操作系统:Win10 64bit Python版本:3.7 Pycharm:社区免费版 一.Python3.7安装 下载链接:官网https://www.python.org/downloads/windows/或腾讯软件中心下载https://pc.qq.com/detail/5/detail_24685.html或其他站点下载.我下载的是python-3.7.0-amd64. 下载到安装包后打开,如果想安装到默认路径(C盘)的话一直点下一步就可以了,或者自定义安装到其他分区,我的

  • python3.6.8 + pycharm + PyQt5 环境搭建的图文教程

    首先安装python3.6.8解释器和PyCharm软件,这篇文章假设你以及安装好啦. 其次安装pyQT5,我这次是使用pip工具安装的.安装pyQT5之前,需要先安装SIP.找到python安装目录下Scripts文件夹,我们可以看到有一个pip3.exe可执行文件.这时,在这个文件夹空白处,按shift+鼠标右键,找到在此处打开命令窗口.如图,输入 pip3 install SIP 等待安装完成. 上图中我们可以看到Successfully Installed SIP 字样,说明安装SIP成

  • Python PyQt5 Pycharm 环境搭建及配置详解(图文教程)

    PyQt5相关安装 python 版本 python 3.6.3 1.安装PyQt5 执行命令: pip install pyqt5 2.安装PyQt5-tools 执行命令:pip install pyqt5-tools 3.校验是否成功 执行如下代码 # FileName : PyQtDemo.py # Author : Adil # DateTime : 2018/2/1 11:07 # SoftWare : PyCharm from PyQt5 import QtWidgets, QtG

  • PyQt5+Caffe+Opencv搭建人脸识别登录界面

    最近开始学习Qt,结合之前学习过的caffe一起搭建了一个人脸识别登录系统的程序,新手可能有理解不到位的情况,还请大家多多指教. 我的想法是用opencv自带的人脸检测算法检测出面部,利用caffe训练好的卷积神经网络来提取特征,通过计算当前检测到的人脸与已近注册的所有用户的面部特征之间的相似度,如果最大的相似度大于一个阈值,就可以确定当前检测到的人脸对应为这个相似度最大的用户了. ###Caffe人脸识别 因为不断有新的用户加入,然而添加新用户后重新调整CNN的网络结构太费时间,所以不能用CN

  • 使用pyqt5搭建yolo3目标识别界面的方法

    由于这是我第一次写这种博客,其目的也不是为了赚取积分,主要是为了记录我的学习过程中的一些方法,以便以后我再次需要用的时候可以知道我当时是怎么做的.所以文中会有很多地方并不会解释其原理(主要是我自己压根也没搞明白,当时只想知道怎么用就行了,遇到需要用其他的再百度),主要着重于怎么运用.如有不当之处,请指出我当改正. 搭建pyqt5环境 我用的IDE是PyCharm,深度学习环境搭建可以参考其他博主的教程. pyqt5的环境搭建流程参考的是b站up主@刘金玉编程. 安装Anaconda3,搭建好虚拟

  • Pyqt5 实现跳转界面并关闭当前界面的方法

    网上大部分教程都写的直接关闭界面,我摸索出来一个方法:同时绑定两个事件 例: #自己方法 self.registerButton.clicked.connect(self.register_re) #关闭界面 self.registerButton.clicked.connect(login.close) 代码顺序代表进行顺序,上例先运行自己函数,再关闭当前窗口. 以上这篇Pyqt5 实现跳转界面并关闭当前界面的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • pyqt5使用按钮进行界面的跳转方法

    简介 进行按钮进行界面的跳转,我这里面我介绍两种,一种是没有使用Qtdesigner的代码,另一种是使用Qtdesigner的代码 代码1 import sys from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication class First(QMainWindow): def __init__(self): super().__init__() self.initUI() def initUI(self): self.

  • python GUI库图形界面开发之PyQt5窗口类QMainWindow详细使用方法

    QMainWindow QMainWindow类中比较重要的方法 方法 描述 addToolBar() 添加工具栏 centralWidge() 返回窗口中心的一个控件,未设置时返回NULL menuBar() 返回主窗口的菜单栏 setCentralWidget() 设置窗口中心的控件 setStatusBar() 设置状态栏 statusBar() 获得状态栏对象后,调用状态栏对象的showMessage(message,int timeout=0)方法 显示状态栏信息,其中第一个参数是要显

  • Docker使用Portainer搭建可视化界面的方法

    Portainer介绍 Portainer是Docker的图形化管理工具,提供状态显示面板.应用模板快速部署.容器镜像网络数据卷的基本操作(包括上传下载镜像,创建容器等操作).事件日志显示.容器控制台操作.Swarm集群和服务等集中管理和操作.登录用户管理和控制等功能.功能十分全面,基本能满足中小型单位对容器管理的全部需求. 下载Portainer镜像 # 查询当前有哪些Portainer镜像 docker search portainer 上图就是查询出来的有下载量的portainer镜像,我

  • python GUI库图形界面开发之PyQt5输入对话框QInputDialog详细使用方法与实例

    PyQt5输入对话框QInputDialog介绍 QInputDialog控件是一个标准对话框,有一个文本框和两个按钮(ok和cancel)组成,当用户单击ok或enter键后,在父窗口可以收集通过QInputDialog控件输入的信息,QInputDialog控件是QDialog标准对话框的一部分 在QInpuTDialog控件中可以输入数字,字符串或列表中的选项,标签用于提示必要的信息 QInputDialog类中常用的方法 方法 描述 getint() 从控件中获得标准整数输入 getDo

  • python GUI库图形界面开发之PyQt5信号与槽基础使用方法与实例

    信号与槽有三种使用方法 第一种:内置信号与槽的使用 第二种:自定义信号与槽的使用 第三种:装饰器的信号与槽的使用 一: 内置信号与槽的使用 内置信号与槽的使用,是指在发射信号时,使用窗口控件的函数,而不是自定义的函数,这种也是我们前面用的最多的,下面简单的一个实例,大家就会明白 import sys from PyQt5.QtWidgets import QMessageBox,QPushButton,QApplication,QWidget app=QApplication(sys.argv)

  • FineReport中自定义登录界面的方法

    FineReport报表软件是一款纯Java编写的.集数据展示(报表)和数据录入(表单)功能于一身的企业级web报表工具,它"专业.简捷.灵活"的特点和无码理念,仅需简单的拖拽操作便可以设计复杂的中国式报表,搭建数据决策分析系统. 在登录平台时,不希望使用FR默认的内置登录界面,想通过自定义登录界面实现登录操作,内置登录界面如下图: 登录界面,获取到用户名和密码的值,发送到报表系统,报表服务带着这两个参数访问认证地址进行认证. 自定义登录界面 1)登录界面设置 自定义html登录页面:

  • pyqt5 获取显示器的分辨率的方法

    代码如下 import sys from PyQt5.QtWidgets import QApplication, QWidget class Example(QWidget): def __init__(self): super().__init__() self.initUI() # 界面绘制交给InitUi方法 def initUI(self): self.desktop = QApplication.desktop() #获取显示器分辨率大小 self.screenRect = self

  • 解决.ui文件生成的.py文件运行不出现界面的方法

    一般需要导入下面两个包 from PyQt5.QtWidgets import QApplication import sys 并且在.py文件中加入以下代码: if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) widget = QtWidgets.QWidget() ui = Ui_MainWindow() ui.setupUi(widget) widget.show() sys.exit(app.ex

随机推荐