回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页
best-icon

基于YOLO的水果目标检测装置 简单

头像 zoey不种土豆 2025.06.04 154 0

1.项目介绍

1.1项目简介

本项目基于YOLOv8的目标检测功能,实现了实时视频画面中的水果的种类和数量的检测。通过训练YOLOv8模型,将模型部署到行空板M10上,利用YOLOv8模型推理输出的类别标签和目标框,通过摄像头,从实时视频中检测出视频画面中的19种水果的类别和数量如苹果、香蕉、橙子等,并框出,为水果的自动化分拣、质量检测以及零售库存管理等应用场景提供高效的技术支持。

1.2项目效果视频

2.项目制作框架

本水果识别项目是通过YOLO目标检测算法,使用水果数据集,训练水果目标检测模型,实现画面中水果的检测,显示水果类别标签、数量和框出其位置。

目标检测简单来说就是在图片或视频中找到特定的物体,并确定它们的位置和类别。

下图是我们的项目制作框架图,我们在电脑端完成模型的训练与测试,将模型部署到智能硬件——行空板M10中完成水果目标检测模型的应用,制作出智能水果检测装置。

微信图片编辑_20250605113212.jpg

(YOLO水果检测项目框架图)

 

image.png

(YOLO项目框架图,供参考)

 

3.软硬件环境准备

3.1软硬件器材清单

image.png

注意行空板M10固件在0.3.5——0.4.0的版本均可以用于制作本项目,但都需要为行空板装conda环境,详情见3.3硬件环境准备。

 

3.2软件环境准备

由于我们使用电脑训练水果检测模型,因此需要在电脑端安装相应的库。

首先按下win+R,输入cmd进入窗口。

image4.png
image5.png

 

 

在命令行窗口中依次输入以下指令,安装ultralytics库

代码
pip install ultralytics
pip install onnx==1.16.1
pip install onnxruntime==1.17.1

输入之后会出现以下页面。

image6.png

当命令运行完成,出现以下截图表示安装成功。

image7.png

 

3.3硬件环境准备

在本项目中我们将要将训练好的YOLOv8框架的模型部署到行空板中,进行推理和执行操作。为了在行空板上成功运行YOLOv8,我们将使用Ultralytics官方提供的库进行部署 。

使用USB数据线连接行空板与电脑,等待行空板屏幕亮起表示行空板开机成功。

image8.png

打开编程软件Mind+,点击左下角的扩展,在官方库中找到行空板库点击加载

image9.png
image10.png

点击返回,点击连接设备,找到10.1.2.3.点击连接,等待连接成功.

image11.png

请参考此篇帖子的环境配置教程:如何在行空板上运行 YOLOv10n? 请按照这篇帖子的教程完成到Step 7 安装utralytics,如下图。

image12.png

除了utralytics库本项目还需要使用onnx、onnxruntime、opencv -python 和pinpong库 依次在Mind+终端输入以下命令

(注意行空板需要联网,点此查看行空板联网操作教程

image13.png

代码
pip install onnx==1.16.1
pip install onnxruntime==1.17.1
pip install opencv-python
pip install pinpong

在Mind+终端输入以下指令,可以检查相应库是否安装成功

代码
pip list

image14.png
image15.png

 

4. 制作步骤

4.1数据集准备

为了训练水果目标检测模型,我们需要准备COCO格式的水果数据集。一个标准的目标检测数据集包括训练集和验证集,每个集都包含图像和标注文件(txt文件)。标注文件能提供目标的位置和类别信息。

以水果检测的数据集为例为例,标准的用于目标检测的数据集的格式如下。

image16.png

 

我们使用的水果数据集总共包含19种不同类别的水果如苹果、香蕉、梨、橘子等,其中训练集共有11,227 个图片文件,验证集共有2,992个图片文件(数据集在文档最后的附件)。

代码
fruits_dataset/             //水果数据集
│  
├── train/                  // 训练集,使用训练集的数据进行模型训练
│   ├── images/             // 训练集的图片文件夹
│   └── labels/             // 训练集中图片的标注信息文件夹,作用是提供图像中目标的位置和类别信息。
│  
├── val/                    // 验证集,验证集用于评估模型在未见过的数据上的表现
│   ├── images/             // 验证集的图片文件夹
│   └── labels/             // 验证集图片的标注信息文件夹
│  
└── data.yaml             // 数据集配置文件,用于定义数据集的参数,通常是一个 YAML 文件。

其中YAML文件一个对于目标检测模型训练很重要的文件。YAML 文件通常包含数据集的路径信息,这些路径告诉模型训练脚本在哪里找到训练集和验证集的图像和标注文件。除此之外,YAML 文件定义了类别索引与类别名称之间的映射关系。这对于模型在训练和推理过程中正确识别和分类目标至关重要。如下图,是水果目标检测模型的YAML文件。

image17.png

准备好数据集后,接下来我们就可以进入模型的训练环节了。

 

4.2模型训练

我们首先要去ultralytics的官方仓库下载YOLO项目文件。链接:https://github.com/ultralytics/ultralytics。如下图,将官方文件夹下载下来,并解压(文件夹已附在在本篇文档的最后)。

image18.png

将文件放到一个能找到的路径,打开Mind+,选择Python模式下的代码模式,如下图。

image19.png

在右侧“文件系统”中找到"电脑中的文件",找到此文件夹进行添加。

image20.png
image21.png

 

添加好后可以观察到如此下图。

image22.png

点击"新建文件夹",在ultralytics文件夹中分别新建三个文件夹,依次命名为"datasets"(用于存放数据集),"yamls"(用于存放数据集对应的yaml文件)"runs"(用于存放训练模型的py文件)。

image23.png

建好后如下图。

image24.png

将水果数据集的训练集和验证集文件夹放入"dataset"文件夹,将水果数据集的yaml文件放入"yamls"文件夹。

image25.png

接着我们在"runs"文件夹中建立一个叫做"train.py"的文件,在此文件中编写训练YOLO模型的代码。

image26.png

将训练代码粘贴到train.py中点击运行。我们在预训练模型"yolov8s"基础上进行水果目标检测模型的训练,设置训练轮次是2轮。图片的尺寸是320。

代码
from ultralytics import YOLO  # 导入YOLO类,用于加载和训练模型
import time  # 导入time模块,用于延迟操作
import os  # 导入os模块,用于操作文件路径

# 打印当前工作目录,帮助确认代码运行的路径是否正确
#print("Current working directory:", os.getcwd())

# 确保路径正确
model = YOLO('yolov8s.pt')  # 加载YOLOv8s预训练模型,yolov8s.pt是一个轻量级模型,适合资源有限的环境

# 开始训练模型
results = model.train(
    data=os.path.join(os.getcwd(), '..', 'yamls', 'data.yaml'),  # 数据配置文件路径
    # 使用相对路径,确保指向正确的yamls文件夹,data.yaml 文件中定义了数据集的路径、类别数等信息
    epochs=2,  # 设置训练轮数为2(通常需要更多轮数,这里可能是测试)
    imgsz=320,  # 设置输入图像大小为320x320,降低图像大小可以减少显存占用,适合资源有限的环境
    device='cpu',  # 使用CPU进行训练(如果无GPU或CUDA环境)
    # 如果有GPU,可以设置为 '0' 或 'cuda'
    workers=0,  # 数据加载线程数(Windows系统建议设置为0)
    # workers=0 表示主进程加载数据,避免多线程问题
    batch=2,  # 设置批量大小为2,降低批量大小可以减少显存占用,但可能影响训练效率
    cache=False  # 不使用缓存(避免内存占用过多)
)

运行时可观察终端,自动下载预训练模型"yolov8s.pt",进行模型的训练。

image27.png

YOLO模型的训练对电脑的配置要求比较高,使用电脑CPU一般训练时间较长,可以考虑使用GPU或者云端算力进行训练,这里我们使用的时本地电脑的CPU训练方法,操作比较简单,耗时略长。

image28.png

当训练完成后,我们可以观察"runs"文件夹中自动生成了"detect"文件夹(代表了目标检测任务),里面存放了训练模型的数据和训练好的模型文件。

image29.png
image30.png

模型训练完成可以观察终端出现以下数据,是标记的所有水果类别标签和它的准确率、召回率、F1等数据。

image31.png

 

4.3模型转换

我们训练得到的"best.pt"可以直接用于推理,我们也可以将"best.pt"转成onnx格式的模型文件。ONNX 格式,也是一种模型文件的格式,更加通用,可以与各种推理引擎兼容,提供更高效的推理速度

image32.png

使用以下代码将pt格式的模型文件转成onnx格式的模型文件。

 

代码
from ultralytics import YOLO

# 模型路径,这里填你的pt文件的实际路径
model_path = r'C:\Users\li720\Downloads\ultralytics-main\ultralytics-main\runs\runs\detect\train5\weights\best.pt'  # 训练完成后保存的模型路径

# 加载模型
model = YOLO(model_path)

# 导出为onnx格式
model.export(format='onnx')

print("模型已成功导出为onnx格式")

转换好后,可以在同一目录下找到转换好的onnx模型。

image33.png

 

4.4模型测评与导出

我们先在电脑端测试一下模型的性能,将训练好的模型拖入Mind+项目中的文件下

image34.png

再在项目中的文件中新建一个叫做"img_inference.py"(用来测试图片推理效果),同时将测试图片"test.png"也拖入项目中的文件夹下。

测试图片如下图所示,由于我们训练模型时规定的输入尺寸为320*320,所以推理时图片尺寸不得大于这个尺寸。

image35.png

将以下代码复制到"img_inference.py"文件中进行图片推理测试。

 

 

代码
from ultralytics import YOLO
import cv2

# 1. 加载预训练模型
model = YOLO('best.onnx', task='detect')  # 显式指定任务为检测

# 2. 进行图像推理(带类别统计)
def predict_image(image_path, conf=0.5):
    # 读取图像并调整尺寸
    img = cv2.imread(image_path)
    img = cv2.resize(img, (320, 320))
    
    # 执行推理
    results = model.predict(
        source=img,
        conf=conf,
        save=False,
        imgsz=320
    )
    
    # 初始化类别计数器
    class_counts = {}
    
    # 遍历检测结果
    for result in results:
        # 获取检测到的所有类别
        detected_classes = result.boxes.cls.tolist()
        
        # 统计每个类别的出现次数
        for class_id in detected_classes:
            class_name = result.names[int(class_id)]
            class_counts[class_name] = class_counts.get(class_name, 0) + 1
    
    # 可视化结果
    annotated_img = results[0].plot()
    
    # 显示结果
    cv2.imshow('Detection', annotated_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    return results, class_counts  # 返回结果和统计信息

if __name__ == '__main__':
    try:
        # 执行检测并获取统计结果
        image_results, counts = predict_image('test.png', conf=0.6)
        
        # 打印检测统计
        print("\n检测结果统计:")
        for class_name, count in counts.items():
            print(f"{class_name}: {count}个")
            
        # 原始检测信息(可选)
        print("\n详细检测信息:")
        for result in image_results:
            for box in result.boxes:
                print(f"类别: {result.names[int(box.cls)]}, 置信度: {box.conf.item():.2f}")
                
    except Exception as e:
        print(f"发生错误: {str(e)}")

点击Mind+右上角的”运行",运行代码观察效果。

image36.png

当程序运行时,可以观察到弹出以下窗口,显示在测试图片上的推理结果。观察图片,发现模型成功的检测到了图片中的四个苹果,且置信度都比较高,效果比较好。

image37.png

观察终端的输出,可以看到终端出现了检测到的水果类别的统计信息。

image38.png

接着我们可以继续创建一个叫做"cv_imference.py"的文件(测试实时视频流下的推理效果,可以观看注释了解代码功能),将以下推理代码粘贴到"cv.inference.py"文件中。

代码
import cv2  # 导入OpenCV库,用于图像处理和视频捕获
from ultralytics import YOLO  # 导入YOLO模型库,用于目标检测

# 加载YOLO模型
model = YOLO('best.onnx', task='detect')  # 加载模型文件 'best.onnx',并明确指定任务类型为检测任务

# 初始化摄像头
cap = cv2.VideoCapture(0)  # 打开默认摄像头(设备编号为0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)  # 设置摄像头捕获的帧宽度为320像素
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 320)  # 设置摄像头捕获的帧高度为320像素

# 检查摄像头是否成功打开
if not cap.isOpened():
    print("无法打开摄像头,请检查设备编号或摄像头连接。")
    exit()  # 如果摄像头无法打开,程序退出

try:
    # 进入主循环,实时处理视频流
    while True:
        ret, frame = cap.read()  # 从摄像头读取一帧图像
        if not ret:  # 如果读取失败(例如摄像头关闭),退出循环
            break
        
        # 转换颜色空间,将BGR格式的图像转换为RGB格式
        rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)  # YOLO模型需要RGB格式的输入
        
        # 使用YOLO模型进行目标检测
        results = model(rgb_frame, imgsz=320, verbose=False, conf=0.2)  # 对RGB图像进行推理,指定输入图像尺寸为320x320,并设置置信度阈值0.2才输出
        
        # 获取检测结果
        detections = results[0].boxes.data.tolist()  # 提取检测框信息,将其转换为列表格式
        
        # 统计水果数量
        fruit_counts = {}  # 创建一个字典用于存储每种水果的数量
        for detection in detections:  # 遍历每个检测结果
            class_id = int(detection[5])  # 获取类别ID(位于检测框数据的第6个位置)
            class_name = model.names[class_id]  # 根据类别ID获取对应的类别名称(例如水果名称)
            
            # 更新水果计数
            fruit_counts[class_name] = fruit_counts.get(class_name, 0) + 1  # 如果类别已存在,计数加1;否则初始化为1
        
        # 绘制检测结果
        annotated_frame = results[0].plot()  # 使用YOLO库自带的功能绘制检测框和类别标签
        
        # 在图像上添加水果数量统计信息
        y_offset = 30  # 初始化文本的垂直偏移量
        for fruit, count in fruit_counts.items():  # 遍历统计结果
            cv2.putText(  # 在图像上绘制文本
                annotated_frame, 
                f"{fruit}: {count}",  # 文本内容,显示水果名称和数量
                (10, y_offset),  # 文本起始位置
                cv2.FONT_HERSHEY_SIMPLEX,  # 字体类型
                0.7,  # 字体大小
                (0, 255, 0),  # 文本颜色(绿色)
                2  # 文本线条粗细
            )
            y_offset += 30  # 更新文本的垂直偏移量,避免文本重叠
        
        # 显示结果图像
        cv2.imshow(  # 显示处理后的图像
            'Detection',  # 窗口标题
            cv2.cvtColor(annotated_frame, cv2.COLOR_RGB2BGR)  # 将RGB格式的图像转换为BGR格式
        )
        
        # 按下 'a' 键退出程序
        if cv2.waitKey(1) == ord('a'):  # 检测按键事件,如果按下 'a' 键
            break

except KeyboardInterrupt:  # 捕获键盘中断(例如用户按下Ctrl+C)
    print("程序被用户中断。")

finally:  # 无论程序是否正常退出,都会执行以下代码
    cap.release()  # 释放摄像头资源
    cv2.destroyAllWindows()  # 关闭所有OpenCV创建的窗口

运行程序,可以看到出现一个窗口实时的显示电脑摄像头放入画面,并将画面中的水果检测结果实时的显示出来.这里视频流的尺寸仍是320*320。相比图片推理效果来看,受视频画质的限制,视频推理的置信度结果有所降低,不过准确度还是可以的。

image39.png

 

4.5部署模型到行空板完成执行操作

接着我们可以部署模型到行空板中制作水果检测装置。使用USB数据线连接电脑与行空板。

image8.png

连接行空板与摄像头。

image40.jpeg

打开编程软件Mind+,点击左下角的扩展,在官方库中找到行空板库点击加载

image9.png
image10.png

点击返回,点击连接设备,找到10.1.2.3.点击连接,等待连接成功.

image11.png
image41.png

 

我们选中模型文件点击上传到行空板中。上传成功能在行空板的根目录下找到模型文件。

image42.png
image43.png

同样的,我们将"cv_inference.py"文件也上传到行空板中。

image44.png

保持行空板的连接,在终端输入以下指令来激活行空板的yolo环境(请确保完成3.2硬件环境部署准备)。

代码
conda activate yolo

image45.png

接着在终端输入以下指令,在行空板中运行"cv_inference.py"文件,第一次加载模型比较慢,请耐心等待。

代码
python cv_inference.py

image46.png

运行成功后,我们可以调整摄像头的角度,观察行空板屏幕能自动圈出画面中的水果,将数量显示在行空板屏幕画面左上角。这样,我们就成功用行空板M10与摄像头制作出来一个能实时检测并统计水果数量的智能水果检测装置了。

image47.png

 

4.6核心代码解析

我们一起来看一下在行空板上运行的'cv_inference.py'代码的核心功能代码。

如下图,此程序主要分成三个主要部分(1)初始化模型设置与摄像头:加载模型、配置摄像头参数。(2)逐帧推理与原始结果输出:负责逐帧读取摄像头数据,调用模型进行推理,并输出原始检测结果。(3)结果后处理与展示:负责对原始检测结果进行进一步处理,比如统计水果数量、绘制检测框和标签、显示结果等。其中第1、2部分是通用的,是每一个目标检测项目都需要的,无需更改。第3部分是灵活的,可以根据不同的需求对模型推理的原始结果进行处理,实现想要的功能。

image48.png

怎么二次处理原始推理结果呢?,我们先来看看原始推理输出的结果有什么吧!

在程序中,我们使用的是以下语句来获取模型推理和打印推理结果。model()是YOLO模型的推理函数,conf=0.5设置置信度阈值为0.5,只有置信度大于或等于这个阈值的检测结果才会被保留,这个值可以根据实际需要进行修改。results存储了模型推理的输出结果。可以使用print语句将results打印出来。

代码
    # 使用YOLO模型进行目标检测
   results = model(rgb_frame, imgsz=320, verbose=False, conf=0.5)  # 对RGB图像进行推理,指定输入图像尺寸为320x320,并设置置信度阈值0.2才输出
    print('模型的原始输出:',results)

如下图,是我打印的模型推理的原始结果。

image49.png
image50.png

这里,以表格的形式整理了模型原始输出的全部内容,如下。我们可以观察到原始的推理输出有比较多的内容,在项目的人制作中不是每一个输出数据都要用到,其中最常被用的数据是"boxes"和"names"。boxes: 包含检测框的详细信息,包括边界框坐标、置信度和类别ID。这是最常被使用的数据。names: 提供类别ID到类别名称的映射,用于将检测结果转换为人类可读的类别名称。

image.png

 

为了能够从每一次推理的原始输出中整理出画面中出现的水果的类别与数量,我们使用以下代码,遍历boxes数据,从中提取出检测出的每个类别与其置信度,同时统计,每个类别水果每出现一次就加1,最后将结果以绘制文字的形式显示在画面中,从而实现了统计画面中每种水果的数量的功能。

代码
        # 获取检测结果
        detections = results[0].boxes.data.tolist()  # 提取检测框信息,将其转换为列表格式
        
        # 统计水果数量
        fruit_counts = {}  # 创建一个字典用于存储每种水果的数量
        for detection in detections:  # 遍历每个检测结果
            class_id = int(detection[5])  # 获取类别ID(位于检测框数据的第6个位置)
            class_name = model.names[class_id]  # 根据类别ID获取对应的类别名称(例如水果名称)
            
            # 更新水果计数
            fruit_counts[class_name] = fruit_counts.get(class_name, 0) + 1  # 如果类别已存在,计数加1;否则初始化为1
        
        # 绘制检测结果
        annotated_frame = results[0].plot()  # 使用YOLO库自带的功能绘制检测框和类别标签
        
        # 在图像上添加水果数量统计信息
        y_offset = 30  # 初始化文本的垂直偏移量
        for fruit, count in fruit_counts.items():  # 遍历统计结果
            cv2.putText(  # 在图像上绘制文本
                annotated_frame, 
                f"{fruit}: {count}",  # 文本内容,显示水果名称和数量
                (10, y_offset),  # 文本起始位置
                cv2.FONT_HERSHEY_SIMPLEX,  # 字体类型
                0.7,  # 字体大小
                (0, 255, 0),  # 文本颜色(绿色)
                2  # 文本线条粗细
            )
            y_offset += 30  # 更新文本的垂直偏移量,避免文本重叠
        

项目扩展思考:除了统计水果数量,我们可以修改第三部分的代码,可以结合硬件或实际的应用场景进行扩展,例如添加语音合成模块,将结果播报出来;或者只检测并显示某一类特定的水果数量;还可以通过列表增加每一类水果对应的单价,从而实现水果自动检测计价等等的装置。

5.项目相关资料附录

image.png

本项目相关资料见网盘:
链接: https://pan.baidu.com/s/1rL-RqyXj2_NsjJ119JeHPw?pwd=mz4j

评论

user-avatar