- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章使用pyqt5搭建yolo3目标识别界面的方法由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
由于这是我第一次写这种博客,其目的也不是为了赚取积分,主要是为了记录我的学习过程中的一些方法,以便以后我再次需要用的时候可以知道我当时是怎么做的。所以文中会有很多地方并不会解释其原理(主要是我自己压根也没搞明白,当时只想知道怎么用就行了,遇到需要用其他的再百度),主要着重于怎么运用。如有不当之处,请指出我当改正.
我用的IDE是PyCharm,深度学习环境搭建可以参考其他博主的教程。 pyqt5的环境搭建流程参考的是b站up主@刘金玉编程.
打开命令提示符窗口,输入'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'文件,就可以从代码中对界面进行调用和编辑.
我没有从直接设计界面开始,而是从代码中设计界面.
主界面 。
。
子界面 。
需要导入以下常用的库:
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_()) #监听退出,如果选择退出,界面就会关掉
(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()
(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识别界面内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。
原文链接:https://blog.csdn.net/qq_43180908/article/details/114639985 。
最后此篇关于使用pyqt5搭建yolo3目标识别界面的方法的文章就讲到这里了,如果你想了解更多关于使用pyqt5搭建yolo3目标识别界面的方法的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我使用的是linux的windows子系统,安装了ubuntu,bash运行流畅。 我正在尝试使用make,似乎bash 无法识别gcc。尝试将其添加到 PATH,但没有任何改变。奇怪的是 - cmd
ImageMagick 已正确安装。 WAMP 的“PHP 扩展”菜单也显示带有勾选的 php_imagick。除了 Apache 和系统环境变量外,phpinfo() 没有显示任何 imagick
我是这么想的,因为上限是 2^n,并且考虑到它们都是有限机,n 状态 NFA 和具有 2^n 或更少状态的 DFA 的交集将是有效。 我错了吗? 最佳答案 你是对的。 2^n 是一个上限,因此生成的
我有一个大型数据集,其中包含每日值,指示一年中的特定一天是否特别热(用 1 或 0 表示)。我的目标是识别 3 个或更多特别炎热的日子的序列,并创建一个包含每个日子的长度以及开始和结束日期的新数据集。
我有一个向量列表,每个向量看起来像这样 c("Japan", "USA", "country", "Japan", "source", "country", "UK", "source", "coun
是否有任何工具或方法可以识别静态定义数组中的缓冲区溢出(即 char[1234] 而不是 malloc(1234))? 昨天我花了大部分时间来追踪崩溃和奇怪的行为,最终证明是由以下行引起的: // e
我一直在尝试通过导入制表符分隔的文件来手动创建 Snakemake 通配符,如下所示: dataset sample species frr PRJNA493818_GSE120639_SRP1628
我一直在尝试通过导入制表符分隔的文件来手动创建 Snakemake 通配符,如下所示: dataset sample species frr PRJNA493818_GSE120639_SRP1628
我想录下某人的声音,然后根据我获得的关于他/她声音的信息,如果那个人再次说话,我就能认出来!问题是我没有关于哪些统计数据(如频率)导致人声差异的信息,如果有人可以帮助我如何识别某人的声音? 在研究过程
我希望我的程序能够识别用户何时按下“enter”并继续循环播放。但是我不知道如何使程序识别“输入”。尝试了两种方法: string enter; string ent = "\n"; dice d1;
我创建了这个带有一个参数(文件名)的 Bash 小脚本,该脚本应该根据文件的扩展名做出响应: #!/bin/bash fileFormat=${1} if [[ ${fileFormat} =~ [F
我正在寻找一种在 for 循环内迭代时识别 subview 对象的方法,我基本上通过执行 cell.contentView.subviews 从 UITableView 的 contentView 获
我正在尝试在 Swift 中使用 CallKit 来识别调用者。 我正在寻找一种通过发出 URL 请求来识别调用者的方法。 例如:+1-234-45-241 给我打电话,我希望它向 mydomain.
我将(相当古老的)插件称为“thickbox”,如下所述: 创建厚盒时,它包含基于查询的内容列表。 使用 JavaScript 或 jQuery,我希望能够访问 type 的值(在上面的示例中 t
我想编写一些可以接受某种输入并将其识别为方波、三角波或某种波形的代码。我还需要一些产生所述波的方法。 我确实有使用 C/C++ 的经验,但是,我不确定我将如何模拟所有这些。最终,我想将其转换为微 Co
我创建了一个 for 循环,用于在每个部分显示 8 个项目,但我试图在循环中识别某些项目。例如,我想识别前两项,然后是第五项和第六项,但我的识别技术似乎是正确的。 for (int i = 0; i
如何识别 UIStoryboard? 该类具有创建和实例化的方法,但我没有看到带有类似name 的@property。例如 获取 Storyboard对象 + storyboardWithName:b
如何确定所运行的SQLServer2005的版本 要确定所运行的SQLServer2005的版本,请使用SQLServerManagementStudio连接到SQLServer2005,然后运行
这个问题在这里已经有了答案: How to check whether an object is a date? (26 个答案) 关闭2 年前。 我正在使用一个 npm 模块,它在错误时抛出一个空
我正在制作一个使用 ActivityRecognition API 在后台跟踪用户 Activity 的应用,如果用户在指定时间段(例如 1 小时)内停留在同一个地方,系统就会推送通知告诉用户去散步.
我是一名优秀的程序员,十分优秀!