计算机视觉技巧合集(一)如何读取数据集

计算机视觉技巧合集(一)如何读取数据集

在计算机视觉领域,数据的重要性不可忽视。数据是训练和提升视觉算法的关键基石,它们为计算机系统提供了对世界的认知能力。丰富、多样的数据集可以帮助计算机视觉模型学习视觉特征、识别对象和场景,并进行准确的预测。数据的质量和多样性直接影响了模型的性能和鲁棒性。因此,有效地获取、整理和利用数据是实现出色计算机视觉应用的关键要素。计算机视觉主要分为图像分类、目标检测和图像分割这3大类任务,任务不同,所使用的数据也不同,其读取方式也是不一样的。因此,本文将具体说明如何读取图像分类和目标检测任务的数据。

图像分类篇

图像分类任务使用的数据集一般都是按数据的类别名称进行划分的,将属于同一类别的数据放入同一文件夹中,因此,读取分类数据集,需要知道如何读写文件。

本文选取花分类数据集作为一个例子来演示如何读取分类数据集。首先,简单介绍以下什么是花分类数据集,花分类数据集包含5个类别,分别是雏菊(Daisy)、蒲公英(Dandelion)、玫瑰(Roses)、向日葵(Sunflowers)和郁金香(Tulips),共计3670张图像,下表展示了数据集中各个类别的图像数量情况:

类别雏菊(Daisy)蒲公英(Dandelion)玫瑰(Roses)向日葵(Sunflowers)郁金香(Tulips)
图像数量633898641699799

下图展示了数据集的格式:
在这里插入图片描述
可以看出数据集按类别名称划分数据,每一种类别都单独作为一个文件夹,包含全部属于该类别的图像。

花分类数据集的百度网盘链接:链接:https://pan.baidu.com/s/1fSoAmx4vDknd5Okj9GyTFQ 提取码:5flv

简单的读取数据集

以下是用Python实现的读取示例代码:

import os
import json
import random

def load_datset(root):
    # 保证随机结果可复现
    random.seed(0)
    # 检查路径是否正确
    assert os.path.exists(root), "dataset root: {} does not exist.".format(root)
    # 读取类别名称,一个文件夹对应一个类别
    img_class = [cla for cla in os.listdir(root) if os.path.isdir(os.path.join(root, cla))]
    # 类别名称按ASCII码顺序排序
    img_class.sort()
    # 生成类别名称以及对应的数字索引
    class_indices = dict((k, v) for v, k in enumerate(img_class))
    # 以{数字索引: 类别名称}的格式保存为json文件,用于将预测的分类索引转换成对应的类别名称
    json_str = json.dumps(dict((val, key) for key, val in class_indices.items()), indent=4)
    with open('class_indices.json', 'w') as json_file:
        json_file.write(json_str)

    # 生成图像路径列表和标签列表,用于制作dataset
    all_image_paths = []
    labels = []
    # 存储每个类别的样本数量
    every_class_nums = []
    # 支持的文件后缀类型。可以根据自己需要添加或删除
    supported = [".jpg", ".JPG", ".png", ".PNG"]
    for cla in img_class:
        cla_path = os.path.join(root, cla)
        # 获取该类别包含的全部图像样本路径
        image_paths = [os.path.join(root, cla, i) for i in os.listdir(cla_path) if os.path.splitext(i)[-1] in supported]
        # 获取该类别对应的索引
        image_index = class_indices[cla]
        # 记录该类别的样本数量
        every_class_nums.append(len(image_paths))
        for img_path in image_paths:
            all_image_paths.append(img_path)
            labels.append(image_index)

    # 打印数据集的总样本数量
    print("{} images were found in the dataset.".format(sum(every_class_nums)))

    return all_image_paths, labels

if __name__ == "__main__":
    root = r"G:\datasets\flower_photos"
    all_image_paths, labels = load_datset(root)

程序执行结果:

在这里插入图片描述

按照训练集,验证集和测试集的方式划分读取数据集

简单的读取数据集可以用于已经划分成train,val,test文件夹的数据集,对于没有划分的数据集,可以使用以下代码。

以下是用Python实现的读取示例代码:

import os
import json
import random

def read_split_three_data(root: str, train_val_rate: float = 0.8, train_rate: float = 0.8):
    # 保证随机结果可复现
    random.seed(0)
    # 检查路径是否正确
    assert os.path.exists(root), "dataset root: {} does not exist.".format(root)

    # 将划分好的train,val,test数据的存入文本文件
    split_dataset_path = r"./split_dataset"
    if os.path.exists(split_dataset_path) is False:
        os.makedirs(split_dataset_path)
    # 将训练,验证,测试数据信息保存成文本文件
    f_train = open(os.path.join(split_dataset_path, 'train.txt'), 'w')
    f_val = open(os.path.join(split_dataset_path, 'val.txt'), 'w')
    f_test = open(os.path.join(split_dataset_path, 'test.txt'), 'w')

    # 读取类别名称,一个文件夹对应一个类别
    img_class = [cla for cla in os.listdir(root) if os.path.isdir(os.path.join(root, cla))]
    # 类别名称排序
    img_class.sort()
    # 生成类别名称以及对应的数字索引
    class_indices = dict((k, v) for v, k in enumerate(img_class))
    # 以{数字索引: 类别名称}的格式保存为json文件,用于将预测的分类索引转换成对应的类别名称
    json_str = json.dumps(dict((val, key) for key, val in class_indices.items()), indent=4)
    with open('class_indices.json', 'w') as json_file:
        json_file.write(json_str)

    train_images_path = []  # 存储训练集的所有图片路径
    train_images_label = []  # 存储训练集图片对应索引信息
    val_images_path = []  # 存储验证集的所有图片路径
    val_images_label = []  # 存储验证集图片对应索引信息
    test_images_path = [] # 存储测试集的所有图片路径
    test_images_label = []  # 存储测试集图片对应索引信息
    every_class_nums = []  # 存储每个类别的样本总数
    supported = [".jpg", ".JPG", ".png", ".PNG"]  # 支持的文件后缀类型。可以根据自己需要添加或删除

    # 按每一个类别划分数据,分别放入训练集,验证集,测试集
    for cla in img_class:
        cla_path = os.path.join(root, cla)
        # 遍历获取supported支持的所有文件路径
        images = [os.path.join(root, cla, i) for i in os.listdir(cla_path)
                  if os.path.splitext(i)[-1] in supported]
        # 获取该类别对应的索引
        image_class = class_indices[cla]
        # 记录该类别的样本数量
        every_class_nums.append(len(images))

        # 先划分出训练验证集
        train_val_path = random.sample(images, k=int(len(images) * train_val_rate))
        # 不在训练验证集中的样本放入测试集
        for img_path in images:
            if img_path not in train_val_path:
                test_images_path.append(img_path)
                test_images_label.append(image_class)
                in_str = img_path + ", " + str(image_class)
                f_test.write(in_str + '\n')

        # 再划分出训练集,不在训练集的数据存入验证集中
        train_path = random.sample(train_val_path, int(len(train_val_path) * train_rate))
        for img_path in train_val_path:
            if img_path in train_path:
                train_images_path.append(img_path)
                train_images_label.append(image_class)
                train_str = img_path + ', ' + str(image_class)
                f_train.write(train_str + '\n')
            else:
                val_images_path.append(img_path)
                val_images_label.append(image_class)
                val_str = img_path + ', ' + str(image_class)
                f_val.write(val_str + '\n')

    f_train.close()
    f_val.close()
    f_test.close()

    print("{} images were found in the dataset.".format(sum(every_class_nums)))
    print("{} images for training.".format(len(train_images_path)))
    print("{} images for validation.".format(len(val_images_path)))
    print("{} images for test.".format(len(test_images_path)))
    print("train:val:test = {}:{}:{}".format(len(train_images_path)/sum(every_class_nums), len(val_images_path)/sum(every_class_nums), len(test_images_path)/sum(every_class_nums)))

    return train_images_path, train_images_label, val_images_path, val_images_label

if __name__ == "__main__":
    root = r"G:\datasets\flower_photos"
    # 训练集:验证集:测试集 = 6:2:2,那么train_val_rate = (6+2) / 1 = 0.8, train_rate = 6/(6+2) = 0.75
    train_images_path, train_images_label, val_images_path, val_images_label = read_split_three_data(root, train_val_rate=0.8, train_rate=0.75)

程序运行结果如下:
在这里插入图片描述
划分出来的文本文件:
在这里插入图片描述
训练集信息展示:
在这里插入图片描述

根据已有的文本文件读取数据集

创建好文本文件后,就可以保证不同模型做横向对比实验时使用完全相同的训练集、验证集和测试集,避免因为划分的不同是模型的精确度无法比较的情况发生。

以下是用Python实现的读取示例代码:

import os

def load_data(text):
    with open(text, 'r') as f:
        dataset = f.readlines()

    img_paths = []
    labels = []
    for data in dataset:
        data = data.split(', ')
        img_paths.append(data[0])
        labels.append(int(data[1]))

    return img_paths, labels

if __name__ == "__main__":
    root = r"./split_dataset/train.txt"
    # 通过已划分好的文本文件来读取数据
    img_paths, labels = load_data(root)
    print("{} imgs.".format(len(img_paths)))

程序运行结果如下:
在这里插入图片描述
目标检测篇待更新!!!

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值