数据集的整理和命名和格式转换

e智团队实验室项目-数据集的整理和命名和格式转换

赵雅玲 *, 张钊* ,赵尉* 

(淮北师范大学计算机科学与技术学院,淮北师范大学经济与管理学院,安徽 淮北)

*These authors contributed to the work equllly and should be regarded as co-first authors.

🌞欢迎来到深度学习的世界 
🌈博客主页:卿云阁

💌欢迎关注🎉点赞👍收藏⭐️留言📝

🌟本文由卿云阁原创!

🌠本阶段属于练气阶段,希望各位仙友顺利完成突破

📆首发时间:🌹2022年11月10日🌹

✉️希望可以和大家一起完成进阶之路!

🙏作者水平很有限,如果发现错误,请留言轰炸哦!万分感谢!


目录

🍈 数据集的划分

 🍉命名

🍻格式的转换

🍈 数据集的划分

      对机器学习和深度学习而言,都需要进行训练集和测试集的划分,在运行一些目标检测算法的时候,经常需要手写代码进行划分,这里为大家整理好了一份代码。

# 将图片和标注数据按比例切分为 训练集和测试集
import shutil
import random
import os

# 原始路径
image_original_path = 'D:\sraffic_news\images/'
label_original_path = 'D:\sraffic_news\labels/'
# 训练集路径
train_image_path = 'D:\sraffic_news\ train\images/'
train_label_path = 'D:\sraffic_news\ train\labels/'
# 验证集路径
val_image_path = 'D:\sraffic_news\ val\images/'
val_label_path = 'D:\sraffic_news\ val\labels/'
# 测试集路径
test_image_path = 'D:\sraffic_news\ test\images/'
test_label_path = 'D:\sraffic_news\ test\labels/'

# 数据集划分比例,训练集75%,验证集15%,测试集15%
train_percent = 0.8
val_percent = 0.1
test_percent = 0.1


# 检查文件夹是否存在
def mkdir():
    if not os.path.exists(train_image_path):
        os.makedirs(train_image_path)
    if not os.path.exists(train_label_path):
        os.makedirs(train_label_path)

    if not os.path.exists(val_image_path):
        os.makedirs(val_image_path)
    if not os.path.exists(val_label_path):
        os.makedirs(val_label_path)

    if not os.path.exists(test_image_path):
        os.makedirs(test_image_path)
    if not os.path.exists(test_label_path):
        os.makedirs(test_label_path)


def main():
    mkdir()

    total_txt = os.listdir(label_original_path)
    num_txt = len(total_txt)
    list_all_txt = range(num_txt)  # 范围 range(0, num)

    num_train = int(num_txt * train_percent)
    num_val = int(num_txt * val_percent)
    num_test = num_txt - num_train - num_val

    train = random.sample(list_all_txt, num_train)
    # train从list_all_txt取出num_train个元素
    # 所以list_all_txt列表只剩下了这些元素:val_test
    val_test = [i for i in list_all_txt if not i in train]
    # 再从val_test取出num_val个元素,val_test剩下的元素就是test
    val = random.sample(val_test, num_val)
    # 检查两个列表元素是否有重合的元素
    # set_c = set(val_test) & set(val)
    # list_c = list(set_c)
    # print(list_c)
    # print(len(list_c))

    print("训练集数目:{}, 验证集数目:{},测试集数目:{}".format(len(train), len(val), len(val_test) - len(val)))
    for i in list_all_txt:
        name = total_txt[i][:-4]

        srcImage = image_original_path + name + '.jpg'
        srcLabel = label_original_path + name + '.txt'

        if i in train:
            dst_train_Image = train_image_path + name + '.jpg'
            dst_train_Label = train_label_path + name + '.txt'
            shutil.copyfile(srcImage, dst_train_Image)
            shutil.copyfile(srcLabel, dst_train_Label)
        elif i in val:
            dst_val_Image = val_image_path + name + '.jpg'
            dst_val_Label = val_label_path + name + '.txt'
            shutil.copyfile(srcImage, dst_val_Image)
            shutil.copyfile(srcLabel, dst_val_Label)
        else:
            dst_test_Image = test_image_path + name + '.jpg'
            dst_test_Label = test_label_path + name + '.txt'
            shutil.copyfile(srcImage, dst_test_Image)
            shutil.copyfile(srcLabel, dst_test_Label)


if __name__ == '__main__':
    main()

 🍉命名

      首先,大家第一时间想到的肯定是在文件夹中Ctrl+A全选,接着,右键选择重命名,或者是下载一个图片处理工具,但是前者却会出现下图的问题,命名后会出现烦人的“()”,不符合要求;而后者,先不说下载耽误时间,如果对于处理大量图片命名的工程是极其慢的(本人曾尝试过),因为当你下载好软件后,你要将所有图片一一上传至该软件,之后再一张一张的命名和保存(该过程是无法操作的,只能苦苦等待),整个过程下来已经超过了截止时间了。接下来我来介绍一种可以超快速给大量图片批量名的方法,请小伙伴们认真学习。

操作步骤:

打开文件夹,点击右上角箭头,接着Ctrl+A全选图片,

点击左上角的“复制路径”(就是复制了所有图片的地址),打开Excel表格,将其粘贴到表格中;

之后手动提取图片的后缀名称“绿灯(1).jpg”到第二列,然后按下Ctrl+E批量提取;

然后再第三列输入你想要替换的图片名;

接下来将代码(="ren """&B2&""" "&C2)输入到第四列后,按回车,双击右下角填充代码,如下图,代码中的B2、C2分别是被替换名和替换名,可以根据需要随意调整,其中“ren”是rename的简写,

该代码的公式为:ren+空格+旧图片名+空格+新文件名;

 

然后复制所有的代码,在图片文件夹中新建一个txt文档,把代码粘贴进去,保存文本文档;

将编码改为ANSl,再将文件名后缀改为“.BAT”,然后保存后,运行生成的.BAT文件,然后图片的批量修改就完成了!


🍻格式的转换

    对于目标检测算法,一共有两种形式的标签。一种是txt格式,一种是xml格式。

txt与xml格式的转换

from xml.dom.minidom import Document
import os
import cv2


# def makexml(txtPath, xmlPath, picPath):  # txt所在文件夹路径,xml文件保存路径,图片所在文件夹路径
def makexml(picPath, txtPath, xmlPath):  # txt所在文件夹路径,xml文件保存路径,图片所在文件夹路径
    """此函数用于将yolo格式txt标注文件转换为voc格式xml标注文件
    在自己的标注图片文件夹下建三个子文件夹,分别命名为picture、txt、xml
    """
    dic = {'0': "green",  # 创建字典用来对类型进行转换
           '1': "red",  # 此处的字典要与自己的classes.txt文件中的类对应,且顺序要一致
           }
    files = os.listdir(txtPath)
    for i, name in enumerate(files):
        xmlBuilder = Document()
        annotation = xmlBuilder.createElement("annotation")  # 创建annotation标签
        xmlBuilder.appendChild(annotation)
        txtFile = open(txtPath + name)
        txtList = txtFile.readlines()
        img = cv2.imread(picPath + name[0:-4] + ".jpg")
        Pheight, Pwidth, Pdepth = img.shape

        folder = xmlBuilder.createElement("folder")  # folder标签
        foldercontent = xmlBuilder.createTextNode("driving_annotation_dataset")
        folder.appendChild(foldercontent)
        annotation.appendChild(folder)  # folder标签结束

        filename = xmlBuilder.createElement("filename")  # filename标签
        filenamecontent = xmlBuilder.createTextNode(name[0:-4] + ".jpg")
        filename.appendChild(filenamecontent)
        annotation.appendChild(filename)  # filename标签结束

        size = xmlBuilder.createElement("size")  # size标签
        width = xmlBuilder.createElement("width")  # size子标签width
        widthcontent = xmlBuilder.createTextNode(str(Pwidth))
        width.appendChild(widthcontent)
        size.appendChild(width)  # size子标签width结束

        height = xmlBuilder.createElement("height")  # size子标签height
        heightcontent = xmlBuilder.createTextNode(str(Pheight))
        height.appendChild(heightcontent)
        size.appendChild(height)  # size子标签height结束

        depth = xmlBuilder.createElement("depth")  # size子标签depth
        depthcontent = xmlBuilder.createTextNode(str(Pdepth))
        depth.appendChild(depthcontent)
        size.appendChild(depth)  # size子标签depth结束

        annotation.appendChild(size)  # size标签结束

        for j in txtList:
            oneline = j.strip().split(" ")
            object = xmlBuilder.createElement("object")  # object 标签
            picname = xmlBuilder.createElement("name")  # name标签
            namecontent = xmlBuilder.createTextNode(dic[oneline[0]])
            picname.appendChild(namecontent)
            object.appendChild(picname)  # name标签结束

            pose = xmlBuilder.createElement("pose")  # pose标签
            posecontent = xmlBuilder.createTextNode("Unspecified")
            pose.appendChild(posecontent)
            object.appendChild(pose)  # pose标签结束

            truncated = xmlBuilder.createElement("truncated")  # truncated标签
            truncatedContent = xmlBuilder.createTextNode("0")
            truncated.appendChild(truncatedContent)
            object.appendChild(truncated)  # truncated标签结束

            difficult = xmlBuilder.createElement("difficult")  # difficult标签
            difficultcontent = xmlBuilder.createTextNode("0")
            difficult.appendChild(difficultcontent)
            object.appendChild(difficult)  # difficult标签结束

            bndbox = xmlBuilder.createElement("bndbox")  # bndbox标签
            xmin = xmlBuilder.createElement("xmin")  # xmin标签
            mathData = int(((float(oneline[1])) * Pwidth + 1) - (float(oneline[3])) * 0.5 * Pwidth)
            xminContent = xmlBuilder.createTextNode(str(mathData))
            xmin.appendChild(xminContent)
            bndbox.appendChild(xmin)  # xmin标签结束

            ymin = xmlBuilder.createElement("ymin")  # ymin标签
            mathData = int(((float(oneline[2])) * Pheight + 1) - (float(oneline[4])) * 0.5 * Pheight)
            yminContent = xmlBuilder.createTextNode(str(mathData))
            ymin.appendChild(yminContent)
            bndbox.appendChild(ymin)  # ymin标签结束

            xmax = xmlBuilder.createElement("xmax")  # xmax标签
            mathData = int(((float(oneline[1])) * Pwidth + 1) + (float(oneline[3])) * 0.5 * Pwidth)
            xmaxContent = xmlBuilder.createTextNode(str(mathData))
            xmax.appendChild(xmaxContent)
            bndbox.appendChild(xmax)  # xmax标签结束

            ymax = xmlBuilder.createElement("ymax")  # ymax标签
            mathData = int(((float(oneline[2])) * Pheight + 1) + (float(oneline[4])) * 0.5 * Pheight)
            ymaxContent = xmlBuilder.createTextNode(str(mathData))
            ymax.appendChild(ymaxContent)
            bndbox.appendChild(ymax)  # ymax标签结束

            object.appendChild(bndbox)  # bndbox标签结束

            annotation.appendChild(object)  # object标签结束

        f = open(xmlPath + name[0:-4] + ".xml", 'w')
        xmlBuilder.writexml(f, indent='\t', newl='\n', addindent='\t', encoding='utf-8')
        f.close()


if __name__ == "__main__":
    picPath = "D:\VOCdevkit/VOC2007/JPEGImages/"  # 图片所在文件夹路径,后面的/一定要带上
    txtPath = "D:\VOCdevkit/VOC2007/YOLO/"  # txt所在文件夹路径,后面的/一定要带上
    xmlPath = "D:\VOCdevkit/VOC2007/Annotations/"  # xml文件保存路径,后面的/一定要带上
    makexml(picPath, txtPath, xmlPath)

xml与txt格式的转换

import xml.etree.ElementTree as ET

import pickle
import os
from os import listdir, getcwd
from os.path import join
import glob

classes = ["green", "red"]


def convert(size, box):
    dw = 1.0 / size[0]
    dh = 1.0 / size[1]
    x = (box[0] + box[1]) / 2.0
    y = (box[2] + box[3]) / 2.0
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return (x, y, w, h)


def convert_annotation(image_name):
    in_file = open('./datasets/Annotations/outputs/' + image_name[:-3] + 'xml')  # xml文件路径
    out_file = open('./datasets/ImageSets/' + image_name[:-3] + 'txt', 'w')  # 转换后的txt文件存放路径
    f = open('./datasets/Annotations/outputs/' + image_name[:-3] + 'xml')
    xml_text = f.read()
    root = ET.fromstring(xml_text)
    f.close()
    size = root.find('size')
    w = int(size.find('width').text)
    h = int(size.find('height').text)

    for obj in root.iter('object'):
        cls = obj.find('name').text
        if cls not in classes:
            print(cls)
            continue
        cls_id = classes.index(cls)
        xmlbox = obj.find('bndbox')
        b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
             float(xmlbox.find('ymax').text))
        bb = convert((w, h), b)
        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')


wd = getcwd()

if __name__ == '__main__':

    for image_path in glob.glob("./datasets/images/*.jpg"):  # 每一张图片都对应一个xml文件这里写xml对应的图片的路径
        image_name = image_path.split('\\')[-1]
        convert_annotation(image_name)

Institutional Review Board Statement: Not applicable.

Informed Consent Statement: Not applicable.

Data Availability Statement: Not applicable.

Author Contributions:All authors participated in the assisting performance study and approved the paper.

Conflicts of Interest: The authors declare no conflict of interes

以下是使用 PyTorch 对时序数据集进行滑动窗口划分,并按照比例划分为训练集、验证集和测试集的代码示例: ```python import torch from torch.utils.data import DataLoader, Dataset import numpy as np class SlidingWindowDataset(Dataset): def __init__(self, data, window_size): self.data = data self.window_size = window_size def __len__(self): return len(self.data) - self.window_size + 1 def __getitem__(self, idx): return self.data[idx:idx+self.window_size] # 读取时序数据集 dataset = np.loadtxt('data.csv', delimiter=',') # 定义滑动窗口大小和步长 window_size = 10 step_size = 1 # 使用滑动窗口划分法整理数据集 data = [] for i in range(0, len(dataset)-window_size+1, step_size): window = dataset[i:i+window_size] data.append(window) data = np.array(data) # 划分训练集、验证集和测试集 train_ratio = 0.7 val_ratio = 0.2 test_ratio = 0.1 num_samples = len(data) num_train_samples = int(num_samples * train_ratio) num_val_samples = int(num_samples * val_ratio) num_test_samples = num_samples - num_train_samples - num_val_samples train_data = data[:num_train_samples] val_data = data[num_train_samples:num_train_samples+num_val_samples] test_data = data[num_train_samples+num_val_samples:] train_dataset = SlidingWindowDataset(train_data, window_size) val_dataset = SlidingWindowDataset(val_data, window_size) test_dataset = SlidingWindowDataset(test_data, window_size) train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) val_loader = DataLoader(val_dataset, batch_size=32, shuffle=False) test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False) ``` 在这个示例中,我们首先读取时序数据集,然后使用滑动窗口划分法整理数据集,得到一组滑动窗口。然后,我们按照比例划分为训练集、验证集和测试集,并使用 PyTorch 中的 `SlidingWindowDataset` 类将数据集转换为 PyTorch Dataset 对象。最后,我们使用 PyTorch 中的 DataLoader 类将数据集转换为可迭代的数据加载器,并设置每个批次的大小、是否打乱数据顺序等参数。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卿云阁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值