当前位置:   article > 正文

好文转载:基于深度学习的水果检测与识别系统(Python界面版,YOLOv5实现)_from utils.torch_utils import time_synchronized

from utils.torch_utils import time_synchronized

在这里插入图片描述

摘要:本博文介绍了一种基于深度学习的水果检测与识别系统,使用YOLOv5算法对常见水果进行检测和识别,实现对图片、视频和实时视频中的水果进行准确识别。博文详细阐述了算法原理,同时提供Python实现代码、训练数据集,以及基于PyQt的UI界面。通过YOLOv5实现对图像中存在的多个水果目标进行识别分类,用户可以在界面中选择各种水果图片、视频进行检测识别。本文旨在为相关领域的研究人员和新入门的朋友提供一个参考,完整代码资源文件请转至文末的下载链接。本文结构如下:

水果检测与识别系统功能演示与介绍(YOLOv5+PyQt5+UI界面

➷点击跳转至文末所有涉及的完整代码文件下载页☇


前言

        近年来,随着全球经济的发展,水果消费市场规模不断扩大,水果种类也日益丰富。水果检测与识别技术在农业生产、仓储物流、超市零售等领域具有重要的应用价值。传统的水果检测与识别方法主要依赖于人工识别,这种方法在一定程度上受到人力成本、识别效率和准确性等方面的限制。因此,开发一种高效、准确的自动化水果检测与识别系统具有重要的研究意义和实际价值。(本文的参考文献请见文末

        计算机视觉作为人工智能的一个重要分支,在目标检测和识别方面取得了显著的研究进展。特别是深度学习技术的发展,极大地推动了计算机视觉在水果检测与识别领域的应用。许多研究人员已经尝试利用深度学习技术进行水果检测与识别,取得了一定的成果[1]。然而,当前的研究仍然存在一定的局限性,如算法复杂度高、实时性差等问题。

        在计算机视觉领域,已有多种深度学习算法被应用于目标检测和识别任务。例如,R-CNN[2]、Fast R-CNN[3]、Faster R-CNN[4]、SSD[5]、RetinaNet[6]等。这些算法在一定程度上提高了目标检测的准确性和速度。然而,这些算法仍然存在一定的局限性,如计算复杂度高、实时性差等。为了解决这些问题,研究人员提出了YOLO(You Only Look Once)算法[7],该算法采用端到端的训练方式,能够在保持较高检测准确性的同时实现实时检测。YOLO算法自2016年首次提出以来,经历了多次改进,如YOLOv2[8]、YOLOv3[9]、YOLOv4[10]等,每个版本都在前一个版本的基础上提高了检测准确性和速度。针对水果检测与识别任务,有研究人员尝试将深度学习技术应用于该领域。例如,使用Faster R-CNN进行苹果检测[11],采用Mask R-CNN实现对葡萄的实例分割[12],以及利用SSD进行柑橘检测[13]等。这些研究表明深度学习技术在水果检测与识别任务上具有很大的前景。

        在本博文中,我们提出了一种基于深度学习的水果检测与识别系统,该系统采用YOLOv5算法对常见水果进行检测和识别,实现对图片、视频和实时视频中的水果进行准确识别。YOLOv5[14]作为YOLO系列算法的最新版本,在保持实时性的同时,进一步提高了检测准确性。与其他目标检测算法相比,YOLOv5具有较高的性能和较低的计算复杂度,因此适合应用于水果检测与识别任务。

        本文的主要贡献包括:(1)介绍了一种基于YOLOv5的水果检测与识别系统;(2)详细描述了算法原理,提供了Python实现代码以及训练数据集;(3)展示了基于PyQt的UI界面设计,并分析了训练和评估结果等实验。本文旨在为相关领域的研究人员和新入门的朋友提供一个参考。


1. 系统界面演示效果

        在本节中,我们将展示系统的界面效果。通过演示界面效果,可以帮助读者更好地理解整个水果检测与识别系统的工作流程,同时也有利于展示系统的功能和易用性。下面我们将通过图片和描述来展示系统的界面效果,本系统具有以下主要功能:

(1)用户登录注册:支持用户进行注册和登录。

在这里插入图片描述

(2)选择图片识别:用户可以上传单张图片进行水果检测与识别,系统将识别出图片中的水果并显示相应的类别和置信度。

在这里插入图片描述

(3)视频识别:用户可以上传视频文件进行水果检测与识别,系统将实时识别视频中的水果并显示相应的类别和置信度。

在这里插入图片描述

(4)摄像头识别:用户可以使用摄像头进行实时水果检测与识别,系统将捕捉摄像头图像并实时识别出水果,显示相应的类别和置信度。

在这里插入图片描述
(5)更换模型和修改文字图标:用户可以点击右侧的模型选择按钮更换不同的模型,对于界面中的文字和图标的修改请参考文末的介绍。


2. 算法原理介绍

        本系统采用了基于深度学习的目标检测算法YOLOv5,该算法是YOLO系列算法的最新版本,相比于YOLOv3和YOLOv4,YOLOv5在检测精度和速度上都有很大的提升。YOLOv5算法的核心思想是将目标检测问题转化为一个回归问题。YOLOv5使用一种称为“Anchor Free”的方法来代替传统目标检测算法中的Anchor框,通过直接预测物体中心点的坐标来代替Anchor框。此外,YOLOv5还引入了一种称为SPP(Spatial Pyramid Pooling)的特征提取方法,这种方法可以在不增加计算量的情况下,有效地提取多尺度特征,提高检测性能。

        在YOLOv5中,首先将输入图像通过骨干网络进行特征提取,得到一系列特征图。然后,通过对这些特征图进行处理,将其转化为一组检测框和相应的类别概率分数,即每个检测框所属的物体类别以及该物体的置信度。YOLOv5中的特征提取网络使用CSPNet(Cross Stage Partial Network)结构,它将输入特征图分为两部分,一部分通过一系列卷积层进行处理,另一部分直接进行下采样,最后将这两部分特征图进行融合。这种设计使得网络具有更强的非线性表达能力,可以更好地处理目标检测任务中的复杂背景和多样化物体。

在这里插入图片描述

        在YOLOv5中,每个检测框由其左上角坐标(x,y)、宽度(w)、高度(h)和置信度(confidence)组成。同时,每个检测框还会预测C个类别的概率得分,即分类得分(ci),每个类别的得分之和等于1。因此,每个检测框最终被表示为一个(C+5)维的向量。在训练阶段,YOLOv5使用交叉熵损失函数来优化模型。损失函数由定位损失、置信度损失和分类损失三部分组成,其中定位损失和置信度损失采用了Focal Loss和IoU Loss等优化方法,能够有效地缓解正负样本不平衡和目标尺寸变化等问题。</font

         YOLOv5网络结构是由Input、Backbone、Neck、Prediction组成。Yolov5的Input部分是网络的输入端,采用Mosaic数据增强方式,对输入数据随机裁剪,然后进行拼接。Backbone是Yolov5提取特征的网络部分,特征提取能力直接影响整个网络性能。YOLOv5的Backbone相比于之前Yolov4提出了新的Focus结构。Focus结构是将图片进行切片操作,将W(宽)、H(高)信息转移到了通道空间中,使得在没有丢失任何信息的情况下,进行了2倍下采样操作。博主觉得YOLOv5不失为一种目标检测的高性能解决方案,能够以较高的准确率对海洋动物进行分类与定位。当然现在YOLOv6、YOLOv7、YOLOv8等算法也在不断提出和改进,等其代码版本成熟后博主也会再设计本系统的算法,敬请期待。

在这里插入图片描述


3. 数据集与预处理

        在水果识别领域有一些数据集如Perez-Borrero I, Marin-Santos D, Gegundez-Arias M E, et al. A fast and accurate deep learning method for strawberry instance segmentation[J]. Computers and Electronics in Agriculture, 2020, 178: 105736,如下图所示。

在这里插入图片描述
        还有Laboro Tomato数据集,也可参考这篇文章Real-time fruit detection using deep neural networks on CPU (RTFD): An edge AI application,包括介绍和算法都可以参考。

在这里插入图片描述

        本系统使用的水果检测数据集Fruit Detection Dataset,手动标注了包含苹果、香蕉、火龙果、番石榴、橙子、梨、菠萝、释迦果等8个类别的水果,共计3030张图片。该数据集中每个类别的水果都有大量的旋转和不同的光照条件,有助于训练出更加鲁棒的检测模型。本文实验的水果检测识别数据集包含训练集2424张图片,验证集303张图片,测试集303张图片,选取部分数据部分样本数据集如图所示。

在这里插入图片描述
        由于YOLOv5算法对输入图片大小有限制,需要将所有图片调整为相同的大小。为了在不影响检测精度的情况下尽可能减小图片的失真,我们将所有图片调整为640x640的大小,并保持原有的宽高比例。此外,为了增强模型的泛化能力和鲁棒性,我们还使用了数据增强技术,包括随机旋转、缩放、裁剪和颜色变换等,以扩充数据集并减少过拟合风险。


5. 系统实现

5.1 Python实现

        本系统的深度学习模型使用PyTorch实现,基于YOLOv5算法进行目标检测。在训练阶段,我们使用了预训练模型作为初始模型进行训练,然后通过多次迭代优化网络参数,以达到更好的检测性能。在训练过程中,我们采用了学习率衰减和数据增强等技术,以增强模型的泛化能力和鲁棒性。

        在测试阶段,我们使用了训练好的模型来对新的图片、视频和实时视频流进行检测。通过设置阈值,将置信度低于阈值的检测框过滤掉,最终得到检测结果。同时,我们还可以将检测结果保存为图片或视频格式,以便进行后续分析和应用。本系统基于YOLOv5算法,使用PyTorch实现。代码中用到的主要库包括PyTorch、NumPy、OpenCV、PyQt等。实现过程中,我们首先需要导入所需的库和模块:

import argparse
import random
  • 1
  • 2

import cv2
import numpy as np
import torch

from models.experimental import attempt_load
from utils.datasets import letterbox
from utils.general import non_max_suppression, check_img_size, scale_coords
from utils.torch_utils import time_synchronized, select_device

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

        然后,我们需要定义一些函数,其中predict()函数用于实现图片的预测推理;cv_imread()函数用于读取图片;plot_one_box()函数用于绘制预测框。

def predict(img):
    img = torch.from_numpy(img).to(device)
    img = img.half() if half else img.float()
    img /= 255.0
    if img.ndimension() == 3:
        img = img.unsqueeze(0)
t1 <span class="token operator">=</span> time_synchronized<span class="token punctuation">(</span><span class="token punctuation">)</span>
pred <span class="token operator">=</span> model<span class="token punctuation">(</span>img<span class="token punctuation">,</span> augment<span class="token operator">=</span><span class="token boolean">False</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span>
pred <span class="token operator">=</span> non_max_suppression<span class="token punctuation">(</span>pred<span class="token punctuation">,</span> opt<span class="token punctuation">.</span>conf_thres<span class="token punctuation">,</span> opt<span class="token punctuation">.</span>iou_thres<span class="token punctuation">,</span> classes<span class="token operator">=</span>opt<span class="token punctuation">.</span>classes<span class="token punctuation">,</span>
                           agnostic<span class="token operator">=</span>opt<span class="token punctuation">.</span>agnostic_nms<span class="token punctuation">)</span>
t2 <span class="token operator">=</span> time_synchronized<span class="token punctuation">(</span><span class="token punctuation">)</span>
InferNms <span class="token operator">=</span> <span class="token builtin">round</span><span class="token punctuation">(</span><span class="token punctuation">(</span>t2 <span class="token operator">-</span> t1<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span>

<span class="token keyword">return</span> pred<span class="token punctuation">,</span> InferNms
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

def cv_imread(filePath):
# 读取图片
cv_img = cv2.imdecode(np.fromfile(filePath, dtype=np.uint8), -1)

<span class="token keyword">if</span> <span class="token builtin">len</span><span class="token punctuation">(</span>cv_img<span class="token punctuation">.</span>shape<span class="token punctuation">)</span> <span class="token operator">&gt;</span> <span class="token number">2</span><span class="token punctuation">:</span>
    <span class="token keyword">if</span> cv_img<span class="token punctuation">.</span>shape<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">&gt;</span> <span class="token number">3</span><span class="token punctuation">:</span>
        cv_img <span class="token operator">=</span> cv_img<span class="token punctuation">[</span><span class="token punctuation">:</span><span class="token punctuation">,</span> <span class="token punctuation">:</span><span class="token punctuation">,</span> <span class="token punctuation">:</span><span class="token number">3</span><span class="token punctuation">]</span>
<span class="token keyword">return</span> cv_img
  • 1
  • 2
  • 3
  • 4

def plot_one_box(img, x, color=None, label=None, line_thickness=None):
# Plots one bounding box on image img
tl = line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1 # line/font thickness
color = color or [random.randint(0, 255) for _ in range(3)]
c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3]))
cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
if label:
tf = max(tl - 1, 1) # font thickness
t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]
c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3
cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA) # filled
cv2.putText(img, label, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA)

if name == main:
img_path = “./UI_rec/test_/b-1459-_jpg.rf.06e32fd1fbee5a10c776e1e63237904f.jpg”
image = cv_imread(img_path)
image = cv2.resize(image, (850, 500))
img0 = image.copy()
img = letterbox(img0, new_shape=imgsz)[0]
img = np.stack(img, 0)
img = img[:, :, ::-1].transpose(2, 0, 1) # BGR to RGB, to 3x416x416
img = np.ascontiguousarray(img)

pred<span class="token punctuation">,</span> useTime <span class="token operator">=</span> predict<span class="token punctuation">(</span>img<span class="token punctuation">)</span>

det <span class="token operator">=</span> pred<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span>
p<span class="token punctuation">,</span> s<span class="token punctuation">,</span> im0 <span class="token operator">=</span> <span class="token boolean">None</span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">,</span> img0
<span class="token keyword">if</span> det <span class="token keyword">is</span> <span class="token keyword">not</span> <span class="token boolean">None</span> <span class="token keyword">and</span> <span class="token builtin">len</span><span class="token punctuation">(</span>det<span class="token punctuation">)</span><span class="token punctuation">:</span>  <span class="token comment"># 如果有检测信息则进入</span>
    det<span class="token punctuation">[</span><span class="token punctuation">:</span><span class="token punctuation">,</span> <span class="token punctuation">:</span><span class="token number">4</span><span class="token punctuation">]</span> <span class="token operator">=</span> scale_coords<span class="token punctuation">(</span>img<span class="token punctuation">.</span>shape<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">:</span><span class="token punctuation">]</span><span class="token punctuation">,</span> det<span class="token punctuation">[</span><span class="token punctuation">:</span><span class="token punctuation">,</span> <span class="token punctuation">:</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">,</span> im0<span class="token punctuation">.</span>shape<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token builtin">round</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token comment"># 把图像缩放至im0的尺寸</span>
    number_i <span class="token operator">=</span> <span class="token number">0</span>  <span class="token comment"># 类别预编号</span>
    detInfo <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
    <span class="token keyword">for</span> <span class="token operator">*</span>xyxy<span class="token punctuation">,</span> conf<span class="token punctuation">,</span> cls <span class="token keyword">in</span> <span class="token builtin">reversed</span><span class="token punctuation">(</span>det<span class="token punctuation">)</span><span class="token punctuation">:</span>  <span class="token comment"># 遍历检测信息</span>
        c1<span class="token punctuation">,</span> c2 <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token builtin">int</span><span class="token punctuation">(</span>xyxy<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">(</span>xyxy<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token builtin">int</span><span class="token punctuation">(</span>xyxy<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token builtin">int</span><span class="token punctuation">(</span>xyxy<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
        <span class="token comment"># 将检测信息添加到字典中</span>
        detInfo<span class="token punctuation">.</span>append<span class="token punctuation">(</span><span class="token punctuation">[</span>names<span class="token punctuation">[</span><span class="token builtin">int</span><span class="token punctuation">(</span>cls<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>c1<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> c1<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> c2<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> c2<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">'%.2f'</span> <span class="token operator">%</span> conf<span class="token punctuation">]</span><span class="token punctuation">)</span>
        number_i <span class="token operator">+=</span> <span class="token number">1</span>  <span class="token comment"># 编号数+1</span>

        label <span class="token operator">=</span> <span class="token string">'%s %.2f'</span> <span class="token operator">%</span> <span class="token punctuation">(</span>names<span class="token punctuation">[</span><span class="token builtin">int</span><span class="token punctuation">(</span>cls<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">,</span> conf<span class="token punctuation">)</span>

        <span class="token comment"># 画出检测到的目标物</span>
        plot_one_box<span class="token punctuation">(</span>image<span class="token punctuation">,</span> xyxy<span class="token punctuation">,</span> label<span class="token operator">=</span>label<span class="token punctuation">,</span> color<span class="token operator">=</span>colors<span class="token punctuation">[</span><span class="token builtin">int</span><span class="token punctuation">(</span>cls<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
<span class="token comment"># 实时显示检测画面</span>
cv2<span class="token punctuation">.</span>imshow<span class="token punctuation">(</span><span class="token string">'Stream'</span><span class="token punctuation">,</span> image<span class="token punctuation">)</span>
<span class="token comment"># if cv2.waitKey(1) &amp; 0xFF == ord('q'):</span>
<span class="token comment">#     break</span>
c <span class="token operator">=</span> cv2<span class="token punctuation">.</span>waitKey<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token operator">&amp;</span> <span class="token number">0xff</span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74

        在这段Python代码中,我们首先定义了一个名为predict的函数,用于对输入的图像进行检测和分类。该函数输入一个图像,先将其转化为PyTorch Tensor,然后对图像进行预测和非极大值抑制,得到预测结果和推理时间。接下来我们定义了cv_imread函数,用于读取图片。cv_imread函数通过OpenCV库的imdecode函数读取图片,并将其转化为NumPy数组,然后返回该数组。接着我们定义了plot_one_box函数,该函数用于在图像上画出检测框和类别标签,其中函数参数中包括了待画出的图像、检测框坐标、类别标签、颜色等。

        最后,在if name == ‘main’:语句中,我们首先读取一张测试图片,并将其调整为合适的大小,然后将其输入到predict函数中进行检测和分类,得到检测结果和推理时间。接着,我们通过遍历检测结果,将检测到的目标物的信息添加到detInfo列表中,然后调用plot_one_box函数,将目标物的检测框和类别标签画在图像上。最后通过OpenCV库的imshow函数将结果图像实时显示在屏幕上。

        这部分代码是我们整个系统实现的关键部分,通过修改和集成该部分代码同样可以实现对输入视频和实时摄像头画面的实时检测和分类,并且可以通过界面将结果显示给用户,提高了系统的实用性。

5.2 PyQt界面设计

        PyQt是Python语言的GUI编程解决方案之一,可以快速地为Python程序创建GUI应用。在本文中,我们使用PyQt库创建一个图形化界面,为用户提供简单易用的交互界面,实现用户选择图片、视频或实时视频进行目标检测。这里介绍系统的GUI设计和开发过程,包括主窗口的设计、UI控件的布局以及信号槽的连接。

        在本系统中,使用PyQt5库设计了可视化的GUI界面,主要包括以下六个模块:

(1)图片检测模块:用户可以选择本地的一张图片进行检测,检测结果将在界面中实时显示。用户也可以选择多张图片进行批量检测,并将结果记录保存到本地。
(2)视频检测模块:用户可以选择本地的一个视频进行检测,检测结果将在界面中实时显示。用户也可以选择多个视频进行批量检测,并将结果记录保存到本地。
(3)实时检测模块:用户可以启动摄像头进行实时检测,检测结果将在界面中实时显示。
(4)更换模型模块:用户可以选择不同的预训练模型进行检测,系统提供了多种不同的预训练模型供用户选择。
(5)结果记录回看模块:用户可以查看历史检测结果,并对检测结果进行搜索和筛选。
(6)其他模块:界面中还包括了一些辅助模块,如登录注册、设置等。

        我们使用Qt Designer设计图形界面,然后使用PyQt将设计好的UI文件转换为Python代码。图形界面中包含多个UI控件,例如:菜单栏、工具栏、标签、按钮等。通过PyQt中的信号槽机制,可以使得UI控件与程序逻辑代码相互连接。

在这里插入图片描述

        界面设计使用了Qt Designer工具,通过拖拽组件的方式进行布局,同时也可以通过代码进行动态添加和修改。在界面的设计过程中,我们主要使用了以下几个组件:

(1)QLabel:用于显示文字和图片。
(2)QToolButton:用于实现按钮功能。
(3)QComboBox:用于实现下拉框功能,供用户选择预训练模型。
(4)QFileDialog:用于选择本地的图片和视频。
(5)QTableWidget:用于展示历史检测结果,并提供搜索和筛选功能。

        为了使得界面更加美观和易于操作,我们还可以自定义控件样式,例如在系统中使用的按钮等,都进行了样式的调整。具体实现方式是通过QSS文件,使用CSS语法进行样式定义。

        在图形界面的实现过程中,我们还需要使用Python中的OpenCV库实现视频的读取和显示。使用OpenCV可以快速实现视频的读取、播放和保存等操作,并且可以与PyQt进行结合,实现更为高效的图像和视频处理。下面我们给出系统GUI的示例图:

在这里插入图片描述


6. 实验结果与分析

        在实验结果与分析部分,我们不仅通过精度和召回率等指标来评估模型的性能,还通过损失曲线和PR曲线来分析训练过程

        我们使用了前面介绍的水果检测数据集进行训练,该数据集包含多种不同的水果类别,包括苹果、香蕉、橙子、西瓜等,共计8个类别。我们使用了YOLOv5算法,训练了300个epochs,训练过程截图如下。

在这里插入图片描述

        在训练过程中,我们使用tensorboard记录了模型在训练集和验证集上的损失曲线。从图6-1中可以看出,随着训练次数的增加,模型的训练损失和验证损失都逐渐降低,说明模型不断地学习到更加精准的特征。

在这里插入图片描述
        在训练结束后,我们对模型在测试集上进行了评估,得到了以下结果。下图展示了我们训练的YOLOv5模型在测试集上的PR曲线。可以看到,模型在不同类别上都取得了较高的召回率和精确率,整体表现良好。

在这里插入图片描述

        综上,我们训练的YOLOv5模型在水果检测数据集上表现良好,具有较高的检测精度和鲁棒性,可以在实际场景中应用。

        博主对整个系统进行了详细测试,最终开发出一版流畅得到清新界面,就是博文演示部分的展示,完整的UI界面、测试图片视频、代码文件,以及Python离线依赖包(方便安装运行,也可自行配置环境),均已打包上传,感兴趣的朋友可以通过下载链接获取。


下载链接

    若您想获得博文中涉及的实现完整全部程序文件(包括测试图片、视频,py, UI文件等,如下图),这里已打包上传至博主的面包多平台,见可参考博客与视频,已将所有涉及的文件同时打包到里面,点击即可运行,完整文件截图如下:

在这里插入图片描述

    在文件夹下的资源显示如下,下面的链接中也给出了Python的离线依赖包,读者可在正确安装Anaconda和Pycharm软件后,复制离线依赖包至项目目录下进行安装,离线依赖的使用详细演示也可见本人B站视频:win11从头安装软件和配置环境运行深度学习项目Win10中使用pycharm和anaconda进行python环境配置教程

在这里插入图片描述

注意:该代码采用Pycharm+Python3.8开发,经过测试能成功运行,运行界面的主程序为runMain.py和LoginUI.py,测试图片脚本可运行testPicture.py,测试视频脚本可运行testVideo.py。为确保程序顺利运行,请按照requirements.txt配置Python依赖包的版本。Python版本:3.8,请勿使用其他版本,详见requirements.txt文件;

完整资源中包含数据集及训练代码,环境配置与界面中文字、图片、logo等的修改方法请见视频,项目完整文件下载请见参考博客文章里面,或参考视频的简介处给出:➷➷➷

参考博客文章:https://zhuanlan.zhihu.com/p/626198529

参考视频演示:https://www.bilibili.com/video/BV1rT411h7dY/

离线依赖库下载链接https://pan.baidu.com/s/1hW9z9ofV1FRSezTSj59JSg?pwd=oy4n (提取码:oy4n )


界面中文字、图标和背景图修改方法:

        在Qt Designer中可以彻底修改界面的各个控件及设置,然后将ui文件转换为py文件即可调用和显示界面。如果只需要修改界面中的文字、图标和背景图的,可以直接在ConfigUI.config文件中修改,步骤如下:
        (1)打开UI_rec/tools/ConfigUI.config文件,若乱码请选择GBK编码打开。
        (2)如需修改界面文字,只要选中要改的字符替换成自己的就好。
        (3)如需修改背景、图标等,只需修改图片的路径。例如,原文件中的背景图设置如下:

mainWindow = :/images/icons/back-image.png

 
 
  • 1
  • 1

        可修改为自己的名为background2.png图片(位置在UI_rec/icons/文件夹中),可将该项设置如下即可修改背景图:

mainWindow = ./icons/background2.png

 
 
  • 1
  • 1

结束语

        由于博主能力有限,博文中提及的方法即使经过试验,也难免会有疏漏之处。希望您能热心指出其中的错误,以便下次修改时能以一个更完美更严谨的样子,呈现在大家面前。同时如果有更好的实现方法也请您不吝赐教。


参考文献

[1] Bargoti, S., & Underwood, J. P. (2017). Image segmentation for fruit detection and yield estimation in apple orchards. Journal of Field Robotics, 34(6), 1039-1060.
[2] Girshick, R., Donahue, J., Darrell, T., & Malik, J. (2014). Rich feature hierarchies for accurate object detection and semantic segmentation. In Proceedings of the IEEE conference on computer vision and pattern recognition (pp. 580-587).
[3] Girshick, R. (2015). Fast R-CNN. In Proceedings of the IEEE international conference on computer vision (pp. 1440-1448).
[4] Ren, S., He, K., Girshick, R., & Sun, J. (2015). Faster R-CNN: Towards real-time object detection with region proposal networks. In Advances in neural information processing systems (pp. 91-99).
[5] Liu, W., Anguelov, D., Erhan, D., Szegedy, C., Reed, S., Fu, C. Y., & Berg, A. C. (2016, October). SSD: Single shot multibox detector. In European conference on computer vision (pp. 21-37). Springer, Cham.
[6] Lin, T. Y., Goyal, P., Girshick, R., He, K., & Dollár, P. (2017). Focal loss for dense object detection. In Proceedings of the IEEE international conference on computer vision (pp. 2980-2988).
[7] Redmon, J., Divvala, S., Girshick, R., & Farhadi, A. (2016). You only look once: Unified, real-time object detection. In Proceedings of the IEEE conference on computer vision and pattern recognition (pp. 779-788).
[8] Redmon, J., & Farhadi, A. (2017). YOLO9000: Better, faster, stronger. In Proceedings of the IEEE conference on computer vision and pattern recognition (pp. 7263-7271).
[9] Redmon, J., & Farhadi, A. (2018). YOLOv3: An incremental improvement. arXiv preprint arXiv:1804.02767.
[10] Bochkovskiy, A., Wang, C. Y., & Liao, H. Y. M. (2020). YOLOv4: Optimal speed and accuracy of object detection. arXiv preprint arXiv:2004.10934.
[11] Sa, I., Ge, Z., Dayoub, F., Upcroft, B., Perez, T., & McCool, C. (2016). DeepFruits: A fruit detection system using deep neural networks. Sensors, 16(8), 1222.
[12] Rahnemoonfar, M., & Sheppard, C. (2017). Deep count: Fruit counting based on deep simulated learning. Sensors, 17(4), 905.
[13] Chakraborty S K, Subeesh A, Dubey K, et al. Development of an optimally designed real-time automatic citrus fruit grading–sorting​ machine leveraging computer vision-based adaptive deep learning model[J]. Engineering Applications of Artificial Intelligence, 2023, 120: 105826.
[14] Jocher, G., Stoken, A., Borovec, J., Bendahan, R. A., Puig, D., Tokozume, Y., … & Guan, H. (2021). Ultralytics/yolov5: v5.0-YOLOv5-PyTorch.

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/140231
推荐阅读
相关标签
  

闽ICP备14008679号