简介:这份资源面向计算机视觉方向的研究人员、软件工程师以及园艺与植物研究从业者,提供一套基于YOLOv11的106种鲜花识别检测系统完整方案,帮助读者掌握从环境搭建、数据集准备到模型训练、导出与GUI落地的全流程技术细节。包内共1个docx文档,压缩包约40KB,以图文文档形式系统梳理项目介绍、项目特点、参考资料、未来改进方向与注意事项,并给出环境准备、数据集配置、模型训练、ONNX导出、性能评估、可视化指标及Tkinter界面创建等实施步骤,便于按目录快速定位关键模块。目前已有137人学习。读者可借此理解YOLOv11在真实场景中的配置方法、训练要点与评价指标,并参考完整代码整合思路与改进方向,为鲜花分类研究或工程落地提供可复用的实践参考。
1. 鲜花识别检测系统:从一张花店货架图说起
花店老板拍了一张货架照片,想自动分辨出玫瑰、向日葵、百合各在哪个位置,这件事听起来像是个玩具项目,但真动手做就会发现:花瓣重叠、颜色相近、光照多变、小目标密集,通用检测模型直接拿来用,mAP 能掉到让你怀疑人生。基于 YOLOv11 的鲜花识别检测系统,要解决的就是这类细粒度、多类别、密集小目标的检测问题——它不是简单跑个 demo,而是从数据集构建、类别定义、模型微调、推理后处理到部署验证的一整套流程。适合谁看?如果你手头有几百到几千张鲜花图片,想训一个能实际用的检测模型,或者你正在做农业分拣、花卉电商、植物科普类的视觉项目,这套路径可以直接复用。下面按「先立住原理、再动手复现、最后避坑」的顺序讲清楚。
2. YOLOv11 做鲜花检测的选型理由与数据准备
2.1 为什么是 YOLOv11 而不是 v8 或 RT-DETR
鲜花检测这个场景有几个硬约束:类别多(常见鲜花 10~30 类)、目标小(花苞、单朵花在整图里可能只占 30×30 像素)、背景杂(枝叶、包装纸、人手)。YOLOv11 相比 v8 的主要变化在 backbone 和 neck 的结构微调,C3k2 模块替换了部分 C2f,注意力机制集成更自然,在 COCO 上小目标 AP 有可感知的提升。RT-DETR 虽然端到端无 NMS,但训练显存占用高,小数据集上收敛慢,对鲜花这种需要快速迭代的场景不友好。我一般会先跑 YOLOv11n 或 YOLOv11s 做 baseline,确认数据 pipeline 没问题再换更大的模型。
提示:不要一上来就上 YOLOv11x,鲜花数据集通常几千张,大模型过拟合风险高,训练时间也翻倍。
2.2 鲜花数据集的采集与标注规范
数据来源常见三种:自己拍、爬公开花卉图库、用现有植物数据集筛选。自己拍要注意覆盖不同光照(顺光、逆光、室内暖光)、不同角度(俯拍、侧拍)、不同密度(单朵、花束、货架陈列)。标注用 LabelImg 或 CVAT,类别名建议用英文小写加下划线,比如rose、sunflower、lily、carnation,避免中文路径导致的编码问题。
标注框要贴紧花瓣外缘,不要框到花茎或包装纸。对于重叠花束,只标可见部分,遮挡超过 70% 的实例建议标ignore区域或直接不标,否则模型会学到模糊边界。每类至少 200 个实例,长尾类别可以少一些但不要低于 50。
2.3 把数据转成 YOLO 格式:目录结构与转换脚本
YOLO 要求每张图对应一个同名.txt文件,每行class_id x_center y_center width height,全部归一化到 0~1。目录结构如下:
flower_dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── data.yaml如果你手头是 VOC 的 XML,用下面脚本转换:
import xml.etree.ElementTree as ET import os def voc_to_yolo(xml_dir, out_dir, class_list): os.makedirs(out_dir, exist_ok=True) for xml_file in os.listdir(xml_dir): if not xml_file.endswith('.xml'): continue tree = ET.parse(os.path.join(xml_dir, xml_file)) root = tree.getroot() size = root.find('size') w = int(size.find('width').text) h = int(size.find('height').text) lines = [] for obj in root.iter('object'): cls = obj.find('name').text if cls not in class_list: continue cls_id = class_list.index(cls) bbox = obj.find('bndbox') x1 = float(bbox.find('xmin').text) y1 = float(bbox.find('ymin').text) x2 = float(bbox.find('xmax').text) y2 = float(bbox.find('ymax').text) # 归一化并转为中心点+宽高 xc = (x1 + x2) / 2.0 / w yc = (y1 + y2) / 2.0 / h bw = (x2 - x1) / w bh = (y2 - y1) / h lines.append(f"{cls_id} {xc:.6f} {yc:.6f} {bw:.6f} {bh:.6f}") with open(os.path.join(out_dir, xml_file.replace('.xml', '.txt')), 'w') as f: f.write('\n'.join(lines))逻辑说明:先读图片宽高做归一化,再把 VOC 的左上右下坐标转成 YOLO 的中心点加宽高。参数上class_list必须和data.yaml里的names顺序完全一致,否则类别会错位。转换完随机抽 10 张用labelImg或脚本可视化检查,确认框没偏移。
2.4 data.yaml 的写法与路径坑
path: /home/user/flower_dataset train: images/train val: images/val test: images/test nc: 12 names: ['rose', 'sunflower', 'lily', 'carnation', 'tulip', 'orchid', 'daisy', 'peony', 'chrysanthemum', 'hydrangea', 'lavender', 'other']path用绝对路径最稳,train等相对路径基于path解析。常见翻车点:Windows 下反斜杠转义、中文路径、names里用了中文逗号。如果训练时报Dataset not found,先检查path拼出来的完整路径是否存在。
3. 训练 YOLOv11 鲜花检测模型:环境、参数与断点续训
3.1 环境配置:ultralytics 安装与 CUDA 对齐
conda create -n flower python=3.10 -y conda activate flower pip install ultralytics==8.3.0 pip install torch==2.4.0 torchvision==0.19.0 --index-url https://download.pytorch.org/whl/cu121装完跑一句验证:
import torch print(torch.cuda.is_available(), torch.cuda.get_device_name(0))必须输出True和你的显卡型号。如果False,检查驱动版本和 CUDA 版本是否匹配。ultralytics 版本不要追最新,选一个稳定版,避免 API 变动导致脚本报错。
3.2 训练命令与关键参数怎么设
yolo detect train \ data=/home/user/flower_dataset/data.yaml \ model=yolo11s.pt \ epochs=150 \ imgsz=640 \ batch=16 \ lr0=0.01 \ lrf=0.01 \ patience=30 \ device=0 \ project=flower_runs \ name=exp1参数逐个说:imgsz=640是默认,如果鲜花目标普遍小于 32×32,可以提到 960 或 1280,但显存翻倍;batch=16在 8G 显存上跑 yolo11s 比较稳,爆显存就降到 8;lr0=0.01是初始学习率,小数据集可以降到 0.005;patience=30表示 30 轮没提升就早停,避免浪费时间;lrf=0.01是最终学习率因子,控制余弦退火终点。
注意:
model=yolo11s.pt会自动下载预训练权重,如果网络不通,提前手动下载放到当前目录。
3.3 训练过程看什么:loss 曲线与 mAP 解读
训练日志里重点看三列:box_loss、cls_loss、mAP50。box_loss下降但cls_loss震荡,通常是类别不平衡或标注噪声;mAP50在 50 轮后还在涨,说明还没收敛,可以加 epoch;如果val/box_loss开始上升而train/box_loss还在降,就是过拟合,加数据增强或减模型容量。
YOLOv11 默认开启 mosaic、mixup、copy-paste 等增强。鲜花场景下 mosaic 有助于小目标,但 mixup 可能把不同花混在一起导致语义混乱,可以关掉:
mixup=0.0 copy_paste=0.13.4 断点续训与多卡训练
训练中断后,用resume继续:
yolo detect train resume model=flower_runs/exp1/weights/last.pt多卡用device=0,1,但注意 batch 要相应翻倍,学习率也可以线性放大。如果只有一张卡,不要开amp=False,混合精度能省显存且几乎不掉点。
4. 推理、后处理与鲜花检测的避坑清单
4.1 推理命令与保存结果
yolo detect predict \ model=flower_runs/exp1/weights/best.pt \ source=/home/user/test_images \ conf=0.25 \ iou=0.45 \ save=True \ save_txt=True \ save_conf=Trueconf=0.25是置信度阈值,鲜花场景如果漏检多就降到 0.15,误检多就升到 0.4;iou=0.45是 NMS 的 IoU 阈值,花束密集时调到 0.5~0.6 保留更多重叠框;save_txt=True会输出每张图的检测结果 txt,方便后续统计。
4.2 小目标优化:切片推理与 imgsz 调整
如果鲜花在图中占比很小,直接推理会漏。常见做法是切片推理(SAHI),把大图切成 640×640 的小块分别检测再合并。ultralytics 本身不直接支持,但可以用 SAHI 库包一层:
from sahi import AutoDetectionModel from sahi.predict import get_sliced_prediction detection_model = AutoDetectionModel.from_pretrained( model_type='yolov11', model_path='flower_runs/exp1/weights/best.pt', confidence_threshold=0.25, device='cuda:0' ) result = get_sliced_prediction( 'test.jpg', detection_model, slice_height=640, slice_width=640, overlap_height_ratio=0.2, overlap_width_ratio=0.2 )overlap_ratio=0.2是切片重叠比例,太小会切断裂目标,太大则重复框多。切片推理速度慢 2~3 倍,但小目标召回能提升 10~20 个点。
4.3 避坑清单:鲜花检测最常见的 5 个翻车点
现象一:训练 mAP 很高,实际推理一塌糊涂。原因:验证集和训练集同分布,但实际场景光照、背景差异大。解决:留一个独立测试集,模拟真实拍摄条件,不要用训练集里的图。
现象二:同类花不同颜色被分成两个类。原因:标注时把颜色当类别,比如red_rose和white_rose。解决:类别按物种分,颜色用属性或后处理区分,否则类别数爆炸且样本不足。
现象三:密集花束只检测出最外面几朵。原因:NMS 把重叠框滤掉了。解决:调高iou阈值到 0.6,或改用 soft-NMS,ultralytics 里可以通过自定义 NMS 实现。
现象四:训练 loss 不降,mAP 一直是 0。原因:data.yaml里nc和names数量不一致,或标签文件路径不对。解决:用yolo detect train前先跑yolo detect val检查数据加载。
现象五:推理结果框偏移或缩放错误。原因:测试图片尺寸和训练时imgsz差异大,letterbox 填充计算有误。解决:推理时显式指定imgsz=640,不要依赖自动推断。
5. 进阶技巧:用验证集反推标注质量与模型边界
训练完不是终点,真正值钱的是从验证结果里读出标注问题。我习惯跑一遍yolo detect val并导出混淆矩阵和 PR 曲线:
yolo detect val \ model=flower_runs/exp1/weights/best.pt \ data=/home/user/flower_dataset/data.yaml \ conf=0.001 \ iou=0.6 \ plots=Trueconf=0.001是为了画全 PR 曲线,plots=True会在runs/val/下生成confusion_matrix.png、PR_curve.png、F1_curve.png。重点看混淆矩阵里哪两类互相误判最多,比如rose和carnation如果大量互错,说明标注时边界定义不清,需要回去统一标准。
另一个技巧是用save_txt导出的置信度分布判断阈值。把某类所有检测框的 conf 值画直方图,如果双峰分布,说明存在一批低质量标注或难样本,可以考虑把低置信度区间对应的图挑出来重新标。
| 验证指标 | 健康范围 | 异常时先查 |
|---|---|---|
| mAP50 | >0.85 | 标注一致性 |
| mAP50-95 | >0.6 | 框的紧密度 |
| precision | >0.8 | 误检来源 |
| recall | >0.8 | 漏检类别 |
| F1 | >0.8 | 阈值是否最优 |
最后说个血泪经验:鲜花检测模型上线后,每隔两个月要重新抽一批新图做验证,因为花店进货品种会变,季节更替也会导致外观差异。我一般会保留一个hard_examples文件夹,把线上误检漏检的图丢进去,攒够 200 张就微调一次,学习率降到 0.001,只训 30 轮。这样模型不会退化,也不用从头再来。希望帮到你。
本文还有配套的精品资源,点击获取