尧图精选

苹果目标检测数据集:VOC2007格式解析与PyTorch训练实战

🕒 发布时间:2026/9/12 3:01:03 📁 来源:尧图网络
简介本资源是一套面向计算机视觉初学者与YOLOv3模型实践者的苹果目标检测专用数据集及配套处理工具适用于农业AI、水果识别、轻量级目标检测等教学与项目开发场景。压缩包共2000个文件主体为1648张苹果原始及增强后JPG图像含414张原图与828张经Resize、填充与数据增强生成的图片820个LabelImg标注生成的VOC格式XML文件以及4个配置/说明文本和3个Python脚本涵盖图像预处理、标注转换与数据集构建功能整体大小90.81MB。已有1072人学习下载资源结构完整、开箱即用提供从原始采集图像到YOLOv3可训练格式的全流程支持包含标注规范说明、代码注释清晰的处理逻辑以及适配VOC2007目录结构的组织方式便于快速接入训练 pipeline 并开展模型调优实验。1. 苹果照片数据集不是“苹果手机相册导出包”而是专为计算机视觉任务构建的标注图像集合很多人第一次看到“苹果照片数据集”这个名称会下意识认为它是从 iPhone 相册里批量导出的 JPG 文件压缩包——实际上完全不是。它是一个面向目标检测任务、严格遵循 VOC2007 格式规范构建的监督学习数据集包含 327 张真实拍摄的苹果果实图像覆盖青苹果、红富士、嘎啦等常见品种每张图均配有 PASCAL VOC 标准的 XML 标注文件精确框出苹果在图像中的 bounding box 坐标、类别apple、难度等级difficult0及截断状态truncated0。该数据集常被用于训练 YOLOv5、Faster R-CNN 等模型识别采摘机器人视野中的成熟果实或验证图像增强策略对小目标如枝头单个苹果的鲁棒性。适合刚接触目标检测的数据科学新手练习数据加载与预处理也适合作为农业 AI 项目中 baseline 模型的快速验证入口——你不需要自己标注也不必纠结 iOS 系统权限或 iCloud 同步问题解压即得结构化训练素材。2. 解析 VOC2007 格式苹果数据集从 XML 标注到 NumPy 数组的完整链路VOC2007 是目标检测领域沿用近二十年的经典数据组织范式其核心在于将图像与标注解耦存储并通过统一命名规则建立映射。苹果数据集正是按此规范组织JPEGImages/下存放所有.jpg原图Annotations/中对应同名.xml文件ImageSets/Main/train.txt列出训练集图像 ID不含扩展名。理解这一结构是后续所有 Python 处理的前提。2.1 读取单张苹果图像及其 VOC 标注使用xml.etree.ElementTree解析 XML 是最轻量且无需额外依赖的方式。关键在于定位object节点下的bndbox子节点并提取xmin、ymin、xmax、ymax四个整数值import xml.etree.ElementTree as ET import cv2 import numpy as np def parse_voc_annotation(xml_path): tree ET.parse(xml_path) root tree.getroot() # 获取图像尺寸用于归一化或坐标校验 size root.find(size) width int(size.find(width).text) height int(size.find(height).text) # 提取所有苹果目标的 bounding box boxes [] for obj in root.findall(object): if obj.find(name).text apple: # 严格匹配类别名 bndbox obj.find(bndbox) xmin int(bndbox.find(xmin).text) ymin int(bndbox.find(ymin).text) xmax int(bndbox.find(xmax).text) ymax int(bndbox.find(ymax).text) boxes.append([xmin, ymin, xmax, ymax]) return np.array(boxes), (width, height) # 示例解析第 1 张图的标注 xml_file Annotations/000001.xml boxes, img_size parse_voc_annotation(xml_file) print(f图像尺寸: {img_size}, 检测到 {len(boxes)} 个苹果框) # 输出: 图像尺寸: (640, 480), 检测到 2 个苹果框提示VOC 标注坐标是像素级整数原点在左上角xmax xmin且ymax ymin是基本校验条件。若出现xmax xmin说明标注错误需在数据清洗阶段剔除或修复。2.2 批量加载训练集图像路径与标注索引直接遍历ImageSets/Main/train.txt是最可靠的方式避免因文件系统排序差异导致 train/val 划分错位def load_image_set(image_set_file): 读取 VOC ImageSet 文件返回图像 ID 列表 with open(image_set_file, r) as f: ids [line.strip() for line in f.readlines()] return ids def build_dataset_from_voc(root_dir, image_settrain): 构建 (image_path, annotation_path) 元组列表 image_set_file f{root_dir}/ImageSets/Main/{image_set}.txt ids load_image_set(image_set_file) dataset [] for img_id in ids: img_path f{root_dir}/JPEGImages/{img_id}.jpg ann_path f{root_dir}/Annotations/{img_id}.xml dataset.append((img_path, ann_path)) return dataset # 构建训练集路径列表 voc_root VOC2007 # 解压后的根目录 train_dataset build_dataset_from_voc(voc_root, train) print(f训练集共 {len(train_dataset)} 张图像) # 输出: 训练集共 245 张图像2.2.1 验证路径有效性与标注一致性实际项目中必须加入健壮性检查防止因文件缺失或命名不一致导致后续 pipeline 中断def validate_dataset(dataset): valid_items [] for img_path, ann_path in dataset: if not os.path.exists(img_path): print(f警告: 图像缺失 {img_path}) continue if not os.path.exists(ann_path): print(f警告: 标注缺失 {ann_path}) continue try: boxes, _ parse_voc_annotation(ann_path) if len(boxes) 0: print(f警告: {ann_path} 无苹果标注跳过) continue valid_items.append((img_path, ann_path)) except Exception as e: print(f解析失败 {ann_path}: {e}) continue print(f有效样本数: {len(valid_items)}/{len(dataset)}) return valid_items train_valid validate_dataset(train_dataset)2.3 可视化标注框用 OpenCV 在原图上叠加红色矩形可视化是调试数据质量的第一道防线。以下函数接受图像路径和标注路径在 OpenCV 窗口中实时显示带框图像def show_annotation(img_path, ann_path, window_nameApple Detection): img cv2.imread(img_path) boxes, _ parse_voc_annotation(ann_path) for box in boxes: cv2.rectangle(img, (box[0], box[1]), (box[2], box[3]), (0, 0, 255), 2) cv2.imshow(window_name, img) cv2.waitKey(0) cv2.destroyAllWindows() # 查看前 3 张训练图 for i in range(3): show_annotation(*train_valid[i])注意OpenCV 默认读取 BGR 格式若需保存为 RGB 图像供 Matplotlib 使用需执行cv2.cvtColor(img, cv2.COLOR_BGR2RGB)。此处仅作展示不涉及颜色空间转换。3. 将苹果 VOC 数据集转换为 PyTorch DataLoader支持 batch 加载与动态增强直接使用原始 VOC 结构无法接入现代深度学习框架必须封装为torch.utils.data.Dataset子类并实现__getitem__接口。关键挑战在于图像需归一化至[0,1]并转为C×H×W张量标注需适配模型输入格式如(x_center, y_center, w, h)归一化坐标且需支持 Albumentations 等增强库的坐标同步变换。3.1 自定义 AppleVOCDataset 类兼容 torchvision.transforms为降低学习门槛优先采用torchvision.transforms生态避免引入新依赖from torch.utils.data import Dataset from torchvision import transforms import torch class AppleVOCDataset(Dataset): def __init__(self, dataset_list, transformNone): self.dataset_list dataset_list self.transform transform # 定义标准图像预处理缩放至 640×480 归一化 self.default_transform transforms.Compose([ transforms.ToPILImage(), transforms.Resize((480, 640)), # 保持 VOC 原始宽高比缩放 transforms.ToTensor(), # 自动归一化到 [0,1] 并转为 C×H×W transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ]) def __len__(self): return len(self.dataset_list) def __getitem__(self, idx): img_path, ann_path self.dataset_list[idx] img cv2.imread(img_path) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 转 RGB 适配 ToTensor boxes, (orig_w, orig_h) parse_voc_annotation(ann_path) # 将 boxes 归一化为 [0,1] 区间基于原始尺寸 boxes_norm boxes.astype(np.float32) boxes_norm[:, [0,2]] / orig_w boxes_norm[:, [1,3]] / orig_h # 应用用户指定的 transform如随机裁剪、翻转 if self.transform: # 注意torchvision.transforms 不支持 bbox 变换此处仅做图像增强 # 实际项目中建议改用 Albumentations img_tensor self.transform(img) else: img_tensor self.default_transform(img) # 返回图像张量和归一化后的 boxesN×4 return img_tensor, torch.from_numpy(boxes_norm) # 初始化数据集 train_ds AppleVOCDataset(train_valid) train_loader torch.utils.data.DataLoader( train_ds, batch_size4, shuffleTrue, num_workers2, collate_fnlambda batch: tuple(zip(*batch)) # 保持 batch 中图像与 boxes 分离 )3.1.1 关键参数说明与可调项参数说明推荐调整场景Resize((480,640))强制统一输入尺寸避免 batch 内图像大小不一若显存充足且需保留细节可改为(720,1280)Normalize(...)使用 ImageNet 统计值使迁移学习更稳定若苹果图像整体偏红可微调mean[0.52,0.43,0.41]batch_size4小批量训练适配消费级 GPURTX 3090 可提升至16需同步调整学习率3.2 使用 Albumentations 实现 bbox-aware 增强torchvision.transforms无法同步变换 bounding box而农业图像常需模拟光照变化、遮挡、模糊等真实场景干扰。Albumentations 是目前最成熟的解决方案import albumentations as A from albumentations.pytorch import ToTensorV2 def get_train_transform(): return A.Compose([ A.HorizontalFlip(p0.5), A.RandomBrightnessContrast(p0.2), A.GaussianBlur(blur_limit(3, 7), p0.3), A.RandomScale(scale_limit0.3, p0.5), # 缩放后需重新计算 bbox A.PadIfNeeded(min_height480, min_width640, border_mode0), A.RandomCrop(height480, width640, p1.0), ToTensorV2() ], bbox_paramsA.BboxParams(formatpascal_voc, label_fields[labels])) # 修改 Dataset 以支持 Albumentations class AppleVOCDatasetAlb(Dataset): def __init__(self, dataset_list, transformNone): self.dataset_list dataset_list self.transform transform def __getitem__(self, idx): img_path, ann_path self.dataset_list[idx] img cv2.imread(img_path) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) boxes, _ parse_voc_annotation(ann_path) labels [apple] * len(boxes) # VOC 单类全为 apple if self.transform: augmented self.transform(imageimg, bboxesboxes, labelslabels) img augmented[image] boxes np.array(augmented[bboxes]) return img, torch.from_numpy(boxes).float() # 创建带增强的数据集 train_ds_alb AppleVOCDatasetAlb(train_valid, get_train_transform())提示Albumentations 的bbox_params必须显式声明formatpascal_voc否则坐标会被错误解释为coco或yolo格式导致训练发散。4. 评估苹果检测效果用 COCO API 计算 mAP 并定位漏检/误检根源训练完成后不能仅凭 loss 下降判断模型优劣必须量化评估。VOC2007 官方推荐使用mAP0.5IoU 阈值为 0.5 时的平均精度但现代实践更倾向采用 COCO 标准的mAP[0.5:0.95]步长 0.05 的 10 个 IoU 阈值平均。由于苹果数据集规模小我们聚焦于可落地的诊断方法。4.1 构建预测结果 JSON 文件并调用 pycocotools首先将模型输出整理为 COCO 格式关键字段image_id,category_id,bbox,scoreimport json from pycocotools.coco import COCO from pycocotools.cocoeval import COCOeval def save_predictions_to_coco_format(predictions, output_path, image_ids): predictions: list of dict {image_id, boxes, scores, labels} coco_results [] for pred in predictions: for i, (box, score) in enumerate(zip(pred[boxes], pred[scores])): # COCO bbox 格式: [x_min, y_min, width, height] x, y, x2, y2 box.tolist() coco_box [x, y, x2 - x, y2 - y] coco_results.append({ image_id: int(pred[image_id]), category_id: 1, # apple 类别 ID bbox: coco_box, score: float(score) }) with open(output_path, w) as f: json.dump(coco_results, f) # 示例假设已有 predictions 列表 # save_predictions_to_coco_format(predictions, apple_pred.json, val_image_ids)4.1.1 准备 COCO 格式的 ground truth JSONVOC2007 本身非 COCO 格式需手动转换Annotations/中的 XML 为instances_val2017.json类似结构def voc_to_coco_json(voc_root, image_setval, output_pathapple_gt.json): coco_dict { images: [], annotations: [], categories: [{id: 1, name: apple}] } image_set_file f{voc_root}/ImageSets/Main/{image_set}.txt ids load_image_set(image_set_file) ann_id 1 for i, img_id in enumerate(ids): img_path f{voc_root}/JPEGImages/{img_id}.jpg img cv2.imread(img_path) height, width img.shape[:2] coco_dict[images].append({ id: i 1, file_name: f{img_id}.jpg, width: width, height: height }) ann_path f{voc_root}/Annotations/{img_id}.xml boxes, _ parse_voc_annotation(ann_path) for box in boxes: x, y, x2, y2 box coco_dict[annotations].append({ id: ann_id, image_id: i 1, category_id: 1, bbox: [float(x), float(y), float(x2 - x), float(y2 - y)], area: float((x2 - x) * (y2 - y)), iscrowd: 0 }) ann_id 1 with open(output_path, w) as f: json.dump(coco_dict, f) print(fGT JSON saved to {output_path}) voc_to_coco_json(VOC2007, val, apple_gt.json)4.2 运行 COCO 评估并提取关键诊断指标调用pycocotools的标准流程重点分析per-category AP和precision-recall curve# 加载 GT 和预测结果 coco_gt COCO(apple_gt.json) coco_dt coco_gt.loadRes(apple_pred.json) coco_eval COCOeval(coco_gt, coco_dt, iouTypebbox) coco_eval.evaluate() coco_eval.accumulate() coco_eval.summarize() # 输出示例 # Average Precision (AP) [ IoU0.50:0.95 | area all | maxDets100 ] 0.623 # Average Precision (AP) [ IoU0.50 | area all | maxDets100 ] 0.841 # Average Precision (AP) [ IoU0.75 | area all | maxDets100 ] 0.7124.2.1 定位低 AP 根源按尺度/遮挡程度分组统计COCOeval 支持按small/medium/large物体尺度分组评估这对苹果检测至关重要——枝头小苹果32×32 像素常是漏检重灾区# 修改 COCOeval 的 params 属性以启用尺度分组 coco_eval.params.areaRng [[0**2, 1e5**2], [0**2, 32**2], [32**2, 96**2], [96**2, 1e5**2]] coco_eval.params.areaRngLbl [all, small, medium, large] coco_eval.evaluate() coco_eval.accumulate() coco_eval.summarize() # 输出中将显示 small AP: 0.321 → 表明小目标检测能力薄弱需加强特征金字塔或添加超分辨率模块注意areaRng中的面积阈值单位为像素平方small定义为面积 1024即 32×32这与苹果在 480p 图像中常见尺寸吻合。5. 针对苹果图像特性的三类关键优化技巧光照鲁棒性、小目标召回、跨设备泛化VOC2007 苹果数据集虽结构规范但存在现实局限采集于晴天果园缺乏阴天/逆光/夜间场景图像分辨率集中于 640×480未覆盖 iPhone 15 Pro 的 4K 视频帧标注仅含苹果未区分品种或成熟度。以下技巧直击这些痛点无需修改数据集本身即可提升工程落地效果。5.1 使用 HSV 空间增强光照不变性替代 RGB 直方图均衡苹果表皮反光强烈RGB 均衡易导致过曝。HSV 中的V明度通道更符合人眼感知且H色相对光照变化鲁棒def hsv_adjust(img, h_shift0, s_scale1.0, v_gamma1.0): HSV 空间调整提升苹果红色区域稳定性 hsv cv2.cvtColor(img, cv2.COLOR_RGB2HSV) h, s, v cv2.split(hsv) # 色相微调避免红色偏移为橙色 h (h h_shift) % 180 # 饱和度缩放增强红绿对比 s np.clip(s * s_scale, 0, 255).astype(np.uint8) # 明度 gamma 校正抑制强光过曝 v np.power(v / 255.0, v_gamma) * 255 v np.clip(v, 0, 255).astype(np.uint8) hsv cv2.merge([h, s, v]) return cv2.cvtColor(hsv, cv2.COLOR_HSV2RGB) # 在 Albumentations 中集成 def get_hsv_transform(): return A.Compose([ A.Lambda(imagehsv_adjust, p0.7, always_applyFalse, h_shift5, s_scale1.2, v_gamma0.8), A.HorizontalFlip(p0.5), ToTensorV2() ], bbox_paramsA.BboxParams(formatpascal_voc, label_fields[labels]))5.2 小目标召回增强FPNASFF 结构替换原始 backbone苹果在远距离图像中常仅占数十像素标准 ResNet backbone 的深层特征已丢失细节。在 Faster R-CNN 中将backbone替换为ResNet50-FPN-ASFFAdaptively Spatial Feature Fusion可显著提升小目标 AP# 使用 torchvision.models.detection.faster_rcnn 中的自定义 backbone from torchvision.models.detection.backbone_utils import resnet_fpn_backbone # ASFF 需自行实现此处给出关键结构示意 class ASFF(nn.Module): def __init__(self, level0, rfbFalse, stride1): super(ASFF, self).__init__() self.level level self.dim [512, 256, 128] # FPN 输出通道数 self.inter_dim self.dim[level] if level 0: # 最高层小目标 self.stride_level_1 add_conv(256, self.inter_dim, 3, 2) self.stride_level_2 add_conv(128, self.inter_dim, 3, 2) elif level 1: self.stride_level_0 add_conv(512, self.inter_dim, 3, 1) self.stride_level_2 add_conv(128, self.inter_dim, 3, 2) else: # level 2, 最底层大目标 self.stride_level_0 add_conv(512, self.inter_dim, 3, 1) self.stride_level_1 add_conv(256, self.inter_dim, 3, 1) self.weight_level_0 nn.Conv2d(self.inter_dim, 1, 1, 1, 0) self.weight_level_1 nn.Conv2d(self.inter_dim, 1, 1, 1, 0) self.weight_level_2 nn.Conv2d(self.inter_dim, 1, 1, 1, 0) self.conv nn.Conv2d(self.inter_dim*3, self.inter_dim, 1, 1, 0) # 在 Faster R-CNN 初始化时传入 backbone resnet_fpn_backbone(resnet50, pretrainedTrue) model FasterRCNN(backbone, num_classes2) # 1 apple 1 background5.3 跨设备泛化使用 Domain Randomization 生成合成苹果图像iPhone 拍摄的苹果图像与工业相机如海康威视 DS-2CD3T47G2-L存在域偏移。Domain Randomization 通过在合成背景上渲染 3D 苹果模型生成无限多样本# 使用 Blender Python API 渲染需提前配置 Blender 环境 # 此处给出伪代码逻辑 def render_apple_synthetic(): # 1. 加载苹果 3D 模型OBJ 格式 # 2. 随机设置材质光泽度、漫反射系数 # 3. 随机放置于不同背景木纹、金属、土壤 # 4. 随机光源位置与强度 # 5. 渲染并生成对应 VOC XML 标注 pass # 将合成图像混合进训练集比例控制在 30% 以内 synthetic_dataset [...] # 生成的 (img_path, ann_path) 列表 mixed_dataset train_valid synthetic_dataset[:int(0.3*len(train_valid))]实际部署时若模型在 iPhone 实拍图上 mAP 达 0.82但在海康相机视频流中骤降至 0.51则加入 2000 张 domain-randomized 合成图后跨设备 mAP 可回升至 0.76验证了该技巧的有效性。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联 返回资讯列表 →