news 2026/10/2 9:54:01

胡萝卜农业视觉数据集:1683张VOC+YOLO双格式田间样本

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
胡萝卜农业视觉数据集:1683张VOC+YOLO双格式田间样本

简介:本资源是一套专为计算机视觉目标检测任务构建的高质量胡萝卜图像数据集,面向深度学习初学者、农业AI研究者及YOLO/VOC模型训练实践者,有效解决小众农作物类别数据匮乏问题。数据集共2000个文件,包含1683张JPG原图、1683份Pascal VOC格式XML标注文件及317份YOLO格式TXT标注文件(含全部样本对应标签),总容量267.6MB;所有标注均由labelImg工具人工绘制矩形框,仅含单类别'carrot',总计7758个精确边界框,标注规范统一、无分割路径干扰,可直接用于模型训练与评估。目前已有250人学习下载,资源结构简洁明确,附带说明文档及标准化命名的标注文件(如xyxr_carrot_*.txt),便于批量加载、格式转换与跨框架适配,是开展农作物识别、轻量级部署验证或课程实验的理想基准数据源。

1. 胡萝卜数据集1683张VOC+YOLO格式:农业视觉落地绕不开的「小众但刚需」样本库

你训练一个蔬菜识别模型,用ImageNet里那几张模糊的胡萝卜图凑数?结果部署到大棚边缘设备上,模型把红萝卜认成红薯、把带泥的缨子当成杂草——这不是玄学,是数据偏差的真实翻车现场。这个「胡萝卜数据集1683张VOC+YOLO格式」不是玩具数据,而是实打实从山东、甘肃、云南三地合作社田间采集的原始图像:覆盖不同生长阶段(苗期/膨大期/成熟期)、多种光照条件(晨雾/正午强光/阴天)、典型干扰场景(泥土附着、叶片遮挡、多株重叠、背景杂乱),每张图都经农技员+算法工程师双人标注校验。它解决的不是“能不能跑通YOLO”,而是“能不能在真实农田里不误判、不漏检、不把采收指令发错”。适合正在做智慧农业硬件集成、农产品分拣流水线视觉模块、或农业AI课程设计的工程师和高校团队——尤其当你发现公开数据集里胡萝卜样本不足200张、且全是超市货架图时,这份田间一手数据就是后悔药。


2. VOC与YOLO双格式并存:为什么必须同时提供两种标注结构?

2.1 VOC格式:兼容传统农业图像分析工具链

VOC格式以Annotations/目录下XML文件为核心,严格遵循PASCAL VOC规范:每个<object>包含<name>(固定为carrot)、<bndbox>(xmin/ymin/xmax/ymax像素坐标)、<difficult>(田间拍摄中极少设为1,仅对严重遮挡样本标记)、<truncated>(对画面边缘截断的胡萝卜根部设为1)。这种结构能直接喂给OpenCV+sklearn的传统pipeline,比如用HOG+SVM做早期胡萝卜病害区域粗筛;也兼容TensorFlow Object Detection API v1.x(需create_pascal_tf_record.py脚本转换),特别适合需要复用旧版农业检测论文代码的团队。

提示:VOC的JPEGImages/与Annotations/目录名不可更改,否则pascal_voc.py加载器会报FileNotFoundError: [Errno 2] No such file or directory: 'Annotations/xxx.xml'——这是新手最常踩的第一个坑,不是路径写错,是目录名大小写或拼写不符规范。

2.2 YOLO格式:为YOLOv5/v8/v10轻量化部署铺路

YOLO格式采用扁平化设计:每张图对应同名.txt文件(如IMG_001.jpg→IMG_001.txt),每行代表一个目标,格式为class_id center_x center_y width height(归一化到0~1范围)。关键细节在于:

  • class_id恒为0(单类检测,避免YOLO训练时因类别索引错位导致loss爆炸);
  • center_x/center_y是bbox中心点相对图像宽高的比例值,不是左上角坐标——这点和VOC本质区别,直接决定模型收敛稳定性;
  • 所有.txt文件必须与图像同名且置于labels/目录,YOLO训练脚本(如train.py)默认只扫描该目录,若误放至Annotations/将静默跳过该样本。
# 验证YOLO标签是否合规的Python脚本(建议训练前必跑) import os from PIL import Image def validate_yolo_labels(img_dir, label_dir): for img_name in os.listdir(img_dir): if not img_name.lower().endswith(('.jpg', '.jpeg', '.png')): continue txt_name = os.path.splitext(img_name)[0] + '.txt' txt_path = os.path.join(label_dir, txt_name) if not os.path.exists(txt_path): print(f"⚠️ 缺失标签: {img_name}") continue # 读取图像尺寸用于归一化校验 img = Image.open(os.path.join(img_dir, img_name)) w, h = img.size 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(f"❌ 标签格式错误({txt_name}第{i+1}行): 应为5个数值,实际{len(parts)}个") continue try: cls_id, cx, cy, bw, bh = map(float, parts) if not (0 <= cx <= 1 and 0 <= cy <= 1 and 0 < bw <= 1 and 0 < bh <= 1): print(f"❌ 坐标越界({txt_name}第{i+1}行): cx={cx}, cy={cy}, bw={bw}, bh={bh}") except ValueError: print(f"❌ 非数字值({txt_name}第{i+1}行): {line.strip()}") validate_yolo_labels("images/", "labels/")

这段代码会逐行校验YOLO标签的数值合法性。我一般会在yolov8 train命令前强制运行它——去年帮某农机厂调试时,就因37张图的bh值算成1.02(超出1.0上限)导致val mAP卡在0.15不动,debug三天才发现是标注工具导出bug。

2.3 双格式同步生成:避免人工转换引入误差

数据集提供者已用voc2yolo.py脚本完成批量转换,但你要理解其核心逻辑:

  1. 解析VOC XML获取原始像素坐标(xmin, ymin, xmax, ymax);
  2. 计算bbox宽高:w = xmax - xmin,h = ymax - ymin;
  3. 计算中心点归一化值:cx = (xmin + w/2) / img_width,cy = (ymin + h/2) / img_height;
  4. 计算宽高归一化值:bw = w / img_width,bh = h / img_height。
    注意:若原始VOC标注中xmax > img_width或ymax > img_height(常见于田间拍摄时镜头畸变导致bbox溢出),脚本会自动裁剪至图像边界——这步处理在voc2yolo.py第42行max(0, min(xmax, img_w))体现,避免YOLO训练时出现负坐标或超限值。

3. 数据集结构解析:1683张图背后的田间分布逻辑

3.1 文件组织:按地域+生长阶段分层管理

数据集解压后呈现清晰的三级目录结构:

carrot_dataset/ ├── images/ # 所有1683张JPG图像(无子目录) ├── labels/ # 对应1683个YOLO格式.txt文件 ├── Annotations/ # 1683个VOC格式.xml文件 ├── ImageSets/ # 划分文件:Main/train.txt, val.txt, test.txt └── README.md # 关键参数说明(含采集设备型号、分辨率、标注工具版本)

其中ImageSets/Main/下的划分文件并非随机生成,而是按地域来源+生长阶段双重平衡:

  • 山东(623张):侧重成熟期采收场景,含大量带泥根茎特写;
  • 甘肃(541张):覆盖苗期到膨大期过渡,强调叶片形态变化;
  • 云南(519张):多阴天/雾天拍摄,突出低对比度下的识别挑战。
    每个划分文件确保三地样本比例接近1:1:1,且各生长阶段占比均衡——这比单纯按7:2:1随机切分更能反映真实部署时的泛化压力。

3.2 图像质量硬指标:拒绝“看起来像”的伪数据

所有图像均满足以下硬性参数:

参数要求不达标后果
分辨率≥1280×720(短边≥720)小目标(如苗期胡萝卜)丢失细节
平均亮度85~180(0~255灰度)过暗导致YOLO anchor匹配失效
标注框面积占比0.5%~35%(单图)过小易被YOLO忽略,过大则泛化差
每图目标数1~12个(中位数4.2)模拟真实田间密度,非实验室摆拍

注意:README.md中明确列出使用cv2.calcHist()计算的亮度直方图统计值,若你用手机补拍新样本,可用该脚本校验是否符合田间光照基准——别让新数据拖垮整个模型的鲁棒性。

3.3 标注一致性保障:农技员与算法工程师的交叉校验机制

每张图经历两轮标注:

  1. 农技员初标:使用LabelImg标注,重点区分胡萝卜与相似物(如白萝卜缨子、甜菜叶、杂草);
  2. 算法工程师复核:用自研carrot_checker.py工具加载标注,自动检测三类问题:
    • overlap_ratio > 0.7(重叠过高,影响YOLO正样本分配);
    • aspect_ratio < 0.3 or > 3.0(过扁或过长,疑似误标);
    • area_ratio < 0.005(面积过小,YOLO默认忽略)。
      复核不通过的图退回重标,最终1683张全部通过——这意味着你拿到手的数据,已经过了农业领域专家+CV工程师的双重过滤。

4. 实战接入指南:从数据加载到YOLOv8训练的完整链路

4.1 数据准备:构建符合Ultralytics规范的目录结构

YOLOv8要求数据集遵循特定布局,需将原始数据集重构为:

carrot_yolo/ ├── train/ │ ├── images/ # 1178张训练图(1683×0.7) │ └── labels/ # 对应1178个.txt ├── val/ │ ├── images/ # 337张验证图(1683×0.2) │ └── labels/ # 对应337个.txt └── test/ # 168张测试图(1683×0.1) ├── images/ └── labels/

执行以下bash命令快速完成(假设原始数据在~/carrot_voc_yolo/):

# 创建目标目录 mkdir -p carrot_yolo/{train,val,test}/{images,labels} # 复制训练集(按ImageSets/Main/train.txt列表) while read img_name; do cp ~/carrot_voc_yolo/images/${img_name}.jpg carrot_yolo/train/images/ cp ~/carrot_voc_yolo/labels/${img_name}.txt carrot_yolo/train/labels/ done < ~/carrot_voc_yolo/ImageSets/Main/train.txt # 同理复制val/test(替换train.txt为val.txt/test.txt) # ⚠️ 注意:YOLOv8默认不读取test/目录,需手动指定--data参数

4.2 配置文件编写:carrot.yaml的关键参数设定

新建carrot.yaml,内容必须包含:

train: ../carrot_yolo/train val: ../carrot_yolo/val test: ../carrot_yolo/test nc: 1 # 单类检测,勿写成0或2 names: ['carrot'] # 名称必须与VOC XML中的<name>完全一致 # 关键:anchor设置要匹配胡萝卜形态 anchors: - [10,13, 16,30, 33,23] # 小目标为主(苗期胡萝卜) - [30,61, 62,45, 59,119] # 中等目标(膨大期) - [116,90, 156,198, 373,326] # 大目标(成熟期带缨子)

为什么锚点要三组?因为胡萝卜在田间尺度变化极大:苗期直径约2cm(占1280px图的0.5%),成熟期连缨子可达30cm(占15%)。若沿用COCO默认anchor,小目标召回率会暴跌——我在山东某基地实测,未调anchor时mAP@0.5仅为0.61,调整后升至0.83。

4.3 YOLOv8训练命令:参数选择的血泪经验

yolo detect train \ data=carrot.yaml \ model=yolov8n.pt \ # 首选nano版:田间边缘设备推理快 epochs=100 \ imgsz=640 \ # 640足够捕捉胡萝卜细节,1280显存吃紧 batch=16 \ # RTX3060可跑满,避免OOM name=carrot_nano_v1 \ patience=15 \ # val loss连续15轮不降则早停,防过拟合 hsv_h=0.015 \ # 色调扰动±1.5°,保留胡萝卜橙红色特征 hsv_s=0.7 \ # 饱和度增强0.7倍,强化泥土中胡萝卜的色差 degrees=5 \ # 旋转±5°,模拟田间自然倾角 translate=0.1 \ # 平移±10%,应对相机抖动 scale=0.5 \ # 缩放±50%,覆盖不同距离拍摄 mosaic=1.0 \ # Mosaic概率100%,提升小目标学习 mixup=0.1 \ # MixUp概率10%,防过拟合(田间样本有限) cache=True \ # 开启缓存,加速IO(1683张图内存够用) device=0 # 指定GPU编号

避坑重点:hsv_h=0.015是经过田间实测的临界值——超过0.02会导致胡萝卜与红土混淆;mosaic=1.0必须启用,否则苗期小目标检测率低于40%;cache=True在16G显存下安全,但若用Colab免费版(12G),需改为cache=False。


5. 避坑指南:1683张图背后的真实翻车现场与解决方案

5.1 现象:YOLO训练loss震荡剧烈,val mAP始终<0.3

原因:VOC XML中<difficult>标签被错误设为1(实际应为0),导致YOLO转换脚本将这些样本标记为ignore,训练时正样本数量锐减。
解决:检查Annotations/下任意XML,确认<difficult>0</difficult>;若存在<difficult>1</difficult>,用sed -i 's/<difficult>1<\/difficult>/<difficult>0<\/difficult>/g' *.xml批量修正。

5.2 现象:推理时大量漏检苗期胡萝卜(细长形态)

原因:YOLOv8默认anchor最小尺寸为10×13像素,在640×640输入下对应原图约20×26像素,而苗期胡萝卜bbox常小于15×15像素。
解决:修改carrot.yaml中第一组anchor为[6,8, 9,15, 15,12],并在训练命令加--cfg ultralytics/cfg/models/yolov8.yaml指向自定义配置。

5.3 现象:验证集PR曲线在Recall=0.8后骤降

原因:ImageSets/Main/val.txt中混入了3张严重遮挡样本(标注框覆盖度<30%),YOLO将其视为难例持续优化,挤占其他样本学习资源。
解决:用labelImg重新打开这3张图,删除低覆盖度标注;或在carrot.yaml中添加rect=True启用矩形训练,降低对遮挡样本敏感度。

5.4 现象:部署到Jetson Nano时FPS仅2.1帧/秒

原因:模型输出层仍保留COCO的80类head,冗余计算拖慢推理。
解决:导出ONNX时指定--simplify --opset 12,再用onnx-simplifier移除未使用分支;或训练时用yolov8n-cls.pt作为backbone微调,而非完整检测模型。

5.5 现象:同一张图在VOC和YOLO格式下bbox位置肉眼可见偏移

原因:VOC标注使用<xmin><ymin><xmax><ymax>(左上+右下),而YOLO转换脚本误将xmax当作width计算,导致bw = xmax / img_width错误。
解决:核对voc2yolo.py第38行是否为w = xmax - xmin,若为w = xmax则立即修复——该bug存在于部分第三方转换脚本中,本数据集已修正。


6. 进阶技巧:用胡萝卜数据集反向优化YOLO的anchor与损失函数

6.1 K-means聚类生成定制anchor

VOC/YOLO双格式存在的最大价值,是让你能基于真实田间bbox分布重算anchor。执行以下步骤:

  1. 从Annotations/提取所有原始像素级bbox:
import xml.etree.ElementTree as ET import numpy as np bboxes = [] for xml_file in os.listdir("Annotations/"): tree = ET.parse(f"Annotations/{xml_file}") root = tree.getroot() for obj in root.findall("object"): 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) bboxes.append([xmax-xmin, ymax-ymin]) # 宽高数组 bboxes = np.array(bboxes)
  1. 运行K-means(k=9,对应YOLOv8的3组×3个anchor):
from sklearn.cluster import KMeans kmeans = KMeans(n_clusters=9, random_state=42, n_init=10) kmeans.fit(bboxes) anchors = kmeans.cluster_centers_ print("推荐anchor(宽,高):") for a in anchors: print(f"[{int(a[0])},{int(a[1])}]")

实测结果:田间胡萝卜最优anchor为[12,18, 22,35, 38,26, 45,72, 82,58, 105,112, 142,95, 185,198, 320,280]——比COCO默认anchor更贴合细长根茎形态。

6.2 修改CIoU损失为WIoU:提升小目标回归精度

YOLOv8默认CIoU在胡萝卜苗期小目标上收敛慢。将ultralytics/utils/loss.py中BboxLoss类的self.iou_loss替换为WIoU:

# 在loss.py中找到compute_loss方法,替换iou计算段 # 原CIoU: # iou = bbox_iou(pred_boxes, target_boxes, CIoU=True) # 改为WIoU: from ultralytics.utils.metrics import wIoU iou = wIoU(pred_boxes, target_boxes)

WIoU对小目标iou梯度更平滑,实测在苗期样本上回归loss下降速度提升40%。

6.3 构建田间特化评估协议:超越mAP的实用指标

农业场景不只看mAP,更关注:

指标计算方式合格线业务意义
漏检率(Miss Rate)漏检胡萝卜数 / 总胡萝卜数≤5%直接影响采收效率
误检率(False Alarm)误标非胡萝卜数 / 总检测框数≤3%防止分拣机错误剔除
泥土适应性在含泥样本上mAP@0.5 vs 全集mAP@0.5≥0.95衡量模型对田间真实干扰的鲁棒性
推理延迟稳定性连续100帧FPS标准差 / 平均FPS≤0.15边缘设备实时性保障

我每次交付农业项目前,都会用这四维表格替代单纯mAP报告——客户看到“泥土适应性0.97”比“mAP@0.5=0.83”更信服。从那以后我每次用新数据集,都强制走一遍这四维验证,哪怕多花两小时。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 9:53:29

Codex升级实测:从代码助手到AI编程智能体的工作流变革

最近几天把 Codex 升级到了最新版&#xff0c;然后用了整整一周。说实话&#xff0c;刚开始我只把它当成一个能在终端里写代码的玩具&#xff0c;但越用越觉得不对劲——这次更新根本不是加几个功能那么简单&#xff0c;而是把整个产品逻辑都换了一套。Codex 这个来自 OpenAI 的…

作者头像 李华
网站建设 2026/10/2 9:53:14

校园团购系统毕业设计:从需求分析到技术落地的完整指南

1. 项目的本质是什么——别把它当成一个普通的购物网站来做很多人拿到"学校团购系统"这个题目&#xff0c;第一反应是"这不就是个商城嘛"&#xff0c;然后照着网上的电商项目模板一顿抄&#xff0c;最后被答辩老师问得哑口无言。我见过太多这样的学生了&am…

作者头像 李华
网站建设 2026/10/2 9:51:46

基于AI代理的多人多AI协同系统架构设计与实践

多人多AI一起干活这事&#xff0c;听起来很热闹&#xff0c;真做起来第一个坑就是“没人牵头”。我几年前在团队里牵头搞过一段内部AI工具整合&#xff0c;当时大家手上有好几个大模型服务、本地跑着一个开源模型&#xff0c;还有几个人各自写了脚本调用。表面看是各干各的&…

作者头像 李华
网站建设 2026/10/2 9:51:39

多回合AI代理开发实战:用Genkit代理API实现工具调用与会话管理

Genkit的代理API我用了大半年&#xff0c;最深的感受是&#xff1a;它确实把“多回合AI代理”的门槛从框架级降到了配置级。以前要自己写上下文管理、工具调用循环、会话隔离&#xff0c;现在几个API就能串起来。这篇文章我会从零开始&#xff0c;用Genkit的代理API做一个能记住…

作者头像 李华
网站建设 2026/10/2 9:51:21

AI知识库不只是搭个RAG:从Demo到生产级系统的关键挑战

“AI知识库是什么&#xff1f;不就是搭个RAG&#xff1f;”这句话我在过去一年里听了不下十遍。说真的&#xff0c;每次听到我都挺感慨——三个月前搭了个RAG demo&#xff0c;上传几份PDF能对话了&#xff0c;就觉得自己已经把AI知识库做完了。直到业务同学把几百份带扫描签章…

作者头像 李华