当前位置:   article > 正文

基于深度学习的水果检测与识别系统(Python界面版,YOLOv5实现)_yolo图片识别分类python_yolov5识别水果

yolov5识别水果

在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

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
  • 12

然后,我们需要定义一些函数,其中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 = time_synchronized()
    pred = model(img, augment=False)[0]
    pred = non_max_suppression(pred, opt.conf_thres, opt.iou_thres, classes=opt.classes,
                               agnostic=opt.agnostic_nms)
    t2 = time_synchronized()
    InferNms = round((t2 - t1), 2)

    return pred, InferNms


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

    if len(cv_img.shape) > 2:
        if cv_img.shape[2] > 3:
            cv_img = cv_img[:, :, :3]
    return cv_img


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, useTime = predict(img)

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

            label = '%s %.2f' % (names[int(cls)], conf)

            # 画出检测到的目标物
            plot_one_box(image, xyxy, label=label, color=colors[int(cls)])
    # 实时显示检测画面
    cv2.imshow('Stream', image)
    # if cv2.waitKey(1) & 0xFF == ord('q'):
    # break
    c = cv2.waitKey(0) & 0xff

  • 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
  • 75

在这段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://www.cnblogs.com/sixuwuxian/p/17372580.html

参考视频演示: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
  • 2

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)

/6c361282296f86381401c05e862fe4e9.png)

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)

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

闽ICP备14008679号