简介:这套番茄(圣女果/西红柿)目标检测数据集面向计算机视觉初学者、课程设计学生及科研入门者,尤其适合正在训练YOLOv5等检测模型、需要现成标注数据完成迁移学习或实验验证的读者。压缩包共1788个文件,主要提供895张PNG原图、892个PASCAL VOC格式的XML边界框标注文件,以及1个数据清单txt;整体约180.4MB,XML标注可直接交给目标检测框架读取,免去自行采集图像和手工标注的重复工作。已有2868人学习下载,说明这套数据集在常用场景下经过较多使用者验证。需注意其中tomato0、tomato1、tomato10三个XML文件已损坏,需重新标注;其余889个XML标注文件完整,足够支撑多数目标检测训练与验证任务。借助该数据集,可快速搭建番茄检测流程,集中精力做数据增强、超参数调优与模型评估,也可用于练习PASCAL VOC格式到YOLO等格式的转换,提升目标检测实战能力。
1. 番茄(圣女果/西红柿)数据集:为什么目标检测团队都拿它做算法验证
一个分类良好的番茄数据集,今天早就不只是农业采摘机器人的专属原料。做目标检测、实例分割、高光谱分析的工程师,往往在跑通公开数据集之后,拿它当成验证算法鲁棒性的“实验台”。原因是番茄的形态天然覆盖了目标检测里最难啃的三种情况:密集粘连、遮挡重叠、表面反光。同一个果实,在不同成熟度下颜色从青绿到深红连续变化,目标尺度跨度大,这让番茄数据集在迁移学习里几乎成了“小目标+形变”的替身。如果你是刚接触数据集清洗、标注格式转换或YOLOv8/YOLOv5训练流程的人,这组数据能让你少走很多弯路:下载渠道公开、标注格式统一、训练收敛速度快。本文按我实际做过的方案,从数据集选型讲到格式转换、训练参数和易踩的坑。
2. 把番茄数据集用起来:三类公开来源与标注格式的取舍
2.1 自建采集 vs. 公开数据集:哪种更适合你的场景
做番茄相关项目时,我通常先问自己一个问题:我要的是成熟度分级,还是采摘点定位,还是单纯拿它验证检测算法?这个问题的答案决定了数据来源。
如果你做的是采摘机器人或温室监测,必须自建采集。常见做法是:用RGB相机固定高度、固定角度拍温室或大田,覆盖不同光照时段,拍完用LabelImg或X-AnyLabeling标注。这类数据集的优点是背景贴近真实作业环境,缺点是成本高,一批数据从采集到清洗再到标注,少说一周时间。
如果目标是算法验证和模型调优,建议直接使用公开的番茄数据集。目前能找到的主要有三类:第一类是用于目标检测的,标注格式多为COCO或VOC,里面包含大量在不同光照和遮挡条件下拍摄的番茄图像;第二类是用于语义分割的,提供像素级掩膜,常见于成熟度分级研究;第三类是用于高光谱分析的,格式往往为.mat或HDF5,这类和公开的icvl高光谱数据集风格更接近,适合做光谱特征提取实验。
公开数据集的优势很明显:处理好的标签能直接供给YOLO系列训练,不需要你为标注质量操心。劣势同样明显:背景相对单一,换到你的实际场景后往往需要二次微调,如果要在YOLOv8上训练自己的数据集,通常需要按你的现场图像做增广。
2.2 COCO、VOC、YOLO三种格式的核心字段与转换判断
拿到番茄数据集后,第一件事不是急着开训练,而是确认标注格式。很多初学者在“数据格式不统一”这一步就卡住,浪费大量时间。这里把三种常见格式的关键字段摆清楚:
COCO格式的标签文件是单个JSON,里面包含images、annotations、categories三部分。annotations里每条记录有bbox、area、segmentation和category_id,其中bbox按“左上角x、左上角y、宽度、高度”记录。VOC格式则是一个XML对应一张图片,标注信息写在object节点下的bndbox里,按“左上角x、左上角y、右下角x、右下角y”记录。YOLO格式则完全不同:每张图片对应一个同名txt文件,每行是“类别id x_center y_center width height”,数值全部做了归一化,范围在0到1之间。
这三种格式的差异就是无数新手在“处理数据集用于yolov8训练”时翻车的根源。COCO和VOC的bbox坐标都是绝对值(像素值),YOLO需要的是相对值(归一化到0~1)。同时COCO的坐标是(x,y,w,h),YOLO也是(x,y,w,h),但VOC的坐标是(x1,y1,x2,y2),这中间要先做一次坐标转换。针对番茄数据集,我一般会先写一个脚本检查标注格式,再做转换,这也是下面要讲的重点。
3. 转换到 YOLO 格式并训练:从标注框到 mAP 的关键命令
3.1 从COCO JSON转换为YOLO TXT的Python脚本
把番茄数据集从COCO转成YOLO,几乎是我每次做目标检测项目都要重复一遍的工作。一个能直接复用的脚本如下:
import json import os from PIL import Image def convert_coco_to_yolo(coco_json_path, image_dir, output_dir): # 读取COCO格式的JSON文件 with open(coco_json_path, 'r', encoding='utf-8') as f: coco_data = json.load(f) # 建立类别ID到索引的映射,这里按category_id排序 categories = coco_data['categories'] cat_id_to_idx = {cat['id']: idx for idx, cat in enumerate(categories)} os.makedirs(output_dir, exist_ok=True) # 以图ID为索引,收集每张图的标注信息 img_id_to_annos = {} for ann in coco_data['annotations']: img_id = ann['image_id'] if img_id not in img_id_to_annos: img_id_to_annos[img_id] = [] img_id_to_annos[img_id].append(ann) for img_info in coco_data['images']: img_id = img_info['id'] file_name = img_info['file_name'] width = img_info['width'] height = img_info['height'] # 生成与图片同名的txt文件 txt_name = os.path.splitext(file_name)[0] + '.txt' txt_path = os.path.join(output_dir, txt_name) with open(txt_path, 'w') as out_file: annos = img_id_to_annos.get(img_id, []) for ann in annos: cat_idx = cat_id_to_idx[ann['category_id']] bbox = ann['bbox'] # COCO格式: [x_min, y_min, width, height] x_min, y_min, w, h = bbox # 归一化到[0,1]区间,YOLO格式要求的核心操作 x_center = (x_min + w / 2) / width y_center = (y_min + h / 2) / height w_norm = w / width h_norm = h / height # 防止归一化后数值越界 x_center = min(max(x_center, 0), 1) y_center = min(max(y_center, 0), 1) w_norm = min(max(w_norm, 0), 1) h_norm = min(max(h_norm, 0), 1) # 写入一行: class_id x_center y_center width height out_file.write(f"{cat_idx} {x_center:.6f} {y_center:.6f} {w_norm:.6f} {h_norm:.6f}\n") print(f"[转换] {file_name} -> {txt_name}, 类别: {cat_idx}") if __name__ == '__main__': # 替换为你的实际路径 convert_coco_to_yolo( coco_json_path='tomato_dataset/annotations/instances_train.json', image_dir='tomato_dataset/images/train', output_dir='tomato_dataset/labels/train' )这段代码的执行逻辑很直接:先从JSON里读出类别和标注,然后对每一张图生成一个txt文件,将COCO的bbox从“左上角+宽高”转成“中心点+宽高”,最后归一化。需要注意两个容易忽略的参数:一个是图片的实际宽高值,不要用文件读取而直接用JSON里的width和height,因为高度不一致的图片在转换时会出错;另一个是归一化后的数值一定要做边界约束,有些标注框边界溢出图片范围,不约束的话训练时会出现NaN损失。
3.2 YOLOv8训练番茄数据集的目录结构与最小命令
转换完标注后,目录结构要按YOLO系列约定摆放。一个最小可跑的目录长这样:
tomato_yolo/ ├── images/ │ ├── train/ # 训练图像 │ └── val/ # 验证图像 ├── labels/ │ ├── train/ # 与训练图像同名的txt标注 │ └── val/ # 与验证图像同名的txt标注 ├── data.yaml # 数据配置文件 └── runs/ # 训练输出目录data.yaml文件内容如下,注意路径不要写成绝对路径,使用相对路径时训练机移动目录不会失效:
# 类别名称,顺序要与前面转换时的索引一致 names: 0: tomato_ripe 1: tomato_unripe # 数据集路径,以tomato_yolo目录作为根 train: images/train val: images/val # 类别数量 nc: 2目录和配置就绪后,训练命令只需要一行。我一般会在训练前先用小批量测试一次链路是否通畅:
# 先验证数据加载是否正常,不实际训练 yolo detect train data=tomato_yolo/data.yaml model=yolov8n.pt epochs=1 batch=2 # 确认没有报错后,再正式训练 yolo detect train data=tomato_yolo/data.yaml model=yolov8n.pt epochs=100 batch=16 imgsz=640 patience=20参数里epochs设100对单类别番茄检测已经够用,因为公开番茄数据集的类别通常只有两到三类(成熟番茄、未成熟番茄、背景),收敛速度比COCO那80类快得多。batch=16是在12GB显存下的常用值,如果显存不够就降到8。imgsz=640是速度和精度的平衡点,想追求小目标召回可以抬到768或960,但训练时间会按平方增长。patience=20的意思是验证集指标连续20轮不提升就自动停止,这可以避免无效训练占用时间。
3.3 训练结果怎么看与mAP偏低时先查哪里
训练结束后,跑一次验证脚本看指标:
yolo detect val data=tomato_yolo/data.yaml model=runs/detect/train/weights/best.pt屏幕会输出mAP50、mAP50-95、precision、recall四组指标。番茄数据集的正常水平是mAP50大于0.9,mAP50-95在0.75左右。如果你的结果明显低于这个区间,不要急着调模型结构,先查三件事:标注框有没有错位、图像是不是有大量重复、训练集和验证集是不是来自同一批视频帧。很多时候mAP虚高或偏低都是这三件事造成的,而不是模型问题。
4. 番茄目标检测的避坑清单:反光、重叠与标注口径
4.1 表面反光带来的漏检误检
现象:训练时loss正常下降,推理时在强光照下的番茄表面动不动就漏检,或者在反光处出现一个多余的框。
原因:番茄表皮光滑,露水和棚膜反光会形成高光区域,这个区域的颜色接近白色,和目标特征差异极大。如果训练图像里反光样本不够,模型会把高光部分当成背景。很多人第一次跑番茄数据集都会在这个问题上翻车,这算是这类数据集典型的“玄学”问题。
解决:核心是增广,而不是换模型。在训练配置里把HSV变换的饱和度增强拉大,同时加上随机亮度和对比度变化。用Ultralytics的配置方式就是在data.yaml里加一段增广参数,把hsv_s调高,再把scale和flip打开。另一个实用技巧是采集数据时,不要只挑光线好的时候拍,把逆光、侧光、阴天中午的样本都放进去,让模型见过反光的变体。
4.2 果实重叠与遮挡导致标注边界不清晰
现象:mAP50看起来不差,但实例分割或框的定位精度很低,尤其在果实重叠区域框整体偏移。
原因:番茄是簇生果实,一束里面三五个果子挤在一起,互相遮挡严重。标注人员在画框的时候对“该框住整个果实还是只框可见部分”的理解不一致,导致同一批数据里既有框完整果实的标注,又有框可见部分的标注。模型在两种标注口径之间摇摆,自然学不准。
解决:在标注前定一个硬规则——统一按“可见部分框住,严重遮挡的不标”。被遮挡超过80%的果实直接放弃标注,这样能减少噪声。如果你用的是公开数据集,要看它的标注文档里是否说明了遮挡处理方式。没有说明的情况下,训练时打开YOLOv8的overlap mask选项可以缓解,但对框类任务作用有限。用YOLOv8做实例分割时,这个问题影响更大。
4.3 成熟度类别判断受光照色温影响
现象:验证集里未成熟番茄的召回率明显低于成熟番茄,误把青色番茄漏掉。
原因:未成熟番茄的颜色偏绿,在暖色棚膜和早晚低色温光照下,颜色会偏移到灰黄,和枯叶背景区分度下降。成熟番茄是红色,色温漂移后依然是红色系里,鲁棒性天然高一些。
解决:做类别均衡重采样。计算训练集中成熟与未成熟的样本比例,如果比例超过3比1,按比例做欠采样或过采样,让模型见到足够多的未成熟样本。同时针对青色果实,手工增加绿色背景的负样本(不带果实的叶片图像),防止模型把整片绿叶误判成未成熟果实。
4.4 数据划分不当导致指标虚高
现象:训练时mAP很好,测试自己拍的视频时完全拉胯。
原因:很多人下载公开数据集后按文件顺序切分训练验证集,但很多番茄公共数据集的图片是从连续视频里抽帧的。连续帧之间高度相似,按顺序切分会造成“训练集见过验证集的邻居帧”,指标好看但没有泛化意义。
解决:按视频片段或田块切分,不要按帧顺序随机切。如果数据集没有提供视频分组信息,就用图像的文件名或聚类方法把相似帧归到同一组,再按组划分。躺平一点的做法是每个文件夹里前80%做训练、后20%做验证,保证同一个文件夹内的连续帧不跨集合。这样才能避免“数据集指标好看,实际场景翻车”的尴尬。
5. 高光谱与多模态方向:番茄数据集的上限在哪里
5.1 高光谱番茄数据集:从检测到品质分析
如果说RGB番茄数据集解决的是“果实在哪里”的问题,高光谱番茄数据集要解决的则是“果实状态怎么样”的问题。常见做法是用高光谱相机采集400~1000nm波段范围内的番茄光谱曲线,配套标注成熟度、含水率或糖度。这类数据集的格式很多是.mat或HDF5,读法上跟处理icvl高光谱数据集mat的思路类似。
一个读取.mat格式的高光谱番茄样本的最小Python示例如下:
import h5py import numpy as np # 读取HDF5格式的高光谱数据 with h5py.File('tomato_hs.mat', 'r') as f: # 打印顶层结构,看看key是什么 print(list(f.keys())) # 假设数据存在'hypercube'这个key下,维度是(高度, 宽度, 波段数) hypercube = f['hypercube'][:] print(f"高光谱数据形状: {hypercube.shape}") # 通常还需要读取波长信息,用于后续波段选择 wavelengths = f['wavelengths'][:] if 'wavelengths' in f else None高光谱数据量极大,直接放进YOLO训练不现实。常规做法是先做波段降维,比如用PCA或选择特征波段,把几十上百个波段压缩成3个通道,再转成伪RGB图送到检测网络。数据增强上注意:高光谱数据不能像RGB那样随便做色相偏移,因为波段值反映物理属性,任意扭曲会破坏光谱曲线。你可以对空间维度做翻转和裁剪,但光谱维度的扰动要极其谨慎。
5.2 多模态融合:番茄采摘机器人的视觉方案
这里再提一下“多模态数据集”对番茄场景的启发。采摘机器人常见的做法是把RGB图像和深度图对齐,生成RGB-D数据,有时还会加入近红外通道来识别被叶片遮挡的果实。做这类方案时,数据集的模态对齐是最大的坑:RGB和深度图的坐标系、分辨率、拍摄时间必须严格对齐,否则融合后特征错位。如果你只做目标检测,先只在RGB通道上训练,把深度通道作为辅助监督信号来用,会少踩很多标定上的坑。
5.3 从数据到模型的常规路径:一张清晰的流程图
在整个番茄数据集的落地流程里,各步骤的数据流关系如下:
原始图像采集 -> 图像清洗(去模糊去重复) -> 标注(检测框/分割掩膜) -> 格式统一(COCO/VOC/YOLO) -> 数据集划分 -> 增广 -> 模型训练/验证 -> 导出TensorRT/ONNX -> 部署这里面最容易被忽略的是“格式统一”和“数据集划分”两步,它们不产生直接收益,但决定了后续所有步骤是否稳定。很多开源项目里,预处理脚本和数据文件是一起打包的,拿到手第一件事就是检查脚本里的路径和类别顺序有没有被改过。这不算技术难点,但绝对是血泪经验。
6. 用番茄数据集做算法验证:三个能直接复用的技巧
第一个技巧是做一个类别热量图。训练完成后,把所有验证集图像过一遍模型,把漏检的目标位置标在热图上。番茄的漏检位置往往集中在图像边缘和果实密集区域,你可以快速判断是增广不足还是NMS阈值不合适。这个方法比只看mAP直观得多。
第二个技巧是利用混淆矩阵判断成熟度分级精度。YOLO训练日志里会输出混淆矩阵图,对番茄数据集,你重点关注成熟番茄和未成熟番茄之间的误分情况。如果误分集中在特定颜色阶段(比如半成熟果),说明你的类别定义太细,得考虑把半成熟并入未成熟类,或者增加过渡态样本。
第三个技巧是把训练好的RGB检测权重当作预训练模型,在另一个小规模番茄分类数据集上微调。因为番茄的颜色和纹理特征相似,迁移后只需要很小的数据量就能获得高准确率,这比每次从ImageNet预训练从头训练省不少时间。
从我做过的项目来看,番茄数据集最有价值的用法不是追求在公开榜单上刷点,而是作为检测算法在抗反光、抗遮挡能力上的磨刀石。每次在番茄上效果好,其他作物场景里也不会差太多。这是我反复用这组数据验证算法的原因。希望这些做法帮你在下一个项目里少走几步弯路。
本文还有配套的精品资源,点击获取