一、简介 本文主要是自己近期在做毕业设计(连续手语识别)时候写的几个python脚本,用于处理数据集的。记录一下。
二、 重点 本文撰写采用Windows操作系统,如果是Linux记得修改字符串分割方式及目录层数多加一层。
1. 数据集划分训练集与测试集 1.1 数据集为视频帧文件夹(文件夹划分) trainNum 参数是划分训练集的视频数,即文件夹数,我的划分是9:1,总数是250个视频,那这里就写225。 dirLongNum 参数为你当前原数据集最深的目录层数 举个例子: F:\data 是我视频帧数据集
000020是我的一个视频类,里面的事每个视频抽帧后的文件夹,要截止到最后一个文件夹
def splitTrainAndTestOnDir(rootFileDir, dstDir, trainNum, dirLongNum): # dirLongNum目录结构最长多少 root_dir = os.walk(rootFileDir) # 训练集、测试集的路径,脚本测试用 # root_train_dir = "F:/pytest/datat/train/" root_train_dir = dstDir + "/train/" # root_test_dir = "F:/pytest/datat/test/" root_test_dir = dstDir + "/test/" # 记录训练集个数 trainFileCount = 0 # 记录当前某类文件夹名 lastFileDirName = ""
# 开始遍历 for root, dirs, files in root_dir: # 组合目录名 nameFile = os.path.join(root) # 拆分成数组 注意修改 nameArr = nameFile.split("\\") # 判定,根据文件夹目录关系:F:\newdata2\000000\P01_s1_00_0_color,判定 类 目录是否更换,即是否到了新的一类,如果到了,清零计数 if lastFileDirName != str(nameArr[-2]): trainFileCount = 0 # 重新赋值 lastFileDirName = str(nameArr[-2]) print(nameArr) # 训练集的数量 if trainFileCount < trainNum: # 移动一次,加一 trainFileCount = trainFileCount + 1 # 定义训练集路径 dstTrainPath = root_train_dir + str(nameArr[-2]) + "/" + str(nameArr[-1]) # 由于遍历时候只需要带有类别和类别内的文件夹两层,根据当前路径得到了len(nameArr)==5时候是拆分后的全路径,然后进行文件夹复制,即将000000\某一个文件夹移动到新的目录下 if len(nameArr) == dirLongNum: shutil.copytree(nameFile, dstTrainPath) else: # 类似于train,将类内剩余部分划分为测试集 dstTestPath = root_test_dir + str(nameArr[-2]) + "/" + str(nameArr[-1]) shutil.copytree(nameFile, dstTestPath)
不明白的部分可以保留住print(nameArr),后面的注释看一下
1.2 数据集为视频文件(文件划分) 这次是记录文件数
def splitTrainAndTest(rootFileDir, dstDir, trainNum): #, trainDir, testDir root_dir = os.walk(rootFileDir) # root_train_dir = "F:/pytest/datat/train/" root_train_dir = dstDir + "/train/" # root_test_dir = "F:/pytest/datat/test/" root_test_dir = dstDir + "/test/" trainFileCount = 0 lastFileDirName = "" for root, dirs, files in root_dir: for f in files: nameFile = os.path.join(root, f) print(nameFile) nameArr = nameFile.split("\\") if lastFileDirName != str(nameArr[-2]): trainFileCount = 0 lastFileDirName = str(nameArr[-2]) print(nameArr) if trainFileCount < trainNum: trainFileCount = trainFileCount + 1 dstTrainPath = root_train_dir + str(nameArr[-2]) + "/" + str(nameArr[-1]) creatDir(root_train_dir + str(nameArr[-2])) print(dstTrainPath) shutil.copy(nameFile, dstTrainPath) else: dstTestPath = root_test_dir + str(nameArr[-2]) + "/" + str(nameArr[-1]) creatDir(root_test_dir + str(nameArr[-2])) shutil.copy(nameFile, dstTestPath)
2. label的重建 由于提供的数据集label不能直接使用,有所变化,转化成tsn的输入形式。这里学习着写了一下文件的读取与生成,思路来自于LeetCode的一到题,没事多刷刷算法能给自己提供更多的思路方法。
2.1 原label读取 采用字典去存取,因为后边会需要,一个类有多个视频,我得通过类文件夹去更新label,而不是计数的形式
def getLabelDict(labelFile): f = codecs.open(labelFile, mode='r', encoding='utf-8') # 打开txt文件,以‘utf-8’编码读取 line = f.readline() # 以行的形式进行读取文件 list1 = [] dict1 = {} while line: print(line) a = line.split() b = a[0:1] # 这是选取需要读取的位数 c = a[1:2] dict1[str(b[0])] = str(c[0]) list1.append(b) # 将其添加在列表之中 line = f.readline() f.close() return dict1
2.2 新label的建立 其中len(nameArr)的长度根据实际情况判定,这个只读取到类文件夹下的视频帧文件夹长度即可,满足长度的打标签,否则从root层就开始打label。
def listfiles(rootDir,txtfile,dict1): ftxtfile = open(txtfile, 'w', encoding='utf-8') list_dirs = os.walk(rootDir) count = 0 fixNum = [] for root, dirs, files in list_dirs: for f in files: nameFile = os.path.join(root, f) fixNum.append(nameFile) name = os.path.join(root) # print(os.path.join(root)) # print(os.path.join(root,f)) nameArr = name.split("\\") print(nameArr) label = "" try: # print(dict1[str(nameArr[4])]) if len(nameArr) == 4 : # label = str(dict1[str(nameArr[4])]) # print(label) txtString = os.path.join(root) + ' ' + str(len(fixNum)) + ' ' + str(dict1[str(nameArr[2])]) + '\n' print(txtString) ftxtfile.write(txtString) except: label = '1' fixNum = [] count = count + 1 #print rootDir+"has"+str(count)+"files" print( rootDir+"has "+str(count)+" files" ) ————————————————
原文链接:「吉吉有梦想」https://blog.csdn.net/qq_42009978/article/details/106117002
|