三、如何搞自定义数据集?


前言

MNIST数据这个最最基础的数据集已经被走在程序猿道路上的同学们玩坏了,所以今天教大家如何搞一个自定义数据集。


一、定义的数据集,未做预处理。

下面展示一些 内联代码片

import  os
from  torch.utils.data import  Dataset ,DataLoader
from PIL import Image

#1.创建数据集类,使用torch.utils.data中的Dataset方法。
class My_Dataset(Dataset):

    #2.循环找到文件路径,并添加标签
    def __init__(self,main_dir,data_type,transforms):
        self.dataset=[]#空列表为装新增一个标签的数据库
        self.transforms=transforms
        if data_type==0:
            data_filename='train'
        elif data_type is 1:
            data_filename='val'
        else:
            data_filename='test'
        for i , cls_filename in enumerate(
        os.listdir(os.path.join(main_dir,data_filename))):
            for i ,img_data in enumerate(os.listdir(
            os.path.join(main_dir,data_filename,cls_filename))):
                self.dataset.append([os.path.join(main_dir,
                data_filename,cls_filename,img_data),int(img_data[0]) ])

    #3.计算图片长度,方便后面迭代
    def __len__(self):
        return len(self.dataset)#为了获取图片长度,方便迭代

    #4、取出图片路径,并打开,便于做数据预处理
    def __getitem__(self, index):
        img,label=self.dataset[index]
        img_data=Image.open(img)
        img_data=self.transforms(img_data)
        return img_data,label

示例:@TOC

二、定义数据集,并做数据预处理。

包括旋转、裁剪、转为张量、扩大、正则化等等。

1.预处理部分

#4、取出图片路径,并打开,便于做数据预处理
def __getitem__(self, index):
    img,label=self.dataset[index]
    img_data=self.data_process(Image.open(img))
    return img_data,label

#5.数据处理,数据增强、加噪声等等
def data_process(self,x):
    return transforms.Compose([transforms.ToTensor(),
    transforms.Normalize(mean=(0.5,),std=(0.5,))])(x)

2.定义数据过程

代码如下(示例):

import  os
from  torchvision import transforms
from  torch.utils.data import  Dataset ,DataLoader
from PIL import Image

#1.创建数据集类,使用torch.utils.data中的Dataset方法。
class My_Dataset(Dataset):

    #2.循环找到文件路径,并添加标签
    def __init__(self,main_dir,data_type):
        self.dataset=[]#空列表为装新增一个标签的数据库
        if data_type==0:
            data_filename='train'
        elif data_type is 1:
            data_filename='val'
        else:
            data_filename='test'
        for i , cls_filename in enumerate(
        os.listdir(os.path.join(main_dir,data_filename))):
            for i ,img_data in enumerate(os.listdir(
            os.path.join(main_dir,data_filename,cls_filename))):
                self.dataset.append([os.path.join(main_dir,
                data_filename,cls_filename,img_data),i ])

    #3.计算图片长度,方便后面迭代
    def __len__(self):
        return len(self.dataset)#为了获取图片长度,方便迭代

    #4、取出图片路径,并打开,便于做数据预处理
    def __getitem__(self, index):
        img,label=self.dataset[index]
        img_data=self.data_process(Image.open(img))
        return img_data,label

    #5.数据处理,数据增强、加噪声等等
    def data_process(self,x):
        return transforms.Compose([transforms.ToTensor(),
        transforms.Normalize(mean=(0.5,),std=(0.5,))])(x)
``
<think>嗯,用户问关于Pascal VOC数据集的标签图片为什么是彩色8位的,255像素值作为背景是黑色,以及如何制作类似的数据集。首先,我需要回顾一下Pascal VOC数据集的结构和标签格式。记得Pascal VOC的语义分割标签是单通道的PNG图像,每个像素的值对应类别索引,比如0是背景,1是飞机,等等。但用户提到标签是彩色的8位,这可能需要进一步解释。 首先,为什么是彩色8位的?可能用户有误解,或者实际标签虽然是单通道,但用彩色显示是为了可视化。比如,当用图像查看软件打开时,伪彩色显示可能会让不同的类别用不同颜色表示。不过Pascal VOC的标签文件通常是单通道的,每个像素的数值代表类别索引,而不是直接存储颜色信息。但可能保存为8位色深的图像,每个像素用8位(0-255)来存储类别,这样最多支持256个类别,而Pascal VOC通常只有20类,所以足够用。 接下来,为什么255作为背景是黑色?通常,在单通道图像中,0代表黑色,255是白色。但这里可能用户观察到的是,在标签图像中,背景部分的像素值为255,显示为黑色。这似乎有矛盾。需要确认:可能用户反了?或者Pascal VOC的标签中背景确实是0?比如,VOC的类别索引中,背景通常是0,而其他类别从1开始。例如,在官方数据集中,像素值0对应背景,显示时可能被映射为黑色。但用户提到255是背景,这可能与实际不符,或者存在特殊情况? 需要核实Pascal VOC标签的具体格式。查阅资料发现,Pascal VOC分割标签确实是单通道的PNG,像素值0表示背景,1-20对应20个物体类别,而255可能被用作忽略区域(如边界或难例)。但可能用户看到的是某些特定处理后的显示方式,比如在可视化时,将类别0显示为黑色,而255可能被处理成某种颜色?或者用户可能混淆了索引值和调色板的应用? 例如,PNG图像可能带有调色板(即索引颜色),每个索引对应一个颜色。在Pascal VOC中,可能调色板中的0索引对应背景(黑色),而其他索引对应不同的颜色。但实际存储的像素值可能还是0到20,而255可能被保留为忽略区域。例如,在官方数据集中,分割的像素值范围包括0(背景)、1-20(物体类别),以及255(忽略)。所以当像素值为255时,可能在可视化时显示为特定的颜色,比如黑色或者另一种颜色,具体取决于调色板的设置。 因此,用户提到的“255作为背景是黑色”可能存在误解。正确的解释应该是,在Pascal VOC数据集中,背景的像素值是0,而255可能被用作忽略区域,显示时可能被渲染为黑色或其他颜色,具体取决于调色板的配置。 接下来,用户如何制作类似的标签数据集?步骤可能包括:确定类别和索引,创建单通道图像,处理忽略区域,保存为PNG格式,可能应用调色板以便可视化。需要详细说明每个步骤,比如在标注时使用工具如LabelMe,然后转换为单通道的索引图像,确保像素值对应正确的类别索引,保存时使用8位深度,并可能附加调色板信息以便正确显示颜色。 总结,回答需要纠正用户可能的误解,解释实际Pascal VOC标签的结构,说明8位的原因,澄清背景和255像素的作用,并给出制作数据集的具体步骤。</think>### 一、Pascal VOC标签格式的原理 1. **彩色8位的本质** Pascal VOC标签图片本质是**单通道8位灰度图**(非真彩色),每个像素值(0-255)对应一个类别索引。 - 0-20:保留给21个类别(背景+20个物体类别) - 255:特殊标记,表示**忽略区域**(如物体边界或难分割区域) - 实际显示的“彩色”是通过**预定义调色板(PALETTE)**映射实现的视觉效果。 2. **黑色背景的误解** 像素值0对应背景类别,在调色板中通常映射为黑色。而像素值255在调色板中可能被映射为黑色或特定颜色(取决于工具),但**核心逻辑是:0=背景,255=忽略**。 --- ### 二、制作类似标签数据集的步骤 #### 步骤1:定义类别与索引 ```python classes = ["background", "aeroplane", "bicycle", ..., "person"] # 共21类 class_to_idx = {name: i for i, name in enumerate(classes)} ``` #### 步骤2:标注工具选择 - **LabelMe**:标注多边形后,需将JSON转换为索引图 - **CVAT**:直接支持导出Pascal VOC格式 - **自定义工具**:生成单通道PNG,像素值=类别索引 #### 步骤3:生成索引图 ```python import numpy as np # 假设标注掩码为HxW矩阵,值为类别索引(0-20) mask = np.zeros((height, width), dtype=np.uint8) mask[obj1_area] = 1 # 自行车=1 mask[obj2_area] = 15 # 人=15 mask[uncertain_area] = 255 # 忽略区域 ``` #### 步骤4:保存为PNG ```python from PIL import Image Image.fromarray(mask).save("label.png", format="PNG", mode="P", palette=palette) ``` 需附加调色板(Pascal VOC官方调色板)以实现可视化彩色效果。 --- ### 、关键注意事项 1. **文件格式** - 必须使用**无损压缩的PNG**(8位单通道+调色板) - 禁止使用JPG(有损压缩会破坏索引值) 2. **调色板绑定** 通过`PIL.ImagePalette`加载VOC官方调色板: ```python # Pascal VOC标准调色板(21类+255) palette = [...] ``` 3. **数据校验** 用以下代码验证标签合法性: ```python unique_vals = np.unique(mask) assert set(unique_vals).issubset({0,1,...,20,255}) ``` --- ### 四、可视化效果对比 | 原始索引图(单通道) | 应用调色板后(伪彩色) | |----------------------|------------------------| | 像素值=0(背景) | 显示为黑色 | | 像素值=15(人) | 显示为粉色 | | 像素值=255 | 显示为深灰/忽略边界 | 通过这种方式,既保证存储效率(单通道8位),又能通过调色板实现直观的可视化效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值