
简介这是一份面向目标检测学习与科研场景的番茄圣女果/西红柿图像数据集包含895张带PASCAL VOC格式边界框标注的真实拍摄图片可直接用于训练YOLOv5等检测模型适合正在完成课程设计、毕业设计或进行目标检测实验的开发者。资源包共1788个文件包括895个png原图、892个xml标注文件及1个说明txt压缩包整体约180.4MBxml标注与图片文件名一一对应划分训练集和验证集比较方便也便于做数据增强和模型评估。需要留意的是tomato0.xml、tomato1.xml、tomato10.xml三个标注文件损坏需借助labelImg等工具重新标注其余标注可正常使用。该资源自发布以来已有2868人学习下载能省去自行采集图像和制作标注的繁琐流程适合快速搭建番茄检测实验并验证模型效果。无论是课程实验还是正式科研都能减少前期数据准备工作量。1. 番茄数据集目标检测与分类落地绕不开的作物样本做计算机视觉的同行应该都有体会网上公开数据集一大堆但真正想训一个能用的作物检测模型时反而找不到针对性强的样本。通用数据集里番茄占比低、场景单一拿去跑业务基本翻车。这份番茄圣女果/西红柿数据集就是把目标锁定在番茄这一个类上覆盖不同成熟度、不同光照和不同拍摄角度下的样本适合做目标检测、实例分割和成熟度分类。新手拿它练手 YOLOv8 能快速跑通全流程熟手可以直接拿它当预训练迁移的基底。它不是什么黑匣子就是一份能让你少踩两个月数据坑的标注好的图集。2. 数据集结构和标注格式先搞清里面到底有什么2.1 目录组织方式拿到压缩包后第一件事不是解压就跑而是先看目录结构。常见做法是分成 images 和 labels 两大块或者按 train / val / test 直接切好。这份数据集通常遵循主流目标检测仓库的组织习惯tomato_dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ ├── classes.txt └── README.md如果下载包是这种结构那么 labels 里的每个 txt 文件与 images 里同名图片一一对应每行格式是class x_center y_center width height坐标是归一化到 0~1 的浮点数。这种格式是 YOLO 系列的原生格式后面直接喂给 YOLOv8 不需要转换。有的版本可能直接给 VOC XML 或者 COCO JSON 格式那就需要用脚本转一下。我一般会先看 classes.txt 里到底定义了几类常见的是把番茄按成熟度分成 green、turning、ripe 三类也有只标一个 tomato 单类的。类别数量直接影响你后面怎么设模型输出头。2.2 标注内容长什么样标注粒度是这份数据集价值的核心。如果标的是 bounding box就是检测任务如果附带 polygon 点那就能直接做分割。以 YOLO 格式为例一个典型标注文件内容如下0 0.5234 0.4821 0.1563 0.1387 1 0.7134 0.2160 0.1024 0.1042 0 0.3098 0.6254 0.0874 0.0921每行第一个数字是类别 ID四个小数分别是框中心 x、中心 y、框宽、框高。注意这里宽高是相对图片宽高的比值不是像素值。看一眼标注再回头对应图片如果你发现框把果蒂也包进去了那是标注风格问题如果框只贴果肉边缘那是精细标注。两种都能用但会影响后处理 NMS 的参数和精度评估。对于分割版本YOLO 格式的每个对象会占多行第一行是类别 ID 加轮廓点个数后面跟着所有点的坐标。这种标注信息量更大训练时可以用 YOLOv8-seg 直接读。2.3 数据划分和类别平衡性检查解压后别急着训练先写几行代码统计每类样本数和每张图的标注框数。这个步骤能避免后面训练一半发现类别严重失衡。import os from collections import Counter label_dirs [labels/train, labels/val, labels/test] class_counts Counter() box_counts [] for ld in label_dirs: for fname in os.listdir(ld): if not fname.endswith(.txt): continue with open(os.path.join(ld, fname)) as f: lines f.readlines() box_counts.append(len(lines)) for line in lines: cls line.split()[0] class_counts[cls] 1 print(类别分布:, dict(class_counts)) print(单图标注框数量分布: min{}, max{}, avg{:.2f}.format( min(box_counts), max(box_counts), sum(box_counts)/len(box_counts)))这段代码把每个标注文件的行数当作框数按类别 ID 累计。如果发现某个类只占 2%后续要么做重采样要么用数据增强补齐。单图平均框数也很关键如果平均只有 1 个框说明大多是单果图像如果平均 5 个以上说明有大片挂果的场景训练时 anchor 和小目标策略要单独调。3. 用 YOLOv8 训练番茄检测从数据整理到 mAP 提升3.1 配置 data.yamlYOLOv8 的配置文件是入门第一道坎。你需要新建一个 tomato.yaml把路径和类别写对。常见错误是路径用了绝对路径导致换机器就崩我一般习惯把数据集和项目放在同一个父目录下然后用相对路径。path: ../tomato_dataset train: images/train val: images/val test: images/test nc: 1 names: [tomato]如果你的 classes.txt 里是三类成熟度就把 nc 改成 3names 列表改成对应的类别名。这里有个细节names 顺序必须和 label 文件里的 class ID 一一对应否则训练看起来正常推理时类别全错位。3.2 训练命令与关键参数用 YOLOv8 训练不需要写复杂的脚本一条命令就能起来。但参数不是默认就行我常用这一套yolo train datatomato.yaml modelyolov8n.pt epochs150 imgsz640 batch16 patience20 projectruns nametomato_exp1modelyolov8n.pt用 nano 模型做前期验证速度快两小时能看出趋势。确认流程通了再换yolov8s.pt或yolov8m.pt提精度。imgsz640如果数据集中大量图片里番茄占比很小可以试imgsz960但显存占用会明显上涨。patience20训练在验证集上连续 20 轮不涨就早停。我用这个值是被 GPU 排队折磨之后养成的习惯省出的时间够别的实验了。训练结束后看 runs/tomato_exp1 下的 weights/best.pt 和 last.pt。best 是验证集上最优的权重部署用这个last 是最后一步的权重你中途想续跑才用得到。3.3 推理验证和可视化模型训完不能只看 mAP要把测试图片拖出来跑一遍看效果。用 predict 模式输出带框的原图重点检查没检测到的、重复框的、类别置信度低的情况。yolo predict modelruns/tomato_exp1/weights/best.pt sourcetomato_dataset/images/test saveTrue conf0.25 iou0.5这里conf0.25是置信度阈值低于这个值的框会被丢掉iou0.5是 NMS 的 IoU 阈值值调小会让重叠框更少但也可能漏掉紧挨着的两个番茄。做过密集果实检测的人应该都懂两个番茄挨在一起阈值调不好一个框吞掉两个果是常态。4. 处理数据集用于 YOLOv8 训练格式转换和增强的实操细节4.1 VOC/COCO 格式转 YOLO 的脚本写法如果拿到的是 VOC XML不用急着找在线转换工具自己写脚本最可靠。核心是把 XML 里的 xmin、ymin、xmax、ymax 转成归一化中心点坐标。注意图片尺寸要从 XML 的 size 节点读不能自己猜。import os import xml.etree.ElementTree as ET def convert_voc_to_yolo(xml_path, out_txt_path): tree ET.parse(xml_path) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) lines [] for obj in root.iter(object): name obj.find(name).text cls_id class_map[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) x_center (xmin xmax) / 2.0 / img_w y_center (ymin ymax) / 2.0 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}) with open(out_txt_path, w) as f: f.write(\n.join(lines))逻辑是先从 XML 里取图片宽高再遍历每个 object 节点。xmin、xmax 是像素坐标除以图片宽高后变成 0~1 的比值。这里最容易写错的是顺序YOLO 需要的是 x_center、y_center、width、height不是 xmin、ymin、xmax、ymax。我见过不少人把最后两个直接填成 xmax 和 ymax导致框全部右偏下偏。class_map 需要自己在脚本里定义比如{tomato: 0}。转完以后一定要抽三五个文件比对一下比如原图 640x480 的框 xmin100转换后 x_center 应该在 100/640 附近算一下验证。4.2 数据增强的取舍番茄数据集的场景往往比较单一大棚里拍的照片背景纹理接近模型容易学到背景而不是果实。常用的做法是离线增强一份副本但别盲目上 HSV 色彩抖动番茄成熟度这个属性恰恰和颜色强相关。把色调乱改会导致红色果变成紫色果模型学到的颜色特征就废了。我一般只对这类作物数据集做以下几种增强import albumentations as A transform A.Compose([ A.HorizontalFlip(p0.5), A.RandomBrightnessContrast(brightness_limit0.15, contrast_limit0.1, p0.5), A.GaussNoise(var_limit(10, 30), p0.2), A.RandomScale(scale_limit0.1, p0.3), ], bbox_paramsA.BboxParams(formatyolo, label_fields[class_labels]))关键是对 bbox 格式钻了一眼YOLO 的 bbox 是归一化坐标formatyolo告诉 albumentations 不要做像素换算。RandomScale 的 scale_limit 控制在 0.1 以内太大会把很多番茄切出画面。如果原图标注框占比都比较大增强后框可能超出图像边界这时候需要设置min_visibility0.7之类参数过滤掉被裁剪过多的框。4.3 稀疏样本类别的处理如果你的数据集里把熟了落地的烂果也归了一类这类样本可能只有十几张。小类别训练时根本学不动我会用重复采样的方法训练时把包含该类的图片的概率提高一倍。做法是写一个自定义 Dataset在__getitem__里优先返回包含稀有类的样本。这样做的副作用是整体 epoch 里的样本分布偏了但多数场景下比直接丢给模型学好得多。5. 番茄数据集使用避坑指南五个典型翻车现场5.1 现象训练 mAP 很高测试集却漏掉大量绿色番茄原因数据集里成熟红色果占比高模型把绿色果当成背景。这不算标注错是分布偏置。解决拆数据集前按类别分层抽样确保 val 和 test 里也有同等比例的绿色果。如果本来就是单类不分成熟度那就把绿色果样本单独复制一份进训练集或者给绿色果区域做局部 mosaic 增强。5.2 现象所有预测框都偏大一个框包住两个番茄原因标注风格不一致。部分图片的标注框贴着果皮边缘另一部分把果蒂和少量叶子也包进去模型学会了一个更大的“平均框”。解决打开 label 文件和图片对比把框的宽高比离群的点找出来。我一般写脚本统计w/h的分布把所有超过 95 分位数的样本挑出来人工看一遍把确实标大的用 labelImg 重新整理。5.3 现象验证集 loss 下降正常但 val 的 mAP 从 50 epoch 开始剧烈震荡原因学习率没配合数据规模。这份数据集如果是几千张的量级默认 YOLOv8 的 lr00.01 偏高后期在最优解附近来回绕。解决把 lr0 调成 0.005 或者用 cosine 调度器。命令里加lr00.005 lrf0.01训练曲线会稳很多。代价是收敛速度更慢但对你理解模型极限是有帮助的。5.4 现象推理时同一颗番茄被两个不同类别都选中原因如果数据集按成熟度分了多个类而不同成熟度之间的颜色边界模糊模型在两个类上都输出 0.5 左右的置信度NMS 只按 IoU 过滤会保留两个。解决这个场景不能只靠 NMS我会把类别数量从三分类改成二分类——成熟/未成熟把半红的归到成熟那一类业务上这个粒度往往够用。你也可以提高 conf 到 0.4 再看效果。5.5 现象数据增强后训练时 loss 突然变成 nan原因Augment 里某次操作生成了空标注框或者坐标越界导致 loss 计算碰到 log(0)。常见于随机裁剪后所有目标都被裁出画面。解决在增强流水线里加检查确保每张图增强后至少保留一个完整标注框。albumentations 里设min_visibility0.3并在训练脚本里用断言过滤掉空 label 的图片。如果你用的是 YOLOv8 内置增强那就把scale0.3改成scale0.1别问我是怎么知道的。6. 最后一道工序用迁移学习把公共番茄模型改造成你的私有识别器大多数情况下你不会只训一次就结束。我现在的习惯是先拿这份数据集训练一个通用番茄检测器当作“预训练权重射手”再针对自己手里的产地大棚图做二次微调。具体做法分三步。第一步用这份数据集在 YOLOv8m 上训满 150 轮得到 best.pt。第二步把自己业务里的少量标注图按 8:2 切分大概 200 张训练、50 张验证。第三步加载第一步的权重固定前 20 层只训练后部检测头。yolo train datamy_tomato.yaml modelruns/tomato_exp1/weights/best.pt epochs80 imgsz640 freeze20 lr00.002这里的freeze20是把前 20 层参数锁死权重不再更新。YOLOv8 的 backbone 和 neck 占了靠前的层锁住它们能防止小数据集把预训练特征冲掉只让 head 去适应目标域的框分布。等这轮跑完再解冻全模型用lr00.0005微调 30 轮精度通常还能涨 1 到 2 个点。从那以后我每次拿到任何作物类数据集都会强制走一遍这个流程先查标注格式再统计类别分布然后训练后必抽图看框最后再用自己的私有小样本微调。整个过程听起来不炫但能把翻车概率压到最低。希望帮到你。本文还有配套的精品资源点击获取