
简介这份资源面向目标检测初学者与需要苹果识别实战数据的开发者提供一套可直接用于YOLOv3训练的苹果图像数据集及配套Python处理代码帮助解决自建数据集时标注、增强与格式转换的繁琐问题。压缩包共约2000个文件以1648张jpg图片和820个xml标注文件为主另含少量txt说明与py脚本整体约90.81MB。其中原始苹果图片414张经数据增强、resize与填充后扩充至828张标注采用labelimg预选框形式生成VOC2007格式xml可直接对接YOLOv3训练流程。配套脚本覆盖数据增强与预处理环节便于读者理解从原始图到训练集的完整转换思路也可按需调整参数复现或扩展自己的数据集。目前已有1074人学习下载适合想快速跑通苹果目标检测、熟悉VOC标注规范与数据增强流程的读者参考使用。1. 苹果照片数据集配 VOC2007 标注这套组合到底解决什么问题手里有一批苹果照片想训练一个能识别苹果、定位苹果的模型最卡人的往往不是网络结构而是数据。照片拍了一堆却没有标注或者标注格式和训练框架对不上这时候一个已经整理成 VOC2007 结构的苹果照片数据集就很有价值。VOC2007 是目标检测领域沿用很久的标注格式一张图对应一个 XML里面记录类别名和边界框坐标主流检测框架基本都能直接读。这个标题里的 zip 包本质是把「苹果图像 VOC 格式标注 Python 处理脚本」打包在一起让你跳过从零标注的环节直接进入训练和验证。它适合两类人刚入门目标检测、想找一个类别单一好上手的练手数据以及已经会跑模型、但缺一份干净苹果数据做迁移学习或对比实验的从业者。下面按「先看懂结构、再跑通脚本、最后避坑」的顺序讲清楚。2. 拆开 VOC2007 结构苹果数据集里每个文件是干什么的2.1 VOC2007 的目录约定与苹果类别的落点VOC2007 不是随便放几个文件夹就叫 VOC2007它有一套约定俗成的目录结构训练框架的默认解析器就是按这套结构找文件的。一个标准的苹果数据集解压后通常长这样VOC2007/ ├── Annotations/ # 每张图一个 XML存苹果的边界框 ├── ImageSets/ │ └── Main/ # train.txt / val.txt / trainval.txt / test.txt ├── JPEGImages/ # 原始苹果照片jpg 格式 └── SegmentationClass/ # 分割任务才用检测任务可忽略 SegmentationObject/Annotations里的 XML 是核心。苹果数据集一般只有一个类别名字可能是apple也可能是pingguo这个字符串必须和后面训练配置里的类别名完全一致大小写都不能错。ImageSets/Main下的 txt 文件只存文件名不带扩展名一行一个框架靠它决定哪些图进训练集、哪些进验证集。JPEGImages放原图文件名要和 XML、txt 三者对得上。判断一份数据是不是真 VOC2007最快的办法是抽查一个 XMLannotation folderVOC2007/folder filename000001.jpg/filename size width500/width height375/height depth3/depth /size object nameapple/name bndbox xmin120/xmin ymin80/ymin xmax300/xmax ymax260/ymax /bndbox /object /annotationsize里的宽高必须和真实图片一致bndbox的坐标是左上角和右下角的像素值且要满足xmin xmax、ymin ymax坐标不能超出图片边界。很多从网上抓来的苹果数据集翻车就翻在这里XML 里的宽高是旧的图片被重新压缩过导致框整体偏移。2.2 用 Python 校验数据集完整性拿到数据先别急着训练用一段脚本把明显有问题的样本筛出来比训练到一半报错强。下面这段做三件事检查 XML 和图片是否一一对应、校验坐标合法性、统计每张图的苹果数量。import os import xml.etree.ElementTree as ET from PIL import Image ROOT VOC2007 anno_dir os.path.join(ROOT, Annotations) img_dir os.path.join(ROOT, JPEGImages) bad [] counts {} for xml_name in os.listdir(anno_dir): if not xml_name.endswith(.xml): continue stem os.path.splitext(xml_name)[0] img_path os.path.join(img_dir, stem .jpg) if not os.path.exists(img_path): bad.append((stem, missing image)) continue tree ET.parse(os.path.join(anno_dir, xml_name)) root tree.getroot() w int(root.find(size/width).text) h int(root.find(size/height).text) # 用真实图片尺寸覆盖 XML 里的记录避免尺寸不一致 real_w, real_h Image.open(img_path).size if (w, h) ! (real_w, real_h): bad.append((stem, fsize mismatch xml({w},{h}) real({real_w},{real_h}))) n 0 for obj in root.findall(object): n 1 box obj.find(bndbox) xmin int(float(box.find(xmin).text)) ymin int(float(box.find(ymin).text)) xmax int(float(box.find(xmax).text)) ymax int(float(box.find(ymax).text)) if not (0 xmin xmax real_w and 0 ymin ymax real_h): bad.append((stem, fbad box {(xmin, ymin, xmax, ymax)})) counts[stem] n print(总样本:, len(counts)) print(异常样本:, len(bad)) for item in bad[:20]: print(item) print(单图苹果数分布:, {k: list(counts.values()).count(k) for k in set(counts.values())})逻辑说明先按文件名配对再读 XML 的size和真实图片尺寸比对最后逐框检查坐标范围。参数上ROOT改成你解压后的实际路径即可如果图片是.png或.jpeg把stem .jpg换成对应后缀。跑完重点看两个数异常样本数和单图苹果数分布。如果异常样本占比超过 5%说明这份数据需要先清洗再训练否则模型会学到错误的框位置。提示坐标校验里用float再转int是因为有些标注工具会写出120.0这种浮点字符串直接int()会抛异常。3. 用 Python 把苹果数据集喂给训练流程划分、转换与可视化3.1 重新划分 train/val 并生成 ImageSets数据集自带的train.txt未必适合你的实验比如你想固定验证集做对比或者原划分里验证集太小。下面这段按 8:1:1 重新划分并写回ImageSets/Main。import os import random ROOT VOC2007 img_dir os.path.join(ROOT, JPEGImages) main_dir os.path.join(ROOT, ImageSets, Main) os.makedirs(main_dir, exist_okTrue) stems [os.path.splitext(f)[0] for f in os.listdir(img_dir) if f.lower().endswith((.jpg, .jpeg, .png))] random.seed(42) # 固定种子保证每次划分一致 random.shuffle(stems) n len(stems) n_train int(n * 0.8) n_val int(n * 0.1) train stems[:n_train] val stems[n_train:n_train n_val] test stems[n_train n_val:] def dump(name, items): with open(os.path.join(main_dir, name), w) as f: f.write(\n.join(items)) dump(train.txt, train) dump(val.txt, val) dump(test.txt, test) dump(trainval.txt, train val) print(ftrain{len(train)} val{len(val)} test{len(test)})逻辑说明random.seed(42)是关键参数固定后每次运行划分结果一致方便复现实验。比例 8:1:1 是常见起点数据量小于 500 张时建议改成 7:2:1让验证集更有统计意义。写出的 txt 只存文件名不带后缀这是 VOC 解析器的硬约定带了后缀框架会找不到图。3.2 转成 YOLO 格式坐标归一化与类别映射如果你用的是 YOLO 系列需要把 VOC 的绝对坐标转成归一化的中心点加宽高。转换脚本如下import os import xml.etree.ElementTree as ET from PIL import Image ROOT VOC2007 anno_dir os.path.join(ROOT, Annotations) img_dir os.path.join(ROOT, JPEGImages) out_dir labels os.makedirs(out_dir, exist_okTrue) classes [apple] # 类别顺序必须和训练配置一致 cls_id {c: i for i, c in enumerate(classes)} for xml_name in os.listdir(anno_dir): if not xml_name.endswith(.xml): continue stem os.path.splitext(xml_name)[0] img_path os.path.join(img_dir, stem .jpg) w, h Image.open(img_path).size root ET.parse(os.path.join(anno_dir, xml_name)).getroot() lines [] for obj in root.findall(object): name obj.find(name).text.strip() if name not in cls_id: continue # 跳过非苹果类别 box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) cx (xmin xmax) / 2 / w cy (ymin ymax) / 2 / h bw (xmax - xmin) / w bh (ymax - ymin) / h lines.append(f{cls_id[name]} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}) with open(os.path.join(out_dir, stem .txt), w) as f: f.write(\n.join(lines))逻辑说明YOLO 的坐标全部除以图片宽高做归一化落在 0 到 1 之间。classes列表的顺序决定类别 id训练时的names配置必须和它逐行对应顺序错了模型会把苹果当背景。:.6f保留六位小数是精度和文件体积的折中。转换后建议随机抽几张用可视化脚本叠框确认别直接开训。3.3 可视化验证把框画回苹果照片上转换或清洗之后肉眼确认一遍最靠谱。下面用 OpenCV 把 XML 里的框画到图上import os import cv2 import xml.etree.ElementTree as ET ROOT VOC2007 anno_dir os.path.join(ROOT, Annotations) img_dir os.path.join(ROOT, JPEGImages) save_dir vis os.makedirs(save_dir, exist_okTrue) for xml_name in os.listdir(anno_dir)[:10]: # 先看前 10 张 if not xml_name.endswith(.xml): continue stem os.path.splitext(xml_name)[0] img cv2.imread(os.path.join(img_dir, stem .jpg)) root ET.parse(os.path.join(anno_dir, xml_name)).getroot() for obj in root.findall(object): box obj.find(bndbox) x1 int(float(box.find(xmin).text)) y1 int(float(box.find(ymin).text)) x2 int(float(box.find(xmax).text)) y2 int(float(box.find(ymax).text)) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.imwrite(os.path.join(save_dir, stem .jpg), img)逻辑说明cv2.rectangle的坐标顺序是左上、右下和 VOC 的xmin/ymin/xmax/ymax一致。颜色(0, 255, 0)是绿色线宽 2 像素。跑完打开vis目录重点看三种情况框是否套住苹果、有没有漏标、有没有把叶子或背景误标成苹果。这一步花五分钟能省下几小时排查训练异常的时间。4. 苹果数据集处理里最容易翻车的几个坑4.1 现象训练 loss 正常下降但框全偏原因XML 尺寸和图片不一致这是血泪经验里出现频率最高的一条。现象是模型能收敛但预测框整体偏移或缩放。原因通常是数据集在整理时图片被统一 resize 过XML 里的size却没更新或者反过来。解决用 2.2 的校验脚本把size mismatch的样本挑出来用真实图片尺寸重写 XML 的width和height坐标本身不用动因为坐标是相对原图的。4.2 现象类别名对不上导致全部样本被跳过原因大小写和空格现象是训练时提示某类别没有样本或者转换后 label 文件全是空的。原因是 XML 里写的是Apple或apple带尾空格而配置里是apple。解决在转换脚本里统一name.strip().lower()同时把配置里的类别名也改成小写两边对齐。别小看一个空格它能让整个数据集白标。4.3 现象验证集指标虚高原因同一张图被分到 train 和 val现象是验证集 mAP 高得离谱换测试集就崩。原因是划分时按文件名随机但数据集里存在同一场景连拍的多张近似图被拆到了训练和验证两边。解决划分前先按场景或拍摄批次分组用分组划分代替纯随机保证同一组只进一个集合。苹果数据集如果来自连续拍摄这个问题尤其明显。4.4 现象坐标出现负数或超出边界原因标注工具导出时未裁剪现象是转换后出现负坐标或大于 1 的归一化值训练直接报错。原因是标注时框拖到了图片外工具没做裁剪。解决在转换脚本里加xmin max(0, xmin)、xmax min(w, xmax)这类钳制同时对钳制后宽高小于几个像素的框直接丢弃避免产生无效样本。4.5 现象中文路径或空格路径导致读图失败原因OpenCV 对非 ASCII 路径支持不稳现象是脚本在本地跑得好好的换台机器就报NoneType。原因是图片路径里有中文或空格cv2.imread返回None。解决统一用英文无空格路径或者改用PIL读图再转numpy给 OpenCV。数据集目录名保持VOC2007这种纯英文是最省事的做法。5. 让苹果数据集真正好用的两个进阶习惯第一个习惯是给数据集做一份「体检报告」并随数据一起存。上面 2.2 的校验脚本跑完把总样本数、异常数、单图目标数分布写进一个dataset_report.txt和VOC2007放同级目录。下次换模型或换人接手先看报告再动手比重新摸一遍快得多。我一般还会把类别名、图片平均尺寸、宽高比分布一起记进去因为这些直接决定 anchor 或输入尺寸怎么设。第二个习惯是固定一套「最小复现集」。从苹果数据里挑 20 张覆盖不同光照、遮挡、大小的图单独放一个mini目录任何新脚本先在这 20 张上跑通再上全量。这样调试转换、可视化、增强逻辑时几秒就能出结果不用等全量数据加载。下面这个小脚本用来生成最小复现集import os import shutil import random ROOT VOC2007 mini mini os.makedirs(os.path.join(mini, JPEGImages), exist_okTrue) os.makedirs(os.path.join(mini, Annotations), exist_okTrue) stems [os.path.splitext(f)[0] for f in os.listdir(os.path.join(ROOT, JPEGImages))] random.seed(0) picked random.sample(stems, min(20, len(stems))) for s in picked: shutil.copy(os.path.join(ROOT, JPEGImages, s .jpg), os.path.join(mini, JPEGImages, s .jpg)) shutil.copy(os.path.join(ROOT, Annotations, s .xml), os.path.join(mini, Annotations, s .xml)) print(mini set:, len(picked))参数上random.seed(0)保证每次挑的是同一批图方便团队共享同一套调试样本。min(20, len(stems))防止数据量不足时报错。这套习惯坚持下来你会发现处理苹果数据集这类单类别数据时真正花时间的从来不是写模型而是把数据对齐、验证、留痕。把校验和最小复现集做成固定动作后面换任何数据集都能直接套。希望帮到你。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。