📖 前言
在现代农业生产中,水果品质检测一直是一个重要环节。传统的人工检测方式不仅效率低下,而且容易受到主观因素影响,难以保证检测标准的一致性。今天,我们将分享一个基于最新YOLO11模型的苹果瑕疵检测系统,展示AI技术如何为农业智能化升级提供强有力的支撑。
🎯 项目概述
本项目采用深度学习目标检测技术,构建了一套完整的苹果瑕疵检测系统。系统能够自动识别苹果表面的各种瑕疵,包括病斑、虫眼、机械损伤等,为农产品质量控制提供了智能化解决方案。
🔧 技术栈
- 深度学习框架: PyTorch
- 检测模型: YOLO11n (轻量级版本)
- 数据处理: OpenCV, PIL
- 可视化: Matplotlib, Seaborn
- 硬件加速: NVIDIA GPU (RTX 4060)
📊 数据集构建
数据规模
- 训练集: 275张苹果图像
- 验证集: 78张苹果图像
- 标注格式: VOC XML格式,包含瑕疵位置和类别信息

数据预处理
我们开发了专门的数据预处理脚本,实现了:
- VOC格式到YOLO格式的自动转换
- 智能数据集划分(训练/验证/测试)
- 数据增强策略优化
python
# 数据增强配置 - 适合苹果瑕疵检测图像
hsv_h: 0.015 # 色调变化
hsv_s: 0.7 # 饱和度变化
hsv_v: 0.4 # 亮度变化
degrees: 10.0 # 旋转角度
translate: 0.1 # 平移比例
scale: 0.5 # 缩放比例
fliplr: 0.5 # 水平翻转
mosaic: 1.0 # 马赛克增强
mixup: 0.1 # 混合增强
python
class VOCToYOLOConverter:
"""VOC格式到YOLO格式转换器"""
def __init__(self, voc_root: str, yolo_root: str):
self.voc_root = Path(voc_root)
self.yolo_root = Path(yolo_root)
self.class_names = ['defect'] # 苹果瑕疵类别
self.class2id = {name: i for i, name in enumerate(self.class_names)}
def create_directories(self):
"""创建YOLO格式目录结构"""
for split in ['train', 'val', 'test']:
(self.yolo_root / 'images' / split).mkdir(parents=True, exist_ok=True)
(self.yolo_root / 'labels' / split).mkdir(parents=True, exist_ok=True)
def parse_xml(self, xml_path: str) -> Tuple[int, int, List[dict]]:
"""解析VOC XML文件"""
tree = ET.parse(xml_path)
root = tree.getroot()
# 获取图像尺寸
size = root.find('size')
width = int(size.find('width').text)
height = int(size.find('height').text)
# 解析目标框
objects = []
for obj in root.findall('object'):
name = obj.find('name').text
if name not in self.class2id:
continue
cls_id = self.class2id[name]
bndbox = obj.find('bndbox')
xmin = float(bndbox.find('xmin').text)
ymin = float(bndbox.find('ymin').text)
xmax = float(bndbox.find('xmax').text)
ymax = float(bndbox.find('ymax').text)
# 转换为YOLO格式 (归一化的中心点坐标和宽高)
x_center = (xmin + xmax) / 2.0 / width
y_center = (ymin + ymax) / 2.0 / height
bbox_width = (xmax - xmin) / width
bbox_height = (ymax - ymin) / height
objects.append({
'class_id': cls_id,
'x_center': x_center,
'y_center': y_center,
'width': bbox_width,
'height': bbox_height
})
return width, height, objects
🚀 模型训练过程
训练配置
- 模型: YOLO11n (轻量级,适合实时检测)
- 训练轮数: 100 epochs
- 批次大小: 16
- 图像尺寸: 640×640
- 优化器: AdamW (自动选择)
- 学习率: 0.002 (自适应调整)
硬件环境
- GPU: NVIDIA GeForce RTX 4060 Laptop GPU (8GB显存)
- 训练时间: 约5小时完成100轮训练
部分训练代码
python
"""苹果瑕疵检测快速训练主函数"""
print("🍎 苹果瑕疵检测 - 快速GPU训练 (本地模型)")
print("=" * 60)
# 检查GPU
if torch.cuda.is_available():
device_name = torch.cuda.get_device_name(0)
print(f"✅ 使用GPU: {device_name}")
device = 'cuda'
else:
print("❌ GPU不可用,使用CPU")
device = 'cpu'
# 检查本地模型
model_path = "models/yolo11n.pt" # 基础检测模型
# model_path = "models/yolo11n-seg.pt" # 如需分割模型可使用此行
if not Path(model_path).exists():
print(f"❌ 本地模型文件不存在: {model_path}")
return
print(f"✅ 本地模型: {model_path}")
# 检查数据集配置文件
data_yaml_path = 'data/data.yaml'
if not Path(data_yaml_path).exists():
print(f"❌ 数据集配置文件不存在: {data_yaml_path}")
print("💡 请先运行数据预处理脚本: python prepare_dataset.py")
return
# 验证数据集目录结构
data_dir = Path('data')
required_dirs = ['images/train', 'images/val', 'labels/train', 'labels/val']
missing_dirs = []
for dir_path in required_dirs:
full_path = data_dir / dir_path
if not full_path.exists():
missing_dirs.append(str(full_path))
if missing_dirs:
print(f"❌ 缺少必要的数据集目录:")
for missing_dir in missing_dirs:
print(f" - {missing_dir}")
print("💡 请先运行数据预处理脚本: python prepare_dataset.py")
return
print(f"✅ 数据集配置: {data_yaml_path}")
# 检查数据集是否为空
train_images = list((data_dir / 'images/train').glob('*'))
val_images = list((data_dir / 'images/val').glob('*'))
if not train_images:
print("❌ 训练集为空,请检查数据预处理")
return
if not val_images:
print("⚠️ 验证集为空,将使用训练集进行验证")
print(f"📊 数据集统计: 训练集 {len(train_images)} 张, 验证集 {len(val_images)} 张")
# 创建保存结果的目录
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
save_dir = Path(f"apple_defect_results/yolo11n_defect_{timestamp}")
save_dir.mkdir(parents=True, exist_ok=True)
try:
print(f"\n📂 加载本地YOLO11模型: {model_path}")
# 加载本地预训练模型,禁用自动下载
model = YOLO(model_path, task='detect')
print("✅ YOLO11模型加载成功")
print(f"\n🚀 开始训练...")
print("=" * 60)
# 开始训练 - 针对显卡性能优化参数
results = model.train(
data=data_yaml_path, # 数据集配置
epochs=100, # 训练轮数
imgsz=640, # 输入图像尺寸
batch=16, # 批次大小(根据显卡调整)
device=device, # 使用GPU
workers=4, # 数据加载线程
cache=True, # 缓存数据到内存
amp=False, # 禁用自动混合精度(避免下载模型)
project='apple_defect_results', # 项目文件夹
name=f'yolo11n_defect_{timestamp}', # 实验名称
exist_ok=True, # 覆盖已存在的文件夹
patience=20, # 早停耐心值
save=True, # 保存最佳模型
verbose=True, # 详细输出
val=True, # 训练时验证
plots=True, # 生成训练图表
# 学习率设置
lr0=0.01, # 初始学习率
lrf=0.01, # 最终学习率比例
momentum=0.937, # SGD动量
weight_decay=0.0005, # 权重衰减
warmup_epochs=3, # 预热轮数
# 数据增强 - 适合苹果瑕疵检测图像
hsv_h=0.015, # 色调增强
hsv_s=0.7, # 饱和度增强
hsv_v=0.4, # 明度增强
degrees=10.0, # 旋转角度
translate=0.1, # 平移
scale=0.5, # 缩放
shear=0.0, # 剪切
perspective=0.0, # 透视变换
flipud=0.0, # 上下翻转
fliplr=0.5, # 左右翻转
mosaic=1.0, # 马赛克增强
mixup=0.1, # 混合增强
)
📈 训练结果分析
关键性能指标
经过53轮训练后,模型达到最佳性能:
指标 | 数值 | 说明 |
---|---|---|
精确率 (Precision) | 62.9% | 检测到的瑕疵中真正瑕疵的比例 |
召回率 (Recall) | 57.6% | 实际瑕疵中被成功检测的比例 |
mAP@0.5 | 61.3% | IoU阈值0.5下的平均精度 |
mAP@0.5:0.95 | 30.4% | IoU阈值0.5-0.95的平均精度 |
训练过程可视化

从训练曲线可以看出:
- 损失函数稳步下降: 训练损失和验证损失都呈现良好的收敛趋势
- 无过拟合现象: 验证损失与训练损失保持同步下降
- 性能持续提升: mAP指标在训练过程中稳步上升
混淆矩阵分析

混淆矩阵显示了模型在瑕疵检测任务上的表现,帮助我们理解模型的优势和改进空间。
精确率-召回率曲线

PR曲线展示了不同置信度阈值下模型的性能表现,为实际部署时的参数调优提供参考。
🔍 检测效果展示
训练样本可视化

验证结果对比

真实标签
模型预测结果
通过对比可以看出,模型能够较好地识别苹果表面的瑕疵区域,检测框的位置和大小都比较准确。
💡 技术亮点
1. 轻量化设计
- 采用YOLO11n模型,参数量仅259万
- 推理速度快,适合实时检测应用
- 模型文件小,便于部署到边缘设备
2. 智能数据增强
- 针对苹果图像特点定制增强策略
- 提高模型对光照、角度变化的鲁棒性
- 有效扩充训练数据,提升泛化能力
3. 端到端训练
- 自动化的数据预处理流程
- 完整的训练监控和可视化
- 模型性能自动评估和保存
4. 工程化实现
- 模块化代码设计,易于维护和扩展
- 完善的配置管理系统
- 详细的日志记录和错误处理
🌟 应用前景
农业生产应用
- 果园自动化分拣: 集成到分拣生产线,实现自动化质量控制
- 移动检测设备: 开发便携式检测设备,用于田间快速检测
- 质量追溯系统: 建立从生产到销售的全链条质量追溯
技术扩展方向
- 多品种水果检测: 扩展到橙子、梨子等其他水果
- 瑕疵类型细分: 识别更多种类的瑕疵,如病害类型分类
- 成熟度检测: 结合颜色特征判断水果成熟度
🔧 部署与使用
环境要求
bash
# 安装依赖
pip install torch torchvision ultralytics
pip install opencv-python pillow numpy pandas
pip install matplotlib seaborn tqdm
快速开始
python
# 训练模型
python train_apple_defect.py
# 测试模型
python test_apple_defect_model.py
模型推理
python
from ultralytics import YOLO
# 加载训练好的模型
model = YOLO('apple_defect_results/yolo11n_defect_*/weights/best.pt')
# 对新图像进行检测
results = model('path/to/apple_image.jpg')
results[0].show() # 显示检测结果
📝 总结与展望
本项目成功构建了一套基于YOLO11的苹果瑕疵检测系统,在有限的数据集上取得了良好的检测效果。通过深度学习技术,我们实现了:
✅ 高效的瑕疵检测 : mAP@0.5达到61.3%,满足实际应用需求
✅ 轻量化模型设计 : 适合边缘设备部署
✅ 完整的工程化方案: 从数据处理到模型部署的全流程解决方案