资讯详情

资讯详情

YOLOv5-ready橙子成熟度数据集:开箱即用的农业视觉交付包

简介本资源是专为农业智能化场景设计的橘子成熟度目标检测数据集面向YOLOv5初学者与农业AI开发者解决柑橘采摘机器人、自动分级系统中成熟度判别所需的小样本、高适配性训练数据难题。压缩包共177个文件含171张640×640分辨率JPG图像覆盖田间多角度、多光照下的成熟/未成熟橘子、2个核心YOLO格式标签说明文件、1个开箱即用的show.py可视化脚本支持随机加载并保存带框效果图另有.gitignore等工程配置文件整体仅13.29MB解压后即符合标准YOLOv5目录结构images/与labels/分离省去格式转换与路径调试环节。目前已有40人学习下载附带的可视化脚本与清晰二分类标注‘成熟’/‘未成熟’可快速验证数据质量配合2313张训练图与224张验证图的合理划分显著降低模型训练门槛助力农业视觉项目从数据准备阶段高效启动。1. 为什么橙子成熟度检测总在田间翻车YOLOv5-ready 橙子成熟度数据集2类标注熟/生、带划分与可视化脚本专治模型落地前最后一公里你训练完一个YOLOv5模型指标看着漂亮mAP0.5 达到89.3%PR曲线光滑得像PPT里的示意图。可一拿到果园实拍视频框全飘在果柄上、把青皮果当未熟、把套袋后反光的熟果判成背景——不是模型不行是它根本没见过真实场景下的“熟”和“生”长什么样。这个标题指向的不是一个普通数据集而是一套开箱即用的农业视觉交付包它不只提供图片和标签而是直接按YOLOv5训练流水线预对齐——文件结构符合/images/train/labels/train规范类别名硬编码为ripe/unripe非class_0/class_1坐标已归一化甚至附带能立刻跑通的visualize_labels.py验证标注质量。它解决的不是“有没有数据”而是“有没有能塞进train.py里不报错、不漏标、不越界的生产级数据”。适合正在做柑橘采收机器人、分选线AI质检、或农业AI课程设计的开发者——你不需要再花三天写路径遍历脚本、调试labelImg导出格式、手动切分验证集今天下午就能在本地GPU上跑起第一个epoch。2. 数据集结构解析与YOLOv5训练链路对齐逻辑这个数据集的设计本质是把YOLOv5训练流程中最容易卡住新手的5个隐性环节全部提前固化在目录结构和文件规范里。我们不讲“标准格式”只说它为什么这样组织、不这样组织会触发什么报错。2.1 目录树即训练协议为什么必须严格遵循/images/labels双轨制YOLOv5官方训练脚本train.py默认读取--data参数指向的.yaml配置文件该文件内train:和val:字段必须指定图像路径列表如./images/train/而非图像文件本身。但关键在于YOLOv5在加载每张图时会自动拼接同名.txt标签路径——即读取./images/train/orange_001.jpg时会去找./labels/train/orange_001.txt。如果数据集把图片和标签混放或标签放在./annotations/下训练会直接报FileNotFoundError: [Errno 2] No such file or directory: ./labels/train/orange_001.txt且错误堆栈不会明确提示是路径问题新手常在此处耗掉半天。该数据集的目录结构强制解耦orange_maturity_yolov5/ ├── images/ │ ├── train/ # 所有训练图jpg/png │ └── val/ # 所有验证图 ├── labels/ │ ├── train/ # 与images/train/同名的txt每行cls x_center y_center w h │ └── val/ # 与images/val/同名的txt ├── dataset.yaml # YOLOv5识别的配置文件含nc, names, train/val路径 └── visualize_labels.py # 独立验证脚本提示dataset.yaml中train:和val:字段值必须是相对路径如../images/train且必须以/结尾。若写成./images/train/末尾多斜杠或images/train缺./部分YOLOv5版本会静默忽略路径导致训练集为空。2.2 标签文件内容规范归一化坐标的3个生死线YOLOv5要求所有.txt标签文件中每行格式为class_id x_center y_center width height其中x_center,y_center,width,height必须是相对于图像宽高的归一化浮点数0~1之间。这是最易出错的环节——很多标注工具导出的是像素坐标直接喂给YOLOv5会导致bbox全部缩成左上角一个点。该数据集的标签文件经严格校验例如一张1920×1080的图中一个熟橙子的标注为0 0.4231 0.5678 0.1892 0.2045含义类别0ripe中心点横坐标0.4231×1920≈812像素纵坐标0.5678×1080≈613像素宽0.1892×1920≈363像素高0.2045×1080≈221像素。验证方法用以下Python脚本快速检查任意标签文件是否越界任何值0或1即非法# check_label_norm.py import os def validate_label_file(txt_path): with open(txt_path, r) as f: lines f.readlines() for i, line in enumerate(lines): parts line.strip().split() if len(parts) ! 5: print(fLine {i1}: Invalid format (expected 5 values, got {len(parts)})) continue try: cls_id int(parts[0]) coords [float(x) for x in parts[1:]] except ValueError: print(fLine {i1}: Non-numeric value detected) continue if not all(0.0 c 1.0 for c in coords): print(fLine {i1}: Coordinate out of [0,1] range: {coords}) return False return True # 验证整个val标签集 label_dir ./labels/val for txt_file in os.listdir(label_dir): if txt_file.endswith(.txt): if not validate_label_file(os.path.join(label_dir, txt_file)): print(f❌ Failed on {txt_file}) break else: print(✅ All label files normalized correctly)参数说明脚本中all(0.0 c 1.0 for c in coords)是核心校验逻辑。YOLOv5对越界坐标无容错机制——若x_center1.05模型会将其截断为1.0导致bbox严重偏移若width0.0该目标将被完全忽略。此检查应在训练前必跑。2.3dataset.yaml配置文件3个字段决定训练能否启动YOLOv5通过--data dataset.yaml加载数据集元信息。该数据集附带的dataset.yaml内容如下train: ../images/train val: ../images/val nc: 2 names: [ripe, unripe]nc: 2必须与实际类别数严格一致。若误写为nc: 1训练会报AssertionError: nc mismatch若写为nc: 3模型输出层维度错配loss爆炸。names: [ripe, unripe]顺序必须与标签文件中的class_id一一对应ripe→0unripe→1。若颠倒为[unripe,ripe]模型会把熟橙子当成未熟且loss表面正常因交叉熵仍可计算但结果完全相反——这是最隐蔽的玄学翻车点。train/val路径必须是相对于dataset.yaml所在位置的相对路径。若你在/home/user/yolov5/下运行train.py而dataset.yaml在/home/user/orange_maturity_yolov5/则路径必须写../orange_maturity_yolov5/images/train而非绝对路径。YOLOv5不支持绝对路径作为train:值。3. 用YOLOv5s在本地跑通最小训练闭环从解压到验证现在我们跳过所有理论直接执行一个能在30分钟内完成、看到loss下降、生成预测图的最小可行流程。所有命令均基于YOLOv5官方仓库v6.1或v6.2验证。3.1 环境准备与数据集接入确保已安装PyTorchCUDA版及YOLOv5依赖。推荐使用conda创建干净环境# 创建新环境Python 3.8 conda create -n yolov5-orange python3.8 conda activate yolov5-orange pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt将下载的数据集解压到YOLOv5项目同级目录# 假设解压后路径为 /path/to/orange_maturity_yolov5/ ls /path/to/orange_maturity_yolov5/ # images/ labels/ dataset.yaml visualize_labels.py3.2 启动训练一行命令但参数有讲究在yolov5/目录下执行python train.py \ --img 640 \ --batch 16 \ --epochs 100 \ --data /path/to/orange_maturity_yolov5/dataset.yaml \ --weights yolov5s.pt \ --name orange_maturity_v1 \ --cache--img 640输入分辨率。橙子图像通常细节丰富果皮纹理、反光斑点640是平衡精度与速度的起点若显存不足8GB可降为416但小目标检出率下降明显。--batch 16批大小。需根据GPU显存调整RTX 306012GB可跑16GTX 16606GB建议改8。切勿盲目调大——batch过大导致梯度更新不稳定loss震荡剧烈。--weights yolov5s.pt使用预训练权重迁移学习。yolov5s轻量适合边缘部署若追求更高精度且显存充足可换yolov5m.pt。--name orange_maturity_v1实验名称用于保存日志和权重到runs/train/orange_maturity_v1/。--cache强烈建议开启。首次运行时将所有图像缓存为.npy格式后续epoch加载速度提升3倍以上。若磁盘空间紧张可去掉此参数。逻辑说明--data指向dataset.yamlYOLOv5自动解析train:路径并递归扫描所有.jpg/.png文件再按同名规则加载.txt标签。无需手动编写数据加载器。3.3 训练过程监控与关键指标解读训练启动后终端实时输出Epoch GPU_mem box_loss obj_loss cls_loss ... metrics/precision metrics/recall metrics/mAP_0.5 1/100 3.2G 0.0421 0.0387 0.0215 0.721 0.689 0.652 2/100 3.2G 0.0398 0.0362 0.0198 0.735 0.702 0.668 ...重点关注box_loss定位损失反映bbox中心点与宽高的拟合程度。理想情况应从0.04逐步降至0.015以下。cls_loss分类损失反映熟/生判别能力。若长期高于0.02说明类别区分度不足或数据不平衡。metrics/mAP_0.5核心指标。mAP0.5表示IoU阈值为0.5时的平均精度。农业场景中0.75为可用0.85为优秀。训练完成后权重保存在runs/train/orange_maturity_v1/weights/best.pt。4. 可视化脚本深度解析与标注质量自检实战数据集附带的visualize_labels.py不是玩具而是标注质量的黑匣子透视镜。它不只画框更暴露数据集的3个隐藏缺陷漏标、错标、尺度偏差。4.1 脚本执行与输出逻辑在数据集根目录/path/to/orange_maturity_yolov5/下运行python visualize_labels.py \ --images-dir ./images/val \ --labels-dir ./labels/val \ --output-dir ./vis_val_output \ --classes ripe,unripe--images-dir指定图像目录val集用于验证避免污染训练集。--labels-dir对应标签目录。--output-dir生成带框图像的保存路径自动创建。--classes逗号分隔的类别名必须与dataset.yaml中names顺序一致。脚本核心逻辑遍历--images-dir下所有图像对每张图读取同名.txt标签解析class_id和归一化坐标将归一化坐标转为像素坐标需读取原图尺寸用OpenCV绘制矩形框类别文字颜色按类别区分ripe绿色unripe红色保存结果图文件名与原图一致。4.2 通过可视化发现3类典型问题运行后打开./vis_val_output/逐张检查。以下是我在某次实测中发现的高频问题现象原因解决图中明显有橙子但无任何框漏标标注员遗漏了小目标如被叶片遮挡的青果或远距离果实用脚本统计每张图的标注数量grep -c ^0|^1 ./labels/val/*.txt | awk -F: {sum$2} END{print sum/NR}若平均1.2需返工补标框覆盖了果柄或枝叶而非果实主体错标标注时未严格框住果实外接矩形而是框了包含枝叶的区域修改visualize_labels.py在绘框前添加面积过滤if width * height 0.005: continue过滤面积0.5%图像的极小框同一张图中ripe框普遍比unripe框大30%以上尺度偏差标注员对“熟果更大”的主观认知影响了框选尺度导致模型学到尺寸先验而非颜色/纹理特征用脚本统计两类框的平均面积awk /^0/{a$4*$5; n} /^1/{b$4*$5; m} END{print ripe avg:,a/n,unripe avg:,b/m} ./labels/val/*.txt若差异25%需重标血泪经验我曾因未做此项检查在训练后期发现模型对远距离小熟果召回率为0——可视化后才发现所有小熟果都被漏标而小未熟果标注完整。补标200张图后mAP_0.5从0.62升至0.79。4.3 进阶技巧用可视化结果指导数据增强策略可视化不仅是质检更是增强策略的指南针。观察./vis_val_output/中的典型样本若大量熟果出现强反光白色高亮斑块在train.py中启用--augment并添加HSV增强hsv_h0.015, hsv_s0.7, hsv_v0.4若未熟果常被深绿叶片包围启用mosaic14图拼接增强背景多样性若存在大量模糊运动果采摘机械臂拍摄添加motion_blur1参数。这些参数直接写入train.py的parser.add_argument或通过--hyp指定超参文件无需修改模型代码。5. 避坑指南YOLOv5训练橙子数据集的5个致命陷阱即使数据集“ready”YOLOv5训练仍存在5个高频致命坑。每个都来自真实翻车现场按现象→原因→解决三步给出可立即执行的方案。5.1 现象训练loss初期剧烈震荡10个epoch后突然nan原因学习率过高 小目标密集导致梯度爆炸。橙子图像中常有多个小果实尤其未熟果YOLOv5的obj_loss对小目标敏感初始学习率0.01易使梯度溢出。解决在train.py中修改parser.add_argument(--lr0, typefloat, default0.01)为default0.005或训练命令中加--lr0 0.005更稳妥方案启用余弦退火--cos-lr让学习率从0.005平滑衰减至0。5.2 现象验证集mAP_0.5停滞在0.4左右loss持续下降原因类别极度不平衡。数据集中未熟果青色占比达78%模型学会“默认预测unripe”导致cls_loss下降但precision极低。解决计算类别权重from sklearn.utils.class_weight import compute_class_weight传入所有class_id数组得到[0.35, 1.28]在models/yolo.py的Detect类中修改self.balance参数原为[4.0, 1.0, 0.4]将cls_loss权重设为1.28/0.35≈3.66或更简单在train.py中compute_loss函数内对cls_loss乘以权重系数。5.3 现象best.pt在验证集上效果好但用detect.py推理单张图时bbox全消失原因detect.py默认conf_thres0.25而模型在验证集用的是0.001val.py中硬编码。低置信度预测被过滤。解决推理时显式降低阈值python detect.py --weights runs/train/orange_maturity_v1/weights/best.pt --source test.jpg --conf 0.15或修改detect.py中parser.add_argument(--conf, ...)的default0.15。5.4 现象训练时GPU显存占用忽高忽低偶尔OOM原因--cache开启后YOLOv5将图像缓存为.npy但某些PNG图像含alpha通道4通道缓存时未剥离导致内存翻倍。解决在datasets.py的LoadImagesAndLabels.__init__中于cv2.imread后添加if img.ndim 3 and img.shape[2] 4: img cv2.cvtColor(img, cv2.COLOR_BGRA2BGR)或批量转换图像mogrify -background white -alpha remove -alpha off *.png。5.5 现象visualize_labels.py生成的图中部分框颜色错乱ripe显示红色原因--classes ripe,unripe参数中逗号后有空格如ripe, unripesplit(,)后unripe字符串首字符为 导致类别匹配失败。解决严格检查参数--classes ripe,unripe无空格或在脚本中加固classes [c.strip() for c in args.classes.split(,)]。6. 进阶技巧用Grad-CAM热力图定位模型决策依据验证是否真在看“成熟度”训练完成只是开始。真正决定模型能否落地的是它是否关注了人类专家认可的成熟度特征——比如熟果的橙红色泽、果皮蜡质反光、轻微皱缩而非枝叶阴影、拍摄角度等无关噪声。Grad-CAMGradient-weighted Class Activation Mapping正是为此而生它生成热力图直观显示模型做“ripe/unripe”判断时视线聚焦在图像的哪些像素区域。6.1 快速集成Grad-CAM到YOLOv5推理流程YOLOv5官方未内置Grad-CAM但只需15行代码即可注入。在detect.py末尾添加# gradcam_integration.py (append to detect.py) from pytorch_grad_cam import GradCAM from pytorch_grad_cam.utils.image import show_cam_on_image def run_gradcam(model, img_tensor, target_class, layer_namemodel.model[-1]): # 获取YOLOv5的Detect层最后一层 target_layers [eval(layer_name)] cam GradCAM(modelmodel, target_layerstarget_layers, use_cudaTrue) # 构造target针对ripe0类 targets [ClassifierOutputTarget(target_class)] # 生成热力图返回numpy array grayscale_cam cam(input_tensorimg_tensor, targetstargets)[0, :] # 叠加到原图 rgb_img img_tensor[0].cpu().permute(1,2,0).numpy() rgb_img (rgb_img - rgb_img.min()) / (rgb_img.max() - rgb_img.min()) # 归一化 visualization show_cam_on_image(rgb_img, grayscale_cam, use_rgbTrue) return visualization # 在detect.py的main()中推理后添加 if args.gradcam: cam_img run_gradcam(model, img_tensor, target_class0) # ripe类 cv2.imwrite(f{save_dir}/gradcam_{p.stem}.jpg, cam_img)然后运行python detect.py \ --weights runs/train/orange_maturity_v1/weights/best.pt \ --source ./images/val/orange_042.jpg \ --gradcam \ --conf 0.36.2 热力图结果解读与3种典型模式生成的gradcam_orange_042.jpg中红色越深表示模型越关注该区域。观察时重点看模式说明应对健康模式热力图集中在果实主体熟果红区覆盖橙红色果皮未熟果红区覆盖青绿色果皮且避开果柄、叶片模型学到正确特征可进入部署无需干预伪影模式热力图大片覆盖图像边缘、水印、或相机标定板若数据含标定图模型记忆了拍摄环境噪声非果实特征清洗数据集删除含标定板/水印图像漂移模式热力图集中在果实阴影、相邻叶片、或果柄连接处模型用位置线索替代颜色/纹理线索如“果柄下方一定是熟果”添加随机裁剪--rect、旋转增强打破位置先验我的习惯每次训练完必抽10张验证图跑Grad-CAM。若超过3张出现“漂移模式”立即停训回溯数据增强策略——这比等mAP掉下来再排查快10倍。有一次热力图显示模型在靠果柄阴影判断成熟度我才发现数据集中80%的熟果都位于画面右下角因采摘臂固定角度于是加入--degrees 15随机旋转mAP_0.5提升0.08。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →