PASCAL VOC2012 自定义Dataset

文章详细介绍了PASCALVOC2012数据集的文件组织结构,包括Annotations、ImageSets和JPEGImages等目录的内容。同时,展示了如何读取和处理VOC数据,包括Compose、ToTensor和RandomHorizontalFlip等预处理步骤。此外,还提供了自定义数据集的方法和生成train.txt、val.txt的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1. PASCAL VOC2012文件架构

2. 读取VOC 数据

3. 自己的数据集自作


个人笔记

代码及资料来源PASCAL VOC2012数据集讲解与制作自己的数据集_哔哩哔哩_bilibili

1. PASCAL VOC2012文件架构

VOCdevkit
    └── VOC2012
         ├── Annotations               所有的图像标注信息(XML文件)
         ├── ImageSets    
         │   ├── Action                人的行为动作图像信息
         │   ├── Layout                人的各个部位图像信息
         │   │
         │   ├── Main                  目标检测分类图像信息
         │   │     ├── train.txt       训练集(5717)
         │   │     ├── val.txt         验证集(5823)
         │   │     └── trainval.txt    训练集+验证集(11540)
         │   │
         │   └── Segmentation          目标分割图像信息
         │         ├── train.txt       训练集(1464)
         │         ├── val.txt         验证集(1449)
         │         └── trainval.txt    训练集+验证集(2913)
         │ 
         ├── JPEGImages                所有图像文件
         ├── SegmentationClass         语义分割png图(基于类别)
         └── SegmentationObject        实例分割png图(基于目标)
  • train.txtval.txttrainval.txt文件里是对应标注文件的索引,每一行对应一个索引信息,也是一个图片的名称

  •  Annotations下一个XML文件对应一张图像的标注信息

XML标注文件中包含了 :

filename,通过在字段能够在JPEGImages 文件夹中能够找到对应的图片。

size记录了对应图像的宽、高以及channel信息。

每一个object代表一个目标,name===该目标的名称,pose===目标的姿势(朝向),truncated===目标是否完整,difficult===该目标的检测难易程度(0简单,1困难)

bndbox===边界框信息,是(xmin,ymin,xmax,ymax)左上角和右下角

  •  通过在标注文件中的filename字段在JPEGImages 文件夹中找到对应的图片。

2. 读取VOC 数据

代码如下:

 transforms定义:(faster_rcnn项目中的transforms.py)

目标检测,如果反转的话boxx也要反转

#     Compose 组合多个transform函数     ToTensor将PIL图像转为Tensor    RandomHorizontalFlip水平翻转 图像+++bboxes
import random
from torchvision.transforms import functional as F

class Compose(object):
    """组合多个transform函数"""
    def __init__(self, transforms):
        self.transforms = transforms

    def __call__(self, image, target):
        for t in self.transforms:
            image, target = t(image, target)
        return image, target

class ToTensor(object):
    """将PIL图像转为Tensor"""
    def __call__(self, image, target):
        image = F.to_tensor(image)
        return image, target

class RandomHorizontalFlip(object):                       #  目标检测,还要翻转对应的bbox
    "&#
### Pascal VOC 2012 数据集用于图像分割的数据预处理方法 #### 数据下载与准备 为了使用Pascal VOC 2012数据集进行图像分割,首先需要从官方或其他可信资源库获取该数据集。增强版本的Pascal VOC 2012数据集尤其适合此类任务,因为其训练样本数量由原来的1464张扩展到了10582张[^2]。 #### 预处理步骤详解 ##### 尺寸调整与裁剪 考虑到实际应用场景中的多样性,在加载图片之前通常会设定固定的尺寸大小以便于后续操作。例如,在某些实验设置下,可能会指定随机裁剪后的输出图像是320×480像素[crop_size = (320,480)]。这一步骤有助于标准化输入给神经网络模型的信息量并减少计算负担[^4]。 ```python from torchvision import transforms transform = transforms.Compose([ transforms.Resize((320, 480)), transforms.RandomCrop(crop_size), ]) ``` ##### 同步数据增强 当执行诸如旋转、翻转之类的几何变换时,必须保证这些变化同样应用于对应的标签mask上;否则将会破坏二者之间的映射关系。因此建议开发人员编写专门针对本项目的Transform函数来同步修改image和label的内容[^5]。 ```python class RandomFlip(object): """Randomly flip the image and its corresponding label horizontally or vertically.""" def __call__(self, img_and_label): img, label = img_and_label if random.random() < 0.5: img = img.transpose(Image.FLIP_LEFT_RIGHT) label = label.transpose(Image.FLIP_LEFT_RIGHT) return img, label ``` ##### 类别重编码 由于原始类别编号可能不连续或者存在冗余情况,所以在正式投入训练前还需要完成一次统一化的再编码过程。具体做法是遍历所有可能出现过的颜色组合,并赋予新的整数值作为最终识别目标。 ```python import numpy as np def encode_labels(mask): mapping = { tuple([0, 0, 0]): 0, # Add more mappings here... } mask = np.array(mask).astype(np.int32) new_mask = np.zeros_like(mask[:, :, 0]) for k, v in mapping.items(): target_area = ((mask[:,:,0]==k[0]) & (mask[:,:,1]==k[1]) & (mask[:,:,2]==k[2])) new_mask[target_area] = int(v) return new_mask ``` #### 创建自定义Dataset类 最后,基于上述准备工作,可以构建一个继承自`torch.utils.data.Dataset`的新类——比如命名为`VOCSegDataset`——从而方便地管理整个流程以及与其他组件集成在一起工作。 ```python from torch.utils.data import Dataset class VOCSegDataset(Dataset): def __init__(self, is_train, crop_size=(320, 480), voc_dir='./data/VOCdevkit/VOC2012'): super().__init__() self.transform = transform self.crop_size = crop_size self.is_train = is_train ... def __getitem__(self, idx): img_path = ... # Get path of an image according to index. lbl_path = ... # Corresponding label file's location. with open(img_path, 'rb') as f: img = Image.open(f).convert('RGB') with open(lbl_path, 'rb') as f: lbl = Image.open(f).convert('RGB') if self.is_train: img, lbl = self.transform(RandomFlip()(img, lbl)) lbl = encode_labels(lbl) return img, lbl def __len__(self): return length_of_dataset ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值