【搞事情】利用PyQt为目标检测SSD300添加界面(三)

【原创文章】欢迎正常授权转载(联系作者)
【反对恶意复制粘贴,如有发现必维权】
【微信公众号原文传送门


软件最终效果


系列文章链接
1. 问题总体描述及三种方案;
2. 方案1详解(附代码);

这篇文章将详细介绍方案2的实现(代码获取见文章末尾)。

老规矩先看看下载好的代码文件构成。
在这里插入图片描述
其中 “ssd” 文件夹中是SSD检测的关键文件,关于这部分之前写文章了,里面详细介绍了如何训练一个属于自己的SSD300,有代码、有预训练的权值文件,不清楚的请移步这里


需求分析

先简单做一个需求分析,看看我们要怎样实现。
在这里插入图片描述
首先,要解决的问题:电脑性能太好(如果你有的话,土豪交朋友吗?),导致使用帧循环的方法时,视频会被“加速”播放,我们想让它按正常的速度播放。
之后,我们先了解一个概念FPS(每秒帧数),对应的可以计算出一帧应该显示几秒。例如:

(FPS: Frames Per Second)
FPS = 20  
(TPF: times Per Frame,这个是我自己造的,哈哈哈哈)    
TPF = 1 / 20 (单位:s)

只要控制 读取图像–>检测–>显示 的节奏,让显示图像的时间与视频的 FPS 对应,那么看起来视频就是正常播放的啦。

通过 计时器(QTimer) 可以很好的实现这个需求,计时器时间一到就会发送 “超时信号 给对应的槽函数(用于检测显示),槽函数收到信号后就开始执行,槽函数执行结束后等待再一次被调用。

最后一个需求是要通过界面的按钮来控制 开始结束 ,这个就很简单,构造函数里实例化计时器,然后在对应的槽函数里 开始停止 计时器就可以了。


代码分析

下面开始详细介绍代码。主要介绍下面几个函数,其他的函数在上篇文章中已经讲过或者比较简单,就不介绍了。(偷个懒,嘿嘿嘿)

1. 构造函数
def __init__(self, parent=None):
"""
  ...上一篇文章已经介绍过...
  ...这里就不写了...
  ...这里说点不一样的...
"""
# 视频文件路径
    self.camera_index = None    # 用于保存视频文件路径
    self.FPS = None             # 用于保存视频文件FPS# 初始化计时器
    self.timer = QTimer(self)  # 更新计时器
    self.timer.timeout.connect(self.timer_update) # 超时信号连接对应的槽函数

在构造函数中初始化必要的变量,同时实例化一个 QTimer计时器 ,并将 “超时”信号 与对应的槽函数绑定起来。代码中self.timer_update为计时器超时信号的槽函数,这里作为参数传入不可以加’()’,后面会详细说。

2. ‘开始’点击槽函数
def on_pushButton_start_clicked(self):
    """
    Slot documentation goes here.
    """
    # TODO: not implemented yet
    # 获取数据流
    self.cap = cv2.VideoCapture(self.camera_index)
    if self.cap.isOpened():
        # 获取视频的FPS
        # FPS ---- 每秒多少帧
        self.FPS = self.cap.get(cv2.CAP_PROP_FPS)
        if isinstance(self.FPS, float):         # 正常获取的FPS是float
            self.FPS = int(self.FPS)            # 如果正确获取FPS就保存在变量
        else:
            self.FPS = 20                       # 没正确获取则设为 20帧/s# 计时器开始计时
        # 计时器的参数为 ms 为了正常速度播放,计时器的参数计算为 1/FPS * 1000 = 1000/FPS
        self.timer.start(int(1000/self.FPS))# 锁定开始按钮
        self.pushButton_start.setEnabled(False)
    else:
        QMessageBox.warning(self, '数据流打开警告', '数据流打开错误!\n请重新尝试。')

该函数的主要功能是:打开视频数据流获取视频流的FPS计时器开始计时。需要注意的是计时器的时间设置问题。
函数self.timer.start(时间,单位:ms)的参数与 1/FPS 之间还需要乘以 1000 ,同时这个值还应该考虑到图像预处理以及检测的时间,适当的减小这个值,如果不考虑的话可能会出现“慢速播放”。

3. ‘结束’点击槽函数

该函数比较简单,主要功能是停止计时器的功能,同时为下一次检测做准备。

def on_pushButton_end_clicked(self):
    """
    Slot documentation goes here.
    """
    # TODO: not implemented yet
    # 重设
    self.resst_detector()    # 详细代码在下方
    # 清除显示
    self.textEdit.clear()
    
def resst_detector(self):
    """
    重设检测器,为下一次检测准备
    :return:
    """
    # 释放摄像头
    if hasattr(self, 'cap'):
        self.cap.release()
        del self.cap
    # 释放‘开始’按钮
    self.pushButton_start.setEnabled(True)
    # 显示空白图片
    self.show_img(self.img_none)
    # 停止计时器
    self.timer.stop()
4. 计时器槽函数
def timer_update(self):
    """
    计时器槽函数
    :return:
    """
    if self.cap.isOpened():
        # 读取图像
        ret, self.img_scr = self.cap.read()
        # 如果视频读取完毕
        if not ret:
            # 计时器停止计时
            self.timer.stop()
            # 对话框提示
            QMessageBox.information(self, '播放提示', '视频已播放完毕!')
            # 释放摄像头
            if hasattr(self, 'cap'):
                self.cap.release()
                del self.cap
            # 释放‘开始’按钮
            self.pushButton_start.setEnabled(True)# 预处理图片
        # 转为RGB
        self.img_scr = cv2.cvtColor(self.img_scr, cv2.COLOR_BGR2RGB)# 检测
        self.preds = self.ssd.Predict(self.img_scr)
        # 过滤
        self.preds = self.filter(self.preds, inclued_class=self.include_class)
        self.img_scr = self.draw_img(self.img_scr, self.preds)
​
        h, w = self.img_scr.shape[:2]
        self.text = self.decode_preds(self.preds, w=w, h=h)
        self.textEdit.setText(self.text)# 显示图像
        self.show_img(self.img_scr)# 响应UI
        QApplication.processEvents()
    else:
        self.textEdit.setText('数据流未打开!!!\n请检查')
        self.resst_detector()    # 没有打开就重设一下

看过上篇文章的是不是很熟悉,没错。基本就是帧循环里面的东西。

5. ‘文件打开’槽函数

为了方便更换被检测视频,创建了一个按钮用于打开文件对话框选择文件,基本功能就是为了实现给变量self.camera_index赋值。

def on_pushButton_open_clicked(self):
    """
    Slot documentation goes here.
    """
    # TODO: not implemented yet
    # 打开文件对话框
    path = QFileDialog.getOpenFileName(self, '打开待检测视频', './', '*.avi;;*.mp4;;AllFile(*.*)', '')
    if path[0] != '':    # 点‘取消’,path[0]的值会为‘’
        path = os.path.normpath(os.path.abspath(path[0]))
        self.camera_index = path
        self.textEdit.setText('{}已选中!'.format(path))
    else:
        self.textEdit.setText('当前未选中任何文件')
​预告:方案3应该下周整理完毕并更新

关注下方公众号,回复关键字即可获取下载地址。
  • 本文配套源代码下载地址::

    回复“SSD界面2”获取。


如果你读后有收获,欢迎关注我的微信公众号
上面有更多完全免费教程,我也会不定期更新
ღ ღ ღ 打开微信扫描下方二维码关注 ღ ღ ღ

在这里插入图片描述

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
利用PyQt5为目标检测Faster-RCNN-PyTorch添加GUI界面是一种很好的方式,可提供用户友好的交互界面,方便用户使用和了解检测结果。下面是一种可能的实现方式: 首先,我们需要安装PyQt5库。使用以下命令在终端中安装: ``` pip install PyQt5 ``` 接下来,我们需要创建一个主窗口来容纳GUI界面。使用PyQt5的QMainWindow类,我们可以轻松创建一个窗口。使用以下代码创建一个名为MainWindow的主窗口: ```python from PyQt5.QtWidgets import QMainWindow class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("目标检测GUI") self.setGeometry(100, 100, 800, 600) # 设置窗口的位置和大小 ``` 然后,我们可以在主窗口中添加各种GUI元素,例如按钮、标签和图像显示区域。根据需要,您可以根据您的要求进行自定义。以下是一个示例: ```python from PyQt5.QtWidgets import QLabel, QPushButton class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("目标检测GUI") self.setGeometry(100, 100, 800, 600) self.label = QLabel(self) self.label.setGeometry(10, 10, 780, 480) self.button = QPushButton("开始检测", self) self.button.setGeometry(10, 500, 780, 50) self.button.clicked.connect(self.start_detection) def start_detection(self): # 在此处添加目标检测的代码 pass ``` 最后,我们需要在主函数中初始化应用程序并显示主窗口。使用以下代码: ```python from PyQt5.QtWidgets import QApplication import sys if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec()) ``` 您可以在`start_detection()`方法中添加您的目标检测代码。这样,当用户点击“开始检测”按钮时,将会调用该方法并执行目标检测。 以上是利用PyQt5为目标检测Faster-RCNN-PyTorch添加GUI界面的一种实现方式。您可以根据需要进行进一步的自定义和改进,以实现更好的用户体验和功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值