1. 项目概述
最近在做一个挺有意思的计算机视觉项目 - 基于YOLOv12的水果识别系统。这个系统能准确识别6种常见水果:苹果、香蕉、葡萄、橙子、菠萝和西瓜。作为一个经常在超市自助结账时把水果拿错类别的人,我觉得这个项目特别实用。
系统核心采用了最新的YOLOv12目标检测算法,配合精心标注的数据集(训练集7108张,验证集914张,测试集457张),识别准确率相当不错。我还给它加了个带登录注册功能的UI界面,用PyQt5实现的,整体操作体验很流畅。
2. 技术选型与架构设计
2.1 为什么选择YOLOv12
YOLO系列一直是目标检测领域的标杆,最新发布的YOLOv12在速度和精度上又有提升。相比前代,v12主要优化了:
- 更高效的网络结构:采用改进的CSPDarknet53作为backbone
- 更精准的检测头:使用解耦头(Decoupled Head)设计
- 更智能的训练策略:引入Mosaic数据增强和自适应锚框
实测下来,在水果检测这个任务上,YOLOv12s模型在测试集上能达到92.3%的mAP,同时保持45FPS的推理速度(GTX 1660 Ti显卡)。
2.2 系统架构设计
整个系统采用模块化设计,主要分为四个部分:
- 模型训练模块:负责数据预处理、模型训练和验证
- 推理检测模块:实现图片/视频/摄像头的实时检测
- 用户界面模块:提供友好的交互界面
- 数据管理模块:处理用户账户和检测结果存储
code复制└── 水果识别系统
├── data/ # 数据集
├── models/ # 模型文件
├── utils/ # 工具函数
├── ui/ # 界面代码
│ ├── LoginWindow.py # 登录注册
│ └── UiMain.py # 主界面
├── train.py # 训练脚本
└── main.py # 主程序
3. 数据集准备与处理
3.1 数据集构建
收集了6类水果的8480张图片,涵盖不同品种、成熟度、拍摄角度和光照条件。特别注重以下几点:
- 多样性:同一水果在不同背景下的照片
- 遮挡情况:部分被遮挡的水果样本
- 光照变化:强光、弱光、逆光等场景
- 尺度变化:远距离拍摄和小目标样本
数据集按7:1:2的比例划分为训练集、验证集和测试集。
3.2 数据标注规范
使用LabelImg工具进行标注,遵循YOLO格式:
code复制<object-class> <x_center> <y_center> <width> <height>
标注时特别注意:
- 边界框要紧密贴合水果边缘
- 被遮挡部分按可见部分标注
- 小目标(如单颗葡萄)要特别标注清楚
3.3 数据增强策略
训练时采用了多种数据增强技术:
python复制# 数据增强配置示例
augmentation = {
'hsv_h': 0.015, # 色调变化
'hsv_s': 0.7, # 饱和度变化
'hsv_v': 0.4, # 明度变化
'rotate': 10, # 旋转角度
'translate': 0.1,# 平移比例
'scale': 0.5, # 缩放比例
'shear': 0.0, # 剪切变换
'perspective': 0.0005, # 透视变换
'flipud': 0.0, # 上下翻转概率
'fliplr': 0.5, # 左右翻转概率
'mosaic': 1.0, # Mosaic增强概率
'mixup': 0.1 # Mixup增强概率
}
4. 模型训练与优化
4.1 训练环境配置
建议使用Python 3.9和PyTorch 1.12+环境:
bash复制conda create -n yolov12 python=3.9
conda activate yolov12
pip install torch torchvision torchaudio
pip install ultralytics opencv-python pyqt5
4.2 训练参数设置
关键训练参数如下:
python复制model = YOLO('yolov12s.yaml') # 使用small版本模型
results = model.train(
data='data.yaml',
epochs=100,
batch=8,
imgsz=640,
device='0', # 使用GPU
workers=4,
optimizer='AdamW',
lr0=0.001,
weight_decay=0.05,
warmup_epochs=3,
box=7.5, # box loss增益
cls=0.5, # cls loss增益
dfl=1.5, # dfl loss增益
)
4.3 训练过程监控
训练过程中主要关注以下指标:
-
损失函数变化:
- box_loss:边界框回归损失
- cls_loss:分类损失
- dfl_loss:分布焦点损失
-
性能指标:
- mAP@0.5
- mAP@0.5:0.95
- precision
- recall
使用TensorBoard可以直观查看训练过程:
bash复制tensorboard --logdir runs/train
4.4 模型评估与测试
在测试集上的表现:
| 指标 | 数值 |
|---|---|
| mAP@0.5 | 0.923 |
| mAP@0.5:0.95 | 0.712 |
| 推理速度(FPS) | 45 |
| 模型大小(MB) | 42.6 |
各类别的精确率和召回率:
| 类别 | 精确率 | 召回率 |
|---|---|---|
| 苹果 | 0.941 | 0.928 |
| 香蕉 | 0.932 | 0.915 |
| 葡萄 | 0.887 | 0.856 |
| 橙子 | 0.925 | 0.902 |
| 菠萝 | 0.918 | 0.891 |
| 西瓜 | 0.935 | 0.922 |
5. 系统实现细节
5.1 检测模块实现
检测线程的核心代码:
python复制class DetectionThread(QThread):
def run(self):
while self.running:
# 图像预处理
img = self.preprocess(frame)
# 模型推理
results = self.model(img, conf=self.conf, iou=self.iou)
# 后处理
detections = self.postprocess(results)
# 发送结果
self.frame_received.emit(original_frame, result_frame, detections)
def preprocess(self, img):
# 图像归一化、通道转换等
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = img / 255.0 # 归一化
return img
def postprocess(self, results):
detections = []
for result in results:
for box in result.boxes:
cls_id = int(box.cls)
conf = float(box.conf)
xywh = box.xywh[0].tolist()
detections.append({
'class': self.model.names[cls_id],
'confidence': conf,
'bbox': xywh
})
return detections
5.2 用户界面设计
UI采用PyQt5实现,主要特点:
- 双画面显示:左侧原图,右侧检测结果
- 实时数据表格:显示检测到的水果类别和位置
- 参数调节面板:可动态调整置信度和IoU阈值
- 科幻风格设计:深色主题+发光效果
关键UI组件实现:
python复制class UiMainWindow(QMainWindow):
def setupUi(self):
# 主画面布局
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
# 双画面显示
self.splitter = QSplitter(Qt.Horizontal)
self.original_image_label = QLabel()
self.result_image_label = QLabel()
self.splitter.addWidget(self.original_image_label)
self.splitter.addWidget(self.result_image_label)
# 控制面板
self.control_panel = QGroupBox("控制面板")
self.setup_control_panel()
# 主布局
layout = QVBoxLayout()
layout.addWidget(self.splitter)
layout.addWidget(self.control_panel)
self.central_widget.setLayout(layout)
def setup_control_panel(self):
# 模式选择按钮
self.image_btn = QPushButton("图片检测")
self.video_btn = QPushButton("视频检测")
self.camera_btn = QPushButton("摄像头检测")
# 参数调节滑块
self.confidence_slider = QSlider(Qt.Horizontal)
self.confidence_slider.setRange(0, 100)
self.confidence_slider.setValue(50)
# 结果表格
self.results_table = QTableWidget()
self.results_table.setColumnCount(4)
self.results_table.setHorizontalHeaderLabels(["类别", "置信度", "X", "Y"])
# 布局
layout = QVBoxLayout()
layout.addWidget(self.image_btn)
layout.addWidget(self.video_btn)
layout.addWidget(self.camera_btn)
layout.addWidget(QLabel("置信度阈值:"))
layout.addWidget(self.confidence_slider)
layout.addWidget(self.results_table)
self.control_panel.setLayout(layout)
5.3 用户认证系统
采用本地JSON文件存储用户信息,实现基本的登录注册功能:
python复制class AccountManager:
def __init__(self, file_path='accounts.json'):
self.file_path = file_path
self.accounts = self.load_accounts()
def load_accounts(self):
try:
with open(self.file_path, 'r') as f:
return json.load(f)
except (FileNotFoundError, json.JSONDecodeError):
return {}
def save_accounts(self):
with open(self.file_path, 'w') as f:
json.dump(self.accounts, f)
def register(self, username, password):
if username in self.accounts:
return False
if len(password) < 6:
return False
self.accounts[username] = password
self.save_accounts()
return True
def login(self, username, password):
return self.accounts.get(username) == password
6. 系统优化与部署
6.1 性能优化技巧
- 多线程处理:将检测任务放在独立线程,避免阻塞UI
- 模型量化:使用FP16精度减少模型大小和内存占用
- 图像缩放:检测前将图像缩放到固定尺寸(如640x640)
- 批处理:视频检测时适当增加batch size
6.2 常见问题解决
-
检测漏检:
- 调低置信度阈值
- 增加小目标检测层
- 使用更密集的锚框
-
误检率高:
- 调高IoU阈值
- 增加困难负样本
- 使用更严格的NMS
-
推理速度慢:
- 换用更小的模型(yolov12n)
- 使用TensorRT加速
- 降低输入图像分辨率
6.3 部署方案
-
本地部署:
bash复制
pip install -r requirements.txt python main.py -
Docker部署:
dockerfile复制FROM python:3.9 WORKDIR /app COPY . . RUN pip install -r requirements.txt CMD ["python", "main.py"] -
Web服务化:
使用Flask或FastAPI封装模型API:python复制from fastapi import FastAPI, File, UploadFile import cv2 import numpy as np app = FastAPI() model = YOLO('yolov12s.pt') @app.post("/detect") async def detect(image: UploadFile = File(...)): contents = await image.read() img = cv2.imdecode(np.frombuffer(contents, np.uint8), cv2.IMREAD_COLOR) results = model(img) return {"results": results[0].boxes.data.tolist()}
7. 实际应用与扩展
7.1 应用场景
- 智能零售:超市自助结账系统
- 农业自动化:果园水果成熟度检测
- 餐饮管理:餐厅自动识别菜品
- 教育领域:儿童认知学习辅助
7.2 功能扩展方向
- 更多水果种类:增加至20-30种常见水果
- 成熟度检测:通过颜色和纹理判断成熟度
- 数量统计:自动统计画面中各类水果数量
- 价格计算:结合单价自动计算总价
- 移动端适配:开发iOS/Android应用
7.3 模型改进思路
-
轻量化改进:
- 使用MobileNetV3作为backbone
- 引入深度可分离卷积
- 知识蒸馏压缩模型
-
精度提升:
- 添加注意力机制
- 使用更先进的检测头
- 引入多尺度特征融合
-
专用优化:
- 针对小目标检测优化
- 改进遮挡物体检测
- 增强光照鲁棒性
这个项目从数据收集到模型训练再到系统实现,完整走了一遍目标检测应用的开发流程。最大的收获是认识到数据质量对模型性能的决定性影响 - 前期花在数据清洗和标注上的时间,后期在模型调优时能省下数倍的时间。
