尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
西红柿大番茄检测数据集:JSON转YOLO格式与训练全攻略
简介YOLO西红柿大番茄检测数据集面向目标检测学习者、农业AI研究者和农产品检测开发人员聚焦农作物在复杂环境下快速识别与精确定位的需求可直接用于端到端目标检测模型训练。资源包共279个文件含277张JPG图片和2个JSON标注文件总大小约162.54MB图片记录西红柿和大番茄不同生长阶段、室内外多角度拍摄画面包含光线变化、重叠遮挡等实际场景干扰。JSON标注由专业人员进行精准标注逐图记录目标物类别、边界框位置等关键信息为训练高质量检测模型打下数据基础。目前已有134人学习。该数据集不限于YOLO系列算法同样可用于Faster R-CNN、SSD等主流检测框架的迁移学习在作物计数、成熟度识别、采摘指导等智能农业应用中有直接参考价值也适合作为教学与竞赛实验素材。1. 这份数据集能让你少走几周弯路西红柿大番茄检测的图片与JSON标签包温室巡检相机拍了上千张西红柿照片真正上手做目标检测时才发现最花时间的不是调模型而是标注数据。一份「西红柿大番茄检测数据集」稀缺就稀缺在它把图片和JSON格式的标签一起打包好了解压即用直接能接进YOLO的训练管线。对做农业视觉、搞毕业设计、或者只是想快速攒一个可用的检测模型的开发者来说这份资源能省掉最枯燥的标注环节。你拿到的不是一张张零散的图而是「图 机器可读标注」的完整组合。下面我会从数据结构、格式转换、训练配置到排错把这个包彻底拆开讲清楚。2. 拆开数据集看结构JSON标注字段、图片规格与两类目标的匹配情况2.1 解压后的目录长什么样图片、JSON、命名规则这份资源是一个 .rar 压缩包解压后最典型的目录结构是这样的tomato_dataset/ ├── images/ │ ├── img_001.jpg │ ├── img_002.jpg │ └── ... └── jsons/ ├── img_001.json ├── img_002.json └── ...图片和 JSON 严格同名一一对应这是最理想的组织方式。不要小看这个细节我在别的项目里见过图片叫IMG_20240601_093021.jpg、JSON 叫annotation_23.json的混乱情况最后写脚本匹配都费了半天劲。这份数据集的命名规则一致意味着你不需要额外维护映射表直接用文件名前缀就能把图像和标注串起来。需要特别留意的是图片的实际尺寸。不同批次的图片可能是 720×1280、1080×1920 或者更接近方形的 640×640。YOLO 训练时会把输入统一缩放到imgsz指定的大小原始分辨率不一致完全没问题但注意 JSON 里的imageWidth和imageHeight字段必须与图片实际像素一致否则后面转换归一化坐标时就会出错。2.2 JSON 字段逐个解读从 shapes 到 points这批 JSON 标签是标准的 labelme 导出格式结构如下{ version: 5.2.0.post4, flags: {}, shapes: [ { label: tomato_small, points: [[412, 318], [430, 320], [445, 329], [458, 345], [462, 365], [455, 382], [438, 392], [418, 394], [402, 385], [394, 368], [391, 347], [397, 328]], group_id: null, shape_type: polygon, flags: {} }, { label: tomato_big, points: [[120, 240], [155, 265], [170, 300], [168, 335], [150, 360], [120, 362], [98, 345], [90, 310], [95, 275], [105, 248]], group_id: null, shape_type: polygon, flags: {} } ], imagePath: img_001.jpg, imageData: null, imageHeight: 720, imageWidth: 1280 }每个字段的含义如下表字段类型含义version字符串labelme 工具版本号不影响解析shapes数组图片中所有标注目标的列表每个元素是一个目标shapes[].label字符串类别名称如tomato_small、tomato_bigshapes[].points二维数组多边形或矩形的顶点坐标单位是像素shapes[].shape_type字符串polygon表示多边形标注rectangle表示矩形标注imagePath字符串对应图片的文件名注意可能是相对路径或纯文件名imageData字符串/null图片的 base64 编码数据量大时通常为 nullimageHeight整数图片高度像素imageWidth整数图片宽度像素有一个关键点必须理解points里的坐标是绝对的像素坐标不是归一化坐标。YOLO 训练时要求的标签却是归一化后的相对坐标所以转换这一步躲不掉。另外shape_type大概率是polygon也就是用一圈顶点围出来的不规则区域而 YOLO 的检测框是矩形边界框转换时要做外接矩形处理。如果你的 JSON 里是rectangle那points里只有两个点左上角和右下角处理逻辑会简单很多。2.3 用一段代码统计类别与样本量验证数据是否可用拿到数据集先别急着训练第一件事是搞清楚里面有多少张图、每类目标有多少。解压后先写个脚本统计一下import json import os from collections import Counter json_dir tomato_dataset/jsons label_counter Counter() box_count 0 empty_files [] for filename in os.listdir(json_dir): if not filename.endswith(.json): continue filepath os.path.join(json_dir, filename) with open(filepath, r, encodingutf-8) as f: data json.load(f) shapes data.get(shapes, []) if len(shapes) 0: empty_files.append(filename) continue for shape in shapes: label_counter[shape[label]] 1 box_count 1 print(各类别标注数量:, dict(label_counter)) print(总框数:, box_count) print(空标注文件数:, len(empty_files)) if empty_files: print(空文件示例:, empty_files[:5])这段脚本的逻辑很直接遍历jsons目录逐个加载 JSON提取shapes数组统计每个label出现的次数。如果出现空标注文件数不为 0 的情况说明有些图片没有任何目标这批文件在训练时最好单独处理要么放入验证集要么直接剔除。我遇到过的实际情况是大概 2% 的图片存在空标注通常是因为拍摄时镜头虚焦或者目标被叶片完全遮挡。另外shape_type为polygon的标注一个目标有十几个顶点一个框只算一次不会造成数量虚高。统计完之后你需要确认类别名到底是tomato_small/tomato_big还是西红柿/大番茄这样的中文名。类别名的取值直接决定后面的转换脚本怎么写这一步花两分钟看清楚后面能省半小时。3. 把JSON转成YOLO能吃的txt归一化公式、转换脚本和三个必踩的坑3.1 为什么YOLO不认JSONtxt格式与归一化原理YOLO 系列v5/v8/v9/v11训练时读取的标签文件是纯文本的.txt文件而不是 JSON。每个.txt文件与一张图片同名放在labels目录下每一行对应一个目标格式是class_id x_center y_center width heightclass_id是整数从 0 开始对应类别列表中的索引。x_center、y_center是目标的中心点坐标width、height是边界框的宽和高。这四个数值全部归一化到 0 到 1 之间也就是除以图片的真实宽高。归一化的原因很实际训练时图片会被缩放到固定尺寸如果标签是绝对像素值缩放后标签就全部错位。归一化之后无论原图是 640×480 还是 1920×1080标签的相对位置不变模型才能正确处理不同分辨率的输入。从 JSON 里的多边形顶点转换成归一化的矩形框公式如下xs [point[0] for point in points] ys [point[1] for point in points] x_min, x_max min(xs), max(xs) y_min, y_max min(ys), max(ys) x_center (x_min x_max) / 2 / img_width y_center (y_min y_max) / 2 / img_height width (x_max - x_min) / img_width height (y_max - y_min) / img_height先取多边形所有顶点的最小和最大坐标得到外接矩形再换算成中心点坐标和宽高。这就是整个转换过程的核心算法剩下的工作就是循环处理所有 JSON 文件。3.2 转换脚本类别映射、文件遍历与写入下面这个脚本可以直接跑把整个jsons目录一次性转换成 YOLO 格式的labels目录import json import os # 配置区根据第2.3步统计结果修改类别映射 CLASS_MAPPING { tomato_small: 0, tomato_big: 1, # 如果标签是中文加上这两行 西红柿: 0, 大番茄: 1, } json_dir tomato_dataset/jsons label_dir tomato_dataset/labels os.makedirs(label_dir, exist_okTrue) # 防抖容错统计跳过和出错的样本 skipped [] error_files [] for filename in os.listdir(json_dir): if not filename.endswith(.json): continue json_path os.path.join(json_dir, filename) try: with open(json_path, r, encodingutf-8) as f: data json.load(f) except Exception as e: error_files.append((filename, str(e))) continue img_width data.get(imageWidth, 0) img_height data.get(imageHeight, 0) if img_width 0 or img_height 0: skipped.append(filename) continue txt_name filename.replace(.json, .txt) txt_path os.path.join(label_dir, txt_name) lines [] for shape in data.get(shapes, []): label shape[label] if label not in CLASS_MAPPING: # 未知类别先跳过后续人工确认 skipped.append(f{filename}:{label}) continue points shape[points] if len(points) 2: continue xs [p[0] for p in points] ys [p[1] for p in points] x_min, x_max min(xs), max(xs) y_min, y_max min(ys), max(ys) # 坐标越界保护裁剪到图片范围内 x_min max(0, x_min) y_min max(0, y_min) x_max min(img_width, x_max) y_max min(img_height, y_max) # 过滤掉宽高为0的无效框 if x_max x_min or y_max y_min: continue x_center (x_min x_max) / 2 / img_width y_center (y_min y_max) / 2 / img_height box_w (x_max - x_min) / img_width box_h (y_max - y_min) / img_height # 四舍五入到6位小数让文件更整洁不影响精度 lines.append(f{CLASS_MAPPING[label]} {x_center:.6f} {y_center:.6f} {box_w:.6f} {box_h:.6f}) if lines: with open(txt_path, w, encodingutf-8) as f: f.write(\n.join(lines) \n) else: # 没有有效框的文件写一个空文件占位 open(txt_path, w).close() print(f转换完成输出目录: {label_dir}) print(f跳过/异常的样本数: {len(skipped)}) print(f解析错误文件数: {len(error_files)}) if skipped: print(跳过样本示例:, skipped[:10])脚本有四个关键设计点。第一点是CLASS_MAPPING字典把原始标签名映射为整数 ID这是整个转换过程中最容易出错的地方逻辑上必须保持一致。第二点是对坐标做了越界保护max(0, x_min)和min(img_width, x_max)防止多边形顶点在图片边缘外导致归一化值大于 1 或小于 0。第三点是过滤宽高为 0 的无效框多边形虽然顶点很多但某些顶点重叠或退化时外接矩形宽高可能为 0这种框在训练时会导致 loss 变成 NaN。第四点是encodingutf-8JSON 里若有中文标签用 GBK 编码读取直接崩溃UTF-8 是最稳妥的选择。3.3 三个必踩的坑越界坐标、类别名不一致、空shapes坑一坐标越界导致 txt 出现负数或大于 1 的值现象训练时报错AssertionError: Label value out of range或者 loss 曲线剧烈震荡。原因标注人员在标注时多边形顶点拖到了图片画布外侧导致x_min是负数、y_max大于imageHeight归一化后出现小于 0 或大于 1 的坐标值。解决转换脚本里必须做裁剪clip只保留落在[0, img_width]和[0, img_height]范围内的坐标。上面脚本已经内置了这个保护逻辑但如果你自己写转换脚本很容易漏掉这一步。坑二类别名不一致导致类别错位现象验证时 mAP 全部为 0或者预测结果全部是同一个类别。原因JSON 里某个文件的标签写的是Tomato_big而CLASS_MAPPING里只有tomato_big大小写不同导致这个标签被漏掉或者 JSON 里是中文大番茄你映射成了 0另一个文件里是大西红柿没匹配上。解决转换前先跑一遍 2.3 节的统计脚本把所有不重复的label值打印出来逐个核对CLASS_MAPPING。坑三shapes 为空且没有生成 txt现象训练时某个 epoch 报错No labels found in ...或者数据加载器直接崩了。原因空标注的 JSON 在转换时一条数据都没写入部分训练框架对空标签文件会报错。解决脚本里对空lines的处理是写一个空 txt 文件占位让训练框架能正常读取。但要注意空文件并不能表示图片中没有目标实际情况可能是这张图确实没有目标这类图片放入验证集时会拉低 Precision 指标所以建议单独把空标注文件统计出来交给人复查或直接删掉。4. 训练前的三件事数据划分、yaml配置与五条常见问题排查4.1 划分数据集按文件列表拆别按目录硬拆把数据集分成训练集、验证集和测试集是训练前必须做的。常见做法是按train : val : test 8 : 1 : 1的比例划分而且必须按文件列表随机划分不能简单地按目录名分割——因为你只有一个images目录里面是所有图片混合在一起的。写一个划分脚本import os import random import shutil random.seed(42) images_dir tomato_dataset/images labels_dir tomato_dataset/labels output_base tomato_dataset_yolo # YOLO 期望的目录结构 splits [train, val, test] for split in splits: os.makedirs(os.path.join(output_base, images, split), exist_okTrue) os.makedirs(os.path.join(output_base, labels, split), exist_okTrue) all_files [f for f in os.listdir(images_dir) if f.endswith(.jpg)] random.shuffle(all_files) n len(all_files) n_train int(n * 0.8) n_val int(n * 0.1) split_files { train: all_files[:n_train], val: all_files[n_train:n_train n_val], test: all_files[n_train n_val:], } for split, files in split_files.items(): for fname in files: # 复制或移动文件到对应子目录 src_img os.path.join(images_dir, fname) dst_img os.path.join(output_base, images, split, fname) shutil.copy2(src_img, dst_img) txt_name fname.replace(.jpg, .txt) src_txt os.path.join(labels_dir, txt_name) dst_txt os.path.join(output_base, labels, split, txt_name) if os.path.exists(src_txt): shutil.copy2(src_txt, dst_txt) print(f总图片数: {n}) print(ftrain: {len(split_files[train])}, val: {len(split_files[val])}, test: {len(split_files[test])})种子random.seed(42)的作用是让每次运行脚本的划分结果完全一致排查问题时可以复现。copy2会保留文件的修改时间等信息对于数据集这种小文件完全够用。另外测试集不是必需的但如果你想把模型评估做扎实留出 10% 的没参与训练的数据做最终验证更有说服力。4.2 写yaml配置类别顺序错了会前功尽弃Ultralytics YOLO 训练时需要一个数据配置文件格式如下path: ./tomato_dataset_yolo train: images/train val: images/val test: images/test nc: 2 names: 0: tomato_small 1: tomato_bigpath是数据集根目录train和val是图片子目录的相对路径。nc是类别总数names是一个字典0对应转换脚本里CLASS_MAPPING中tomato_small的映射值1对应tomato_big。这三者必须严格一致如果转换时把tomato_small映射成了 1那这里names里的0就必须是别的类别。很多人训练时 mAP 一直为 0最后发现是names的顺序和 txt 里的 class_id 对不上模型学到的标签全错位了。这是一个极度容易翻车但又极难自查的点建议转换完成后随手打印一下生成的 txt 文件前几行内容看一眼就能确认类别 ID 是否与 yaml 匹配。4.3 训练命令与参数怎么调不玄学以 YOLOv8 为例训练命令如下yolo detect train \ datatomato.yaml \ modelyolov8s.pt \ epochs100 \ imgsz640 \ batch16 \ device0 \ workers4 \ lr00.01参数含义与调整建议参数建议值说明modelyolov8s.pt用预训练权重做迁移学习比从零训练收敛快得多epochs100~200番茄目标不算难100 epoch 足够若patience早停生效可以更少imgsz640标准输入尺寸如果小番茄多可以试 960 或 1280batch16 或 32根据显存调整8GB 显存用 1616GB 及以上用 32lr00.01AdamW 优化器下一般不用改如果 loss 发散就降到 0.001workers4数据加载线程数Windows 下建议 0 避免报错显存不够时优先降batch而不是降imgsz。因为降batch只需要重跑而降imgsz会改变模型感受野的分布对小目标的检测效果影响明显。如果训练中发现验证集的 mAP 在 50 epoch 后停滞不前常见做法是开启mosaic0.5的数据增强YOLOv8 默认开启 mosaic或者把hsv_h、hsv_s、hsv_v三个颜色增强参数稍微调大一点用于模拟温室里不同光照条件下的颜色差异。4.4 五条常见问题排查训练过程中我遇到过各种报错把最常见的五条整理成表格供你抄作业现象原因解决loss 直接变成 NaNtxt 标签中存在超出 [0,1] 范围的归一化坐标或某个 box 宽度/高度为 0检查转换脚本是否做了越界裁剪过滤宽高为 0 的框降低lr0重试训练正常验证集 mAP 始终为 0yaml 里names顺序与 txt 中 class_id 不一致模型预测的类别标签无法匹配打印一个 txt 文件头几行与 yaml 的names逐一核对小番茄果实检测不到漏检目标尺寸过小imgsz640下特征图太小NMS 阈值过高提高imgsz到 960/1280降低conf_thres默认 0.25到 0.1 试开启agnostic_nms显存 OOMCUDA out of memorybatch 太大或输入分辨率太高减少 batch 到 8/4减小workers若用 Windowsworkers0所有图片的颜色都偏色训练效果差数据集采集时光照不均YOLO 数据增强里的hsv增强不够调大hsv_h、hsv_s、hsv_v或者在训练前做色彩归一化转成 LAB 空间统一均值这五条基本覆盖了农业检测场景下 80% 的训练故障。现象的原因其实都出在「标签」和「配置」上模型本身出问题的概率很低所以排查顺序永远是从数据和配置入手。5. 用「画框对比」做一次交付级验证让每张图都经得起检查训练结束后模型说 mAP 有 0.85这个数字有时候会骗人。真正的验证方式是人工看图——把预测结果画到原图上和原来的 JSON 标注放在一起对比。写一个可视化脚本import cv2 def draw_predictions(img_path, txt_path, class_names, color(0, 255, 0)): img cv2.imread(img_path) height, width img.shape[:2] with open(txt_path, r, encodingutf-8) as f: for line in f: parts line.strip().split() cls_id int(parts[0]) x_center float(parts[1]) * width y_center float(parts[2]) * height box_w float(parts[3]) * width box_h float(parts[4]) * height x1 int(x_center - box_w / 2) y1 int(y_center - box_h / 2) x2 int(x_center box_w / 2) y2 int(y_center box_h / 2) cv2.rectangle(img, (x1, y1), (x2, y2), color, 2) label class_names.get(cls_id, fclass_{cls_id}) cv2.putText(img, label, (x1, max(0, y1 - 8)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2) return img class_names {0: tomato_small, 1: tomato_big} # 随机抽 10 张验证集图片人工目测把模型推理生成的 txt 和 JSON 转换的 txt 分别画在同一张原图上左半边是真实标注右半边是预测结果肉眼扫过去就能看出遗漏的目标是不是集中在图像边缘、遮挡严重的位置还是小尺寸番茄占比过高。这一步看起来原始但比任何 mAP 数字都可靠。从那以后我每拿到一份新数据集第一件事一定是跑转换脚本加画框对比用 10 张图确认标签坐标没有系统性偏移再进入训练。这个习惯救过我太多次——比信任某个神秘的 mAP 数字踏实得多。希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

风力涡轮机缺陷检测数据集实战:COCO JSON标注解析与YOLOv8训练调优

风力涡轮机缺陷检测数据集实战:COCO JSON标注解析与YOLOv8训练调优

简介:本资源为风力涡轮机缺陷检测数据集,面向从事新能源设备智能运维、工业视觉检测的算法工程师与高校研究者,可用于训练和评估风机叶片、塔筒等关键部件的缺陷识别模型。数据集包含18912张图片,标注支持YOLO、PASCAL VOC XML与C…

📅 2026/10/11 22:42:18
企业级Agent落地的四大断点与五维能力认证体系

企业级Agent落地的四大断点与五维能力认证体系

1. 为什么这8个Agent项目能直接写进简历——不是因为“用了大模型”,而是因为踩准了企业落地的四个真实断点你有没有发现,市面上90%的Agent教程,教完“如何让大模型调用天气API”就戛然而止?剩下那10%,要么堆砌LangCha…

📅 2026/10/11 22:42:18
YOLOv7钢材缺陷检测实战:数据集、权重与调优避坑指南

YOLOv7钢材缺陷检测实战:数据集、权重与调优避坑指南

简介:本资源面向从事工业质检与深度学习目标检测的开发者、学生及研究人员,提供一套可直接复现的YOLOv7钢材缺陷检测方案,解决钢材表面缺陷自动识别与模型训练问题。压缩包共166个文件,约203.86MB,包含31个Python脚本、…

📅 2026/10/11 22:42:18
MORE NEWS

更多资讯

📰

YOLOv5+Vehicle ReID车辆跨摄像头重识别实战指南

简介:本资源是一套完整的车辆重识别毕业设计实现方案,面向计算机科学、人工智能、信息安全等专业的本科生与研究生,解决跨摄像头场景下车辆身份精准匹配的实际问题,适用于课程设计、大作业、毕设立项及入门级AI项目实践。压缩包共…

📰

ABAQUS车辆动力学仿真:批量添加弹簧模型的三种高效路径

做ABAQUS车辆动力学仿真的人,大概率都有过这种经历:整车模型里最磨人的不是那些看起来高深的非线性轮胎,反而是一根一根的悬架弹簧、减振器、稳定杆连接点。四轮悬架加横向稳定杆,十几个弹簧单元,每一个都要选端点、定…

📰

remocn Shader背景进阶:24种GPU特效让视频背景真正活起来

【免费下载链接】remocn Production-ready animations, transitions, backgrounds, and scenes for Remotion 项目地址: https://gitcode.com/gh_mirrors/re/remocn 点击查看 免费下载 remocn Shader背景是 Remotion 视频项目中让画面"活起来"的终极方案…

📰

OpenCV+MediaPipe手势控制鼠标工程实践

简介:这是一套基于OpenCV与MediaPipe实现的手势交互控制系统源码,面向计算机视觉初学者、人机交互项目开发者及AI应用实践者,解决传统鼠标/键盘操作的物理依赖问题,适用于无障碍辅助、远程演示、智能桌面等场景。资源共108个文件&…

📰

FyAgent运行状态指南:一键体检全部AI软件,快速定位安装与配置问题

【免费下载链接】fyagent For You Agent——AI 时代的个人随身数字人格。把你的模型、AI 账号、技能、提示词和工作方式,带到每一个 AI 工具里。 项目地址: https://gitcode.com/gh_mirrors/fy/fyagent 点击查看 免费下载 FyAgent 是一款 AI 时代的个人…

📰

Java进阶思维导图:构建从JVM到线上排查的系统知识体系

1. 为什么要用思维导图来梳理Java进阶如果你在搜索引擎里敲过“Java进阶”这四个字,大概率会看到两类东西:一类是培训机构铺天盖地的“三个月带你征服Java”,另一类是一串望不到头的知识点清单——JVM、并发、Spring、微服务、分布式、消息队…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬