使用Yolov5实现智能垃圾分类系统

简介: 使用Yolov5实现智能垃圾分类系统

简介

在这篇博客中,我们将详细介绍如何使用Yolov5构建智能垃圾分类系统,从数据准备到模型部署的全过程。为大家提供有关Yolov5在实际项目中应用的思路和方法。

**1. 背景与挑战**

在这一部分,我们将介绍垃圾分类的环保意义,当前面临的挑战,以及目标检测技术在垃圾分类中的潜力和优势。

**1.1 垃圾分类的环保意义**

随着人口增长和经济发展,全球垃圾产量逐年增加。处理这些垃圾不仅消耗大量资源,还会对环境造成严重影响。因此,垃圾分类成为了一项重要的环保措施。垃圾分类可以实现以下目的:

- 提高资源回收率:通过分类回收,可回收物可以被重新利用,降低对自然资源的开采和消耗。

- 减少环境污染:合理处理有害垃圾和厨余垃圾,防止有毒物质进入环境,减少温室气体排放。

- 降低处理成本:分类后的垃圾处理效率更高,可以降低垃圾填埋、焚烧等处理方式的成本。

- 增强环保意识:通过普及垃圾分类知识,提高公众的环保意识,形成良好的环保习惯。

**1.2 当前面临的挑战**

尽管垃圾分类具有重要意义,但在实际推广过程中,仍然存在许多挑战:

- 缺乏分类意识:许多人对垃圾分类的重要性认识不足,缺乏积极参与的动力。

- 分类标准不统一:不同地区的分类标准可能存在差异,导致公众对分类方法的困惑。

- 分类设施不足:部分地区缺乏足够的回收设施和处理能力,影响垃圾分类的推广效果。

- 分类效率低下:传统的人工分类效率较低,且可能存在分类错误,影响资源回收和环境保护。

**1.3 目标检测技术在垃圾分类中的潜力和优势**

为了解决上述挑战,目标检测技术的引入具有巨大潜力。通过将目标检测算法应用于垃圾分类,我们可以实现以下优势:

- 提高分类准确率:目标检测算法可以自动识别和分类不同类型的垃圾,减少人为错误。

- 提高分类效率:相比人工分类,计算机视觉技术可以实时、高速地处理垃圾图像,提高分类效率。

- 降低人力成本:自动化垃圾分类系统可以减少对人力资源的依赖,降低运营成本。

- 智能监测与反馈:通过智能设备收集垃圾分类数据,为政策制定和设施优化提供支持。

综上所述,目标检测技术在垃圾分类领域具有广泛的应用前景,有望改善当前的垃圾处理和资源回收状况。在后续部分,我们将详细介绍如何使用Yolov5实现智能垃圾分类系统。

**2. Yolov5简介**

在这一部分,我们将简要介绍Yolov5的原理、特点和应用场景,并与其他目标检测算法(如SSD、Faster R-CNN等)进行性能对比。

**2.1 Yolov5原理**

Yolov5(You Only Look Once v5)是一种实时目标检测算法,由Joseph Redmon首次提出。经过多次迭代优化,Yolov5成为了目标检测领域的一种高效、准确的算法。其主要特点包括:

- 单阶段检测:Yolov5采用单阶段检测策略,直接在特征图上预测目标的类别和位置,避免了复杂的区域提议和回归过程。

- 多尺度特征融合:Yolov5通过融合不同尺度的特征图,可以检测到不同大小的目标,提高检测性能。

- 锚框设计:Yolov5使用聚类分析方法自动生成一组锚框,以适应不同形状和大小的目标,提高检测准确性。

**2.2 Yolov5特点**

Yolov5具有以下特点:

- 高速:由于采用单阶段检测策略,Yolov5在实时目标检测任务中具有很高的速度。

- 准确:通过多尺度特征融合和锚框设计,Yolov5在多种目标检测任务中取得了较高的准确率。

- 灵活:Yolov5提供了不同大小的模型(如yolov5s、yolov5m、yolov5l等),可以根据计算资源和性能要求进行选择。

**2.3 应用场景**

Yolov5广泛应用于各种目标检测场景,如:

- 人脸检测与识别:用于监控、安防、人机交互等领域。

- 无人驾驶:用于行人、车辆、交通标志等目标的检测和跟踪。

- 智能制造:用于产品缺陷检测、自动化分拣和包装等任务。

- 在本文中,我们将应用Yolov5于智能垃圾分类系统,提高分类效率和准确率。

**2.4 与其他目标检测算法的性能对比**

Yolov5与其他主流目标检测算法(如SSD、Faster R-CNN等)相比具有以下优势:

- 相对较高的速度:Yolov5采用单阶段检测策略,减少了计算复杂度,具有较高的实时性。

- 较高的准确率:Yolov5通过多尺度特征融合和锚框设计,在各种目标检测任务中取得了较高的准确率。

- 更好的平衡性:Yolov5在速度和准确率之间取得了较好的平衡,适用于资源受限的环境。

总结,Yolov5是一种高效、准确的目标检测算法,适合应用于智能垃圾分类等实时目标检测任务。在接下来的部分,我们将详细介绍如何使用Yolov5构建智能垃圾分类系统。

在这部分,我们将详细介绍如何准备垃圾分类数据集,并提供相应的代码实现。整个过程分为三个部分:数据收集、数据标注和数据预处理。

### 3. 准备垃圾分类数据集

#### 3.1 数据收集

为了收集垃圾分类数据集,你可以从互联网上下载图片,或者使用摄像头拍摄现场垃圾图片。在这个过程中,需要保证图片的多样性和代表性,同时确保图片中包含的垃圾类别覆盖了你想要识别的所有类别。

#### 3.2 数据标注

对于收集到的图片,需要进行目标检测标注。这里推荐使用[labelImg](https://github.com/tzutalin/labelImg)工具进行标注。为了与YOLOv5兼容,你需要将标注输出设置为YOLO格式。具体操作如下:

1. 下载并安装labelImg:

git clone https://github.com/tzutalin/labelImg.git
cd labelImg
pip install -r requirements/requirements.txt
make qt5py3
```

2. 运行labelImg,打开图像文件夹,然后为每张图片中的垃圾物体绘制边界框并指定类别标签:

python labelImg.py
```

3. 完成标注后,确保每张图片对应一个同名的`.txt`文件,其中包含YOLO格式的标注信息。

#### 3.3 数据预处理

在这个阶段,我们将对标注好的数据进行预处理,包括划分数据集、调整文件格式和进行数据增强。

**1. 划分数据集**

我们需要将数据划分为训练集、验证集和测试集。以下代码实现了根据给定的比例(如80%训练、10%验证、10%测试)将数据划分为三个子集,并将文件路径保存到相应的文本文件中。

import os
import random
import argparse
from pathlib import Path
def split_dataset(data_dir, output_dir, train_ratio=0.8, val_ratio=0.1, test_ratio=0.1):
    data_dir = Path(data_dir)
    output_dir = Path(output_dir)
    output_dir.mkdir(parents=True, exist_ok=True)
    # 获取所有图像文件
    image_files = list(data_dir.glob("*.jpg")) + list(data_dir.glob("*.png"))
    # 随机打乱
    random.shuffle(image_files)
    total_count = len(image_files)
    # 划分数据集
    train_count = int(total_count * train_ratio)
    val_count = int(total_count * val_ratio)
    train_files = image_files[:train_count]
    val_files = image_files[train_count:train_count + val_count]
    test_files = image_files[train_count + val_count:]
    # 保存文件路径
    with open(output_dir / "train.txt", "w") as f:
        f.writelines(f"{str(file)}\n" for file in train_files)
    with open(output_dir / "val.txt", "w") as f:
        f.writelines(f"{str(file)}\n" for file in val_files)
    with open(output_dir / "test.txt", "w") as f:
        f.writelines(f"{str(file)}\n" for file in test_files)
if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Split dataset into train, val and test.")
    parser.add_argument("data_dir", help="Directory containing images and labels.")
    parser.add_argument("output_dir", help="Directory to save train.txt, val.txt and test.txt.")
    parser.add_argument("--train_ratio", type=float, default=0.8, help="Training set ratio.")
    parser.add_argument("--val_ratio", type=float, default=0.1, help="Validation set ratio.")
    parser.add_argument("--test_ratio", type=float, default=0.1, help="Test set ratio.")
    args = parser.parse_args()
    split_dataset(args.data_dir, args.output_dir, args.train_ratio, args.val_ratio, args.test_ratio)

**2. 数据增强**

为了提高模型的泛化能力,我们可以对训练集进行数据增强。这里我们使用[Albumentations](https://github.com/albumentations-team/albumentations)库进行数据增强。首先,安装Albumentations库:

pip install albumentations

接下来,定义一个函数来执行数据增强。以下代码示例展示了如何应用随机水平翻转、随机旋转和随机亮度对比度变换:

import cv2
import numpy as np
import albumentations as A
def augment_image(image, annotations, augmentations):
    # 将YOLO标注转换为Albumentations格式
    bboxes = []
    labels = []
    for ann in annotations:
        label, x_center, y_center, width, height = map(float, ann.split())
        x_min = (x_center - width / 2) * image.shape[1]
        y_min = (y_center - height / 2) * image.shape[0]
        x_max = x_min + width * image.shape[1]
        y_max = y_min + height * image.shape[0]
        bboxes.append([x_min, y_min, x_max, y_max])
        labels.append(int(label))
    # 应用数据增强
    augmented = augmentations(image=image, bboxes=bboxes, category_ids=labels)
    # 将Albumentations格式的标注转换回YOLO格式
    new_annotations = []
    for bbox, label in zip(augmented["bboxes"], augmented["category_ids"]):
        x_min, y_min, x_max, y_max = bbox
        width = (x_max - x_min) / image.shape[1]
        height = (y_max - y_min) / image.shape[0]
        x_center = x_min / image.shape[1] + width / 2
        y_center = y_min / image.shape[0] + height / 2
        new_annotations.append(f"{label} {x_center} {y_center} {width} {height}")
    return augmented["image"], new_annotations
# 定义要应用的数据增强
augmentations = A.Compose([
    A.HorizontalFlip(p=0.5),
    A.Rotate(limit=30, p=0.5),
    A.RandomBrightnessContrast(p=0.5)
], bbox_params=A.BboxParams(format="pascal_voc", label_fields=["category_ids"]))
# 示例:对图像和标注应用数据增强
image = cv2.imread("path/to/image.jpg")
with open("path/to/annotations.txt", "r") as f:
    annotations = f.readlines()
augmented_image, augmented_annotations = augment_image(image, annotations, augmentations)
# 保存增强后的图像和标注
cv2.imwrite("path/to/augmented_image.jpg", augmented_image)
with open("path/to/augmented_annotations.txt", "w") as f:
    f.writelines(f"{ann}\n" for ann in augmented_annotations)

你可以根据需求调整数据增强策略。注意,增强后的图像和标注应保存到训练集目录,并将其路径添加到`train.txt`中。

至此,我们已完成垃圾分类数据集的准备工作。接下来,你可以使用这个数据集训练YOLOv5模型,并根据实际需求进行评估、优化和部署。

### 4. 训练YOLOv5模型

#### 4.1 安装依赖库

首先,确保你已经安装了Python 3.8或更高版本。然后,安装YOLOv5所需的依赖库。你可以使用以下命令安装:

pip install -r https://raw.githubusercontent.com/ultralytics/yolov5/master/requirements.txt

#### 4.2 克隆YOLOv5仓库

接下来,克隆YOLOv5的GitHub仓库:

git clone https://github.com/ultralytics/yolov5.git

#### 4.3 准备YOLOv5配置文件

我们需要为垃圾分类问题创建一个适当的配置文件。以下是一个示例配置文件`garbage.yaml`,你可以根据实际情况进行修改:

# 垃圾分类数据集配置
train: path/to/train.txt  # 训练集文件路径
val: path/to/val.txt      # 验证集文件路径
# 类别数和类别名称
nc: 6                      # 类别数
names: ['cardboard', 'glass', 'metal', 'paper', 'plastic', 'trash']  # 类别名称

将此配置文件保存在YOLOv5仓库的`data`文件夹中。

然后,根据你的数据集和计算资源选择一个合适的YOLOv5模型。YOLOv5有四个预训练模型:`yolov5s`, `yolov5m`, `yolov5l`和`yolov5x`。`yolov5s`模型最小,训练速度最快,但准确度略低;`yolov5x`模型最大,训练速度最慢,但准确度最高。你可以根据需求选择一个合适的模型。这里我们以`yolov5s`为例,你需要复制`yolov5s.yaml`文件,然后根据你的类别数修改`nc`参数:

# 部分内容省略
models:
  - name: yolov5s
    # 部分内容省略
    nc: 6  # 修改为你的类别数
    depth_multiple: 0.33  # model depth multiple
    width_multiple: 0.50  # layer channel multiple
    anchors:
      - [10,13, 16,30, 33,23]  # P3/8
      - [30,61, 62,45, 59,119]  # P4/16
      - [116,90, 156,198, 373,326]  # P5/32
    # 部分内容省略

将修改后的配置文件保存在YOLOv5仓库的`models`文件夹中,如`yolov5s_garbage.yaml`。

#### 4.4 训练模型

现在,我们可以开始训练过程。在YOLOv5仓库的根目录下,运行以下命令:

python train.py --img 640 --batch 16 --epochs 100 --data data/garbage.yaml --cfg models/yolov5s_garbage.yaml --weights yolov5s.pt --name garbage

这里的参数解释如下:

- `--img 640`:输入图像的大小。根据你的数据集和计算资源进行调整。

- `--batch 16`:每个批次的图像数量。根据你的计算资源进行调整。

- `--epochs 100`:训练的总轮数。根据你的需求进行调整。

- `--data data/garbage.yaml`:数据集配置文件路径。

- `--cfg models/yolov5s_garbage.yaml`:模型配置文件路径。

- `--weights yolov5s.pt`:预训练模型权重。你可以使用`yolov5s.pt`, `yolov5m.pt`, `yolov5l.pt`或`yolov5x.pt`。

- `--name garbage`:训练过程的名称。这将在`runs/train/`目录下创建一个名为`garbage`的文件夹,用于保存训练结果。

训练完成后,你会在`runs/train/garbage/weights`目录下找到训练好的模型权重文件,如`best.pt`。你可以使用这个权重文件进行目标检测和分类。

### 5. 评估与优化模型

#### 5.1 评估模型性能

在训练过程中,YOLOv5会自动在验证集上评估模型性能。最终的评估指标包括Precision, Recall, mAP等。你可以在训练日志中找到这些指标。

如果你想单独评估一个已经训练好的模型,可以使用以下命令:

python val.py --data data/garbage.yaml --weights runs/train/garbage/weights/best.pt --img 640

这里的参数解释如下:

- `--data data/garbage.yaml`:数据集配置文件路径。

- `--weights runs/train/garbage/weights/best.pt`:训练好的模型权重文件路径。

- `--img 640`:输入图像的大小。根据你的数据集和计算资源进行调整。

运行此命令后,你会看到模型在验证集上的评估结果。

#### 5.2 可视化训练过程

YOLOv5会在`runs/train/garbage`目录下生成训练过程的可视化结果,包括损失函数曲线、mAP曲线等。你可以使用任何图片查看器查看这些图像,或者使用Python代码来显示它们:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
# 显示训练过程中的损失曲线
loss_img = mpimg.imread('runs/train/garbage/results.png')
plt.imshow(loss_img)
plt.show()
# 显示训练过程中的mAP曲线
map_img = mpimg.imread('runs/train/garbage/results_map.png')
plt.imshow(map_img)
plt.show()

#### 5.3 模型优化

根据评估结果和训练过程的可视化,你可以尝试优化模型以获得更好的性能。以下是一些建议:

1. 增加训练数据:收集更多的训练图像,或者使用数据增强技术。

2. 调整模型结构:根据问题复杂性选择更大或更小的YOLOv5模型,如`yolov5m`, `yolov5l`或`yolov5x`。

3. 调整超参数:根据训练过程中的损失曲线,调整学习率、批次大小等超参数。

4. 使用模型融合和集成学习:训练多个模型,然后将它们的预测结果融合在一起,以提高性能。

不断尝试和调整,直到获得满意的模型性能。

### 6. 模型部署与应用

#### 6.1 使用训练好的模型进行目标检测

首先,我们使用训练好的模型进行目标检测。YOLOv5提供了一个`detect.py`脚本,可以方便地进行目标检测。运行以下命令:

python detect.py --source path/to/image_or_folder --weights runs/train/garbage/weights/best.pt --img 640 --conf 0.25

这里的参数解释如下:

- `--source path/to/image_or_folder`:要检测的图像文件或文件夹路径。

- `--weights runs/train/garbage/weights/best.pt`:训练好的模型权重文件路径。

- `--img 640`:输入图像的大小。根据你的数据集和计算资源进行调整。

- `--conf 0.25`:置信度阈值。只有置信度大于此阈值的目标检测结果才会被保留。

运行此命令后,检测结果将被保存在`runs/detect`目录下。

#### 6.2 创建一个简单的Web应用

接下来,我们将创建一个简单的Web应用,用于上传图像并显示目标检测结果。我们将使用Python的Flask框架。首先,安装Flask和依赖库:

pip install Flask flask-cors Pillow

然后,创建一个名为`app.py`的文件,并添加以下代码:

from flask import Flask, request, jsonify, send_from_directory
from flask_cors import CORS
from PIL import Image
import os
import uuid
app = Flask(__name__)
CORS(app)
UPLOAD_FOLDER = 'uploads'
if not os.path.exists(UPLOAD_FOLDER):
    os.makedirs(UPLOAD_FOLDER)
@app.route('/upload', methods=['POST'])
def upload_image():
    file = request.files['file']
    if file.filename == '':
        return jsonify({'error': 'No file provided'}), 400
    file_ext = os.path.splitext(file.filename)[1]
    file_name = f"{uuid.uuid4().hex}{file_ext}"
    file_path = os.path.join(UPLOAD_FOLDER, file_name)
    file.save(file_path)
    # TODO: 在这里添加YOLOv5目标检测代码
    return jsonify({'file_name': file_name})
@app.route('/results/<path:filename>')
def send_result_image(filename):
    return send_from_directory(UPLOAD_FOLDER, filename)
if __name__ == '__main__':
    app.run(debug=True)

这个简单的Web应用提供了两个API:

- `/upload`:用于上传图像。上传的图像将被保存在`uploads`文件夹中。

- `/results/<path:filename>`:用于获取目标检测结果图像。

#### 6.3 集成YOLOv5模型到Web应用中

现在,我们将YOLOv5模型集成到Web应用中。首先,导入YOLOv5所需的库:

import torch
from pathlib import Path
from PIL import ImageDraw, ImageFont

然后,加载训练好的模型权重,并创建一个目标检测函数:

MODEL_PATH = 'runs/train/garbage/weights/best.pt'
IMG_SIZE = 640
CONF_THRESHOLD = 0.25
model = torch.hub.load('ultralytics/yolov5', 'custom', path=MODEL_PATH, force_reload=True)
def detect_objects(image_path, output_path):
    img = Image.open(image_path)
    results = model(img, size=IMG_SIZE)
    results = results.pandas().xyxy[0]
    draw = ImageDraw.Draw(img)
    font = ImageFont.truetype("arial.ttf", 20)
    for _, row in results.iterrows():
        if row['confidence'] > CONF_THRESHOLD:
            x1, y1, x2, y2, conf, cls = row
            draw.rectangle([x1, y1, x2, y2], outline=(255, 0, 0), width=2)
            label = f"{model.names[int(cls)]} {conf:.2f}"
            text_size = draw.textsize(label, font)
            draw.rectangle([x1, y1, x1 + text_size[0], y1 - text_size[1]], fill=(255, 0, 0))
            draw.text((x1, y1 - text_size[1]), label, font=font, fill=(255, 255, 255))
    img.save(output_path)

现在,在`upload_image`函数中调用`detect_objects`函数,并返回检测结果图像的文件名:

@app.route('/upload', methods=['POST'])
def upload_image():
    file = request.files['file']
    if file.filename == '':
        return jsonify({'error': 'No file provided'}), 400
    file_ext = os.path.splitext(file.filename)[1]
    file_name = f"{uuid.uuid4().hex}{file_ext}"
    file_path = os.path.join(UPLOAD_FOLDER, file_name)
    file.save(file_path)
    # 添加YOLOv5目标检测代码
    result_file_name = f"{uuid.uuid4().hex}.jpg"
    result_file_path = os.path.join(UPLOAD_FOLDER, result_file_name)
    detect_objects(file_path, result_file_path)
    return jsonify({'file_name': result_file_name})

现在,你可以运行Web应用并上传图像:

python app.py

打开浏览器,访问`http://localhost:5000`,并上传图像进行目标检测。检测结果将被保存在`uploads`文件夹中,并可以通过`/results/<path:filename>`API获取。

这个简单的Web应用仅供参考。你可以根据自己的需求,将YOLOv5模型集成到不同的应用中。例如,你可以为移动设备创建一个目标检测应用,或将模型部署到云服务器上并提供API服务。

### 结论与展望

本文介绍了YOLOv5的原理、准备数据集、训练、评估、优化和部署的过程。YOLOv5是一个高性能、实时的目标检测算法,适用于许多实际应用场景。通过本文的介绍和示例,我们了解了如何使用YOLOv5训练自定义数据集并将模型部署到Web应用中。

在未来,我们希望看到YOLOv5在更多领域和场景中的应用,如无人驾驶、安防监控、医学影像分析等。此外,随着计算机视觉和深度学习技术的发展,我们期待有更多高性能、低成本的目标检测算法出现,为实际应用带来更大的价值。

综上所述,YOLOv5作为一个强大的目标检测算法,已经在许多领域取得了显著的成果。随着深度学习技术的不断发展,我们有理由相信YOLOv5及其他目标检测算法将在未来带来更多创新和突破。

目录
相关文章
|
7月前
|
存储 XML JSON
开集目标检测-标签提示目标检测大模型(吊打YOLO系列-自动化检测标注)
开集目标检测-标签提示目标检测大模型(吊打YOLO系列-自动化检测标注)
|
7月前
|
机器学习/深度学习 编解码 监控
手把手改进yolo训练自己的数据(坑洼路面识别)
手把手改进yolo训练自己的数据(坑洼路面识别)
|
7月前
|
机器学习/深度学习 开发工具 计算机视觉
YOLOv8 目标检测 | 自定义数据集
YOLOv8 目标检测 | 自定义数据集
|
机器学习/深度学习 编解码 固态存储
超轻目标检测 | 超越 NanoDet-Plus、YOLOv4-Tiny实时性、高精度都是你想要的!
超轻目标检测 | 超越 NanoDet-Plus、YOLOv4-Tiny实时性、高精度都是你想要的!
795 0
超轻目标检测 | 超越 NanoDet-Plus、YOLOv4-Tiny实时性、高精度都是你想要的!
|
2月前
|
机器学习/深度学习 编解码 监控
目标检测实战(六): 使用YOLOv8完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)
这篇文章详细介绍了如何使用YOLOv8进行目标检测任务,包括环境搭建、数据准备、模型训练、验证测试以及模型转换等完整流程。
3513 1
目标检测实战(六): 使用YOLOv8完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)
|
2月前
|
机器学习/深度学习 监控 计算机视觉
目标检测实战(八): 使用YOLOv7完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)
本文介绍了如何使用YOLOv7进行目标检测,包括环境搭建、数据集准备、模型训练、验证、测试以及常见错误的解决方法。YOLOv7以其高效性能和准确率在目标检测领域受到关注,适用于自动驾驶、安防监控等场景。文中提供了源码和论文链接,以及详细的步骤说明,适合深度学习实践者参考。
618 0
目标检测实战(八): 使用YOLOv7完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)
|
2月前
|
机器学习/深度学习 XML 并行计算
目标检测实战(七): 使用YOLOX完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)
这篇文章介绍了如何使用YOLOX完成图像目标检测任务的完整流程,包括数据准备、模型训练、验证和测试。
256 0
目标检测实战(七): 使用YOLOX完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)
|
编解码 算法 数据可视化
一种联合分类与检测训练的方法——YOLO9000
一种联合分类与检测训练的方法——YOLO9000
253 0
一种联合分类与检测训练的方法——YOLO9000
|
机器学习/深度学习 监控 算法
基于深度学习的跌倒检测系统(UI界面+YOLOv5+训练数据集)
基于深度学习的跌倒检测系统(UI界面+YOLOv5+训练数据集)
1532 0