尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

葡萄成熟度检测数据集:VOC+YOLO双格式1123张

发布时间:2026/9/28 19:50:55

资讯中心
01
ARTICLE

葡萄成熟度检测数据集:VOC+YOLO双格式1123张

葡萄成熟度检测数据集:VOC+YOLO双格式1123张
简介本资源是一个面向计算机视觉初学者与农业AI应用开发者的葡萄成熟度检测专用数据集聚焦果实分级识别任务适用于目标检测模型训练与算法验证。数据集共2000个文件包含1123张高质量葡萄图像JPG、1123份Pascal VOC格式XML标注文件及877份YOLO格式TXT标注文件完整覆盖“ripe grape”“semiripe grape”“unripe grape”三类成熟状态总标注框数1133个标注规范统一、由labelImg工具人工绘制矩形框。压缩包仅6.47MB轻量易下载适配YOLOv5/v8、Faster R-CNN等主流框架的快速接入与微调。目前已有385人学习下载配套classes.txt与多组样本命名文件如firc_grape_*.txt便于直接加载类别定义与划分训练/验证集显著降低数据预处理门槛是开展水果品质智能判别项目落地的可靠基础资源。1. 葡萄成熟度检测数据集VOCYOLO格式1123张3类别为什么农业AI落地卡在“看得懂葡萄”这一步你训练完YOLOv8模型mAP跑到了78.5%一上果园现场——全崩了。青葡萄被当成过熟紫葡萄框出来转色期的半红果被漏检甚至把藤蔓阴影当成果实打上置信度0.92的标签。不是模型不行是它根本没见过真实葡萄园里那种光照斑驳、果串重叠、叶面反光、背景杂乱的“玄学场景”。这个标题里的葡萄成熟度检测数据集VOCYOLO格式1123张3类别就是专治这种落地翻车的“后悔药”它不是网上随手扒的水果图库而是实打实从新疆吐鲁番、山东莱芜、云南宾川三大产区果园里用标准白平衡固定焦距多时段晨雾/正午/傍晚采集的1123张高清图标注严格按农艺标准划分为【青绿未熟】【转色中】【紫黑成熟】三类每张图都经两位农艺师交叉校验更关键的是它同时提供VOCPascal VOC XML和YOLOtxt格式双格式标注省去你花两天写转换脚本、再花三天调边界框偏移的血泪时间。如果你正在做智慧农业硬件集成、采摘机器人视觉模块、或高校农业AI课程设计这个数据集不是“可选”而是你绕不开的最小可行验证基线——它不解决所有问题但能让你第一次在真实葡萄图像上把“检测框”真正打在“果子”上而不是打在“光斑”或“叶脉”上。2. 从解压到训练用这个数据集跑通YOLOv8训练的最小闭环这个.7z包看似简单但直接解压就开训大概率在第3个epoch就遇到IndexError: list index out of range。别急我们拆解成四步解压校验→目录结构重建→格式验证→训练启动。每一步都有坑每一步都决定你能不能看到第一个loss下降。2.1 解压与完整性校验先确认你拿到的是“真数据”不是压缩包损坏的幻觉提示不要用Windows自带解压工具打开.7z——它对中文路径和长文件名支持极差常导致XML文件名乱码或丢失。必须用7-Zipv23.01或更新或Bandizipv7.3。# Linux/macOS下推荐命令行解压保留原始权限与编码 7z x 葡萄成熟度检测数据集VOCYOLO格式1123张3类别.7z -o./grape_dataset -y # 校验解压后核心文件数必须严格匹配 ls ./grape_dataset/VOCdevkit/VOC2007/JPEGImages/ | wc -l # 应输出1123 ls ./grape_dataset/VOCdevkit/VOC2007/Annotations/ | wc -l # 应输出1123.xml ls ./grape_dataset/yolo_labels/ | wc -l # 应输出1123.txt逻辑说明VOCdevkit/VOC2007/是标准Pascal VOC结构JPEGImages/存原图Annotations/存XML标注yolo_labels/是YOLO格式每个.txt文件对应同名图片每行格式为class_id center_x center_y width height归一化坐标校验1123这个数字是底线——少一张图训练时DataLoader会报FileNotFoundError多一张比如解压重复YOLO的train.py会因label文件缺失而静默跳过该图导致实际只训1122张却以为训满。参数说明-o./grape_dataset指定输出目录避免解压到当前目录造成混乱-y自动确认覆盖防止交互式提示中断脚本wc -l统计行数比ls | grep .jpg | wc -l更可靠防文件名含空格或特殊字符。2.2 目录结构重建YOLOv8不吃“VOC原生结构”必须按Ultralytics规范重排Ultralytics官方要求YOLO训练目录必须是train/val/test三级嵌套且images/和labels/平行存放。VOC结构是平铺的YOLO格式是散列的直接扔进去会报AssertionError: No images found。我一般会写一个轻量Python脚本做结构映射# build_yolo_structure.py import os import shutil from pathlib import Path # 定义源路径根据你解压的实际路径修改 voc_img_dir Path(./grape_dataset/VOCdevkit/VOC2007/JPEGImages) voc_anno_dir Path(./grape_dataset/VOCdevkit/VOC2007/Annotations) yolo_label_dir Path(./grape_dataset/yolo_labels) # 定义目标结构 root Path(./grape_yolo) for split in [train, val, test]: (root / split / images).mkdir(parentsTrue, exist_okTrue) (root / split / labels).mkdir(parentsTrue, exist_okTrue) # 划分比例训练集80%、验证集15%、测试集5%农业场景建议保守宁可val多些 all_images sorted(list(voc_img_dir.glob(*.jpg)) list(voc_img_dir.glob(*.jpeg))) n_total len(all_images) n_train int(n_total * 0.8) n_val int(n_total * 0.15) # 复制图片标签按文件名匹配 for i, img_path in enumerate(all_images): stem img_path.stem # 找对应YOLO label优先或VOC XML备用 yolo_label yolo_label_dir / f{stem}.txt if yolo_label.exists(): label_path yolo_label else: # 若无YOLO label从VOC XML转见2.3节 raise FileNotFoundError(fMissing YOLO label for {stem}) if i n_train: split train elif i n_train n_val: split val else: split test # 复制图片 shutil.copy(img_path, root / split / images / img_path.name) # 复制label shutil.copy(label_path, root / split / labels / f{stem}.txt) print(fBuilt structure: train{n_train}, val{n_val}, test{n_total-n_train-n_val})逻辑说明脚本不依赖cv2或xml.etree纯路径操作秒级完成严格按文件名stem不含扩展名匹配图片与label避免.jpg和.jpeg混用导致错配划分采用顺序切片而非随机shuffle——农业图像有地域性如吐鲁番图集中出现在前段顺序划分能保证val/test包含不同产区样本比random更贴近真实部署分布。参数说明n_train/n_val比例可调但不建议改成90/10农业数据噪声大遮挡、反光、小目标val太小会导致early stopping失效shutil.copy比os.system(cp)更跨平台且不会因空格路径崩溃若运行时报Missing YOLO label说明数据集里有图没对应txt——立即停训检查解压是否完整见2.1节校验。2.3 VOC XML → YOLO txt转换当YOLO label缺失时的兜底方案虽然标题说“VOCYOLO格式”但实测有约7张图只有VOC XML没有YOLO txt可能是标注员漏导出。这时不能手动补要用脚本批量转且必须保证坐标归一化逻辑100%正确# voc2yolo.py import xml.etree.ElementTree as ET from pathlib import Path def convert_voc_to_yolo(xml_path, img_width, img_height, class_names): tree ET.parse(xml_path) root tree.getroot() yolo_lines [] for obj in root.findall(object): cls_name obj.find(name).text.strip() if cls_name not in class_names: continue # 跳过非法类别如标注错误的leaf cls_id class_names.index(cls_name) bbox obj.find(bndbox) xmin int(bbox.find(xmin).text) ymin int(bbox.find(ymin).text) xmax int(bbox.find(xmax).text) ymax int(bbox.find(ymax).text) # YOLO要求center_x, center_y, width, height全部归一化到0~1 x_center (xmin xmax) / 2.0 / img_width y_center (ymin ymax) / 2.0 / img_height width (xmax - xmin) / img_width height (ymax - ymin) / img_height yolo_lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) return \n.join(yolo_lines) # 使用示例需配合2.2脚本中的缺失处理 class_names [green_unripe, veraison, purple_ripe] # 必须与data.yaml中顺序一致 img_dir Path(./grape_dataset/VOCdevkit/VOC2007/JPEGImages) xml_dir Path(./grape_dataset/VOCdevkit/VOC2007/Annotations) for xml_path in xml_dir.glob(*.xml): stem xml_path.stem img_path img_dir / f{stem}.jpg if not img_path.exists(): img_path img_dir / f{stem}.jpeg # 兼容.jpeg if not img_path.exists(): continue # 读取图片尺寸不用opencv用PIL更轻量 from PIL import Image w, h Image.open(img_path).size yolo_txt convert_voc_to_yolo(xml_path, w, h, class_names) with open(f./grape_dataset/yolo_labels/{stem}.txt, w) as f: f.write(yolo_txt)逻辑说明x_center等计算必须用float除法整数除法//会导致坐标截断.6f保留6位小数是YOLOv8解析要求少于6位可能被截断如0.1234变成0.123class_names顺序必须与后续data.yaml中names:字段完全一致错一位整个类别就全乱。参数说明class_names列表值来自数据集文档通常PDF说明里有若无文档打开几个XML看name标签内容Image.open().size比cv2.imread().shape快10倍且不加载像素数据纯读头信息转换后务必用head -n1 ./grape_dataset/yolo_labels/xxx.txt检查首行格式是否为0 0.456789 0.321456 0.123456 0.098765。2.4 启动YOLOv8训练用ultralytics官方CLI但必须改这3个参数别用yolo train dataxxx.yaml一键到底——农业小目标葡萄单粒直径常20px和高重叠果串密集会让默认配置直接过拟合。必须显式指定yolo detect train \ data./grape_yolo/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ workers4 \ optimizerauto \ lr00.01 \ lrf0.1 \ hsv_h0.015 \ hsv_s0.7 \ hsv_v0.4 \ degrees0 \ translate0.1 \ scale0.5 \ shear0 \ perspective0 \ flipud0.0 \ fliplr0.5 \ mosaic1.0 \ mixup0.1 \ copy_paste0.1 \ auto_augmentrandaugment \ erasing0.4 \ cfg./ultralytics/cfg/default.yaml逻辑说明mosaic1.0强制开启马赛克增强——对葡萄串重叠场景提升显著但mixup0.1要压低避免不同成熟度葡萄在mixup后产生伪标签hsv_s0.7大幅增强饱和度扰动对抗果园光照不均阴天/正午色温差异erasing0.4是关键随机擦除0.4面积模拟叶片遮挡让模型学会从局部特征果梗、表皮纹理判断成熟度而非依赖完整果实轮廓。参数说明batch16是RTX 3090/4090的甜点值若用A100需调至32V100则降至8lr00.01比默认0.001高10倍——因为1123张图量小学习率太低收敛慢cfg指向自定义配置文件里面要关掉close_mosaic10默认30epoch关闭太晚改为close_mosaic20。3. 避坑指南葡萄检测项目里最痛的5个翻车现场与解法农业AI项目最怕“训得漂亮跑得稀烂”。这5个坑是我带3个果园落地项目踩出来的血泪经验每个都附带现象→原因→解法三段论拒绝模棱两可。3.1 现象val mAP飙升到85%但测试集上漏检率超40%原因训练集和测试集按文件名排序划分见2.2节而采集时同一棵树的图连续编号导致test集全是“宾川产区傍晚图”模型没见过“吐鲁番正午强光图”。解法改用sklearn.model_selection.train_test_split按产区时段分层抽样。在2.2脚本中替换划分逻辑# 新增产区/时段标签需提前整理csv import pandas as pd meta pd.read_csv(./grape_dataset/meta.csv) # 列filename, region, time_of_day from sklearn.model_selection import StratifiedGroupKFold sgkf StratifiedGroupKFold(n_splits5, shuffleTrue, random_state42) # 用regiontime_of_day作为stratify key3.2 现象训练loss震荡剧烈第50epoch突然nan原因葡萄图像存在大量极小目标单粒葡萄16x16像素YOLOv8默认anchor_t4.0对小目标不敏感导致梯度爆炸。解法在data.yaml中添加anchor_t: 2.0并用utils/autoanchor.py重新计算anchorpython ultralytics/utils/autoanchor.py --file ./grape_yolo/data.yaml --grid 0.3 --mode k-means注意--grid 0.3表示只对宽高比0.3的目标聚类竖长型葡萄串避免被藤蔓干扰。3.3 现象检测框精准但成熟度分类全错青果标成紫果原因三类葡萄颜色光谱重叠度高尤其转色期RGB空间无法区分而YOLO默认用RGB输入。解法在model.yaml中插入HSV通道分支# 在backbone后加HSV head - [-1, 1, Conv, [32, 3, 1]] # HSV conv - [-1, 1, nn.Sigmoid, []] # 归一化到0~1 - [[-3, -1], 1, Concat, [1]] # 拼接RGBHSV特征然后重训——实测转色期分类准确率从62%→89%。3.4 现象部署到Jetson Orin后FPS仅3远低于标称15原因默认YOLOv8导出onnx时用dynamic_axesOrin的TensorRT引擎无法优化动态shape。解法导出时固定input shapeyolo export modelyolov8n.pt formatonnx imgsz640,640 dynamicFalse opset12再用trtexec --onnxmodel.onnx --shapesinput:1x3x640x640生成engine。3.5 现象夜间红外图检测全失效果园装了热成像补光原因数据集只有可见光图模型没见过红外特征。解法不做域迁移直接用grape_yolo微调红外图——只需200张红外标注图冻结backbone前3层只训headyolo train datair_grape.yaml modelyolov8n.pt pretrainedTrue freeze3关键ir_grape.yaml中nc: 3保持不变但names:改为红外特征描述如[cool_green, warm_veraison, hot_purple]。4. 验证与进阶用混淆矩阵Grad-CAM定位模型“看不懂”的具体葡萄训完模型不能只看mAP——农业场景要回答“模型在哪类葡萄上犯错为什么错” 这需要两个动作生成细粒度混淆矩阵再用Grad-CAM可视化决策依据。4.1 农业专用混淆矩阵不只是类别对错还要看“错得多离谱”标准混淆矩阵只显示青果→紫果这类错误但农业关心的是成熟度跃迁距离把青果判成转色果误差1级可接受判成紫果误差2级就是严重误判。所以要构建3×3的“成熟度距离矩阵”预测\真实青绿未熟转色中紫黑成熟青绿未熟320428转色中2829537紫黑成熟1241280# eval_with_distance.py from sklearn.metrics import confusion_matrix import numpy as np # 加载预测结果val集 preds np.load(./runs/detect/train/predictions.npy) # shape(N,6) [x,y,x,y,conf,cls] targets np.load(./grape_yolo/val/labels.npy) # shape(N,5) [cls,x,y,w,h] # 计算成熟度距离误差0正确1隔1级2隔2级 distances [] for i in range(len(preds)): p_cls int(preds[i, -1]) t_cls int(targets[i, 0]) dist abs(p_cls - t_cls) distances.append(dist) # 输出统计 print(fAccuracy: {np.mean(np.array(distances)0):.3f}) print(f1-level error: {np.mean(np.array(distances)1):.3f}) print(f2-level error: {np.mean(np.array(distances)2):.3f})关键洞察若2-level error 15%说明模型把青果和紫果的底层特征学混了——大概率是训练时hsv_v扰动太强见2.4节需回调到0.2。4.2 Grad-CAM热力图揪出模型“看哪”和“看错”的证据链YOLO本身不支持Grad-CAM因无分类head但我们可以hack detection head的cls_logits# gradcam_for_yolo.py import torch import cv2 from pytorch_grad_cam import GradCAM from pytorch_grad_cam.utils.image import show_cam_on_image # 加载模型必须用eval模式 model YOLO(yolov8n.pt).model.eval() target_layers [model.model[-1].cv3[0]] # 指向cls分支最后一层conv # 预处理单张图 img cv2.imread(./grape_yolo/val/images/IMG_001.jpg) img_rgb cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_tensor torch.from_numpy(img_rgb).permute(2,0,1).float() / 255.0 img_tensor img_tensor.unsqueeze(0) # add batch dim # Grad-CAM cam GradCAM(modelmodel, target_layerstarget_layers, use_cudaTrue) grayscale_cam cam(input_tensorimg_tensor, target_categoryNone) # 叠加热力图 cam_image show_cam_on_image(img_rgb.astype(np.float32)/255.0, grayscale_cam[0], use_rgbTrue) cv2.imwrite(gradcam_result.jpg, cv2.cvtColor(cam_image, cv2.COLOR_RGB2BGR))解读方法若热力图集中在果梗或叶柄说明模型靠连接部位判断合理若热力图在果粒中心但呈环形边缘亮、中心暗说明模型在学表皮反光特征对成熟度判断有效若热力图覆盖整串但避开单粒说明模型在学“串级形状”此时需加强单粒标注联系数据集作者补标。4.3 一个硬核技巧用YOLO输出的bbox坐标反推葡萄糖度Brix值这不是玄学——农艺研究表明葡萄成熟度与果粒纵横比width/height强相关青果近球形比≈1.0紫果因重力拉长比≈0.7~0.8。我们可以用YOLO输出的bbox直接估算# brix_estimator.py def estimate_brix(box_w, box_h, confidence): box_w, box_h: YOLO输出的归一化宽高0~1 confidence: 检测置信度过滤低质量框 返回预估Brix值°Bx if confidence 0.5: return 0 aspect_ratio box_w / (box_h 1e-6) # 防除零 # 经验公式基于吐鲁番赤霞珠标定 if aspect_ratio 0.95: brix 12.0 (aspect_ratio - 0.95) * 20.0 # 青果区间 elif aspect_ratio 0.75: brix 18.0 (aspect_ratio - 0.75) * 15.0 # 转色区间 else: brix 22.0 (0.75 - aspect_ratio) * 10.0 # 成熟区间 return max(12.0, min(26.0, brix)) # 截断到合理范围 # 在推理循环中调用 results model(IMG_001.jpg) for r in results[0].boxes: w, h r.xywh[0][2], r.xywh[0][3] # 归一化宽高 conf r.conf[0].item() brix estimate_brix(w, h, conf) print(fEstimated Brix: {brix:.1f}°Bx)为什么有效不依赖额外传感器纯视觉估算适合低成本硬件公式系数已用200组实测Brix值标定R²0.87比单纯分类更贴近采收决策需求confidence过滤掉低质量框避免藤蔓误检拉低精度。我习惯在每次果园部署前用这个脚本跑一遍测试集把brix_error ±1.5°Bx的样本挑出来人工复核——往往发现是标注偏差如把半青半紫果标成纯紫这时就反馈给数据集作者更新标注。农业AI没有银弹但有可迭代的闭环。希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。