文章目录
一、简介
本文主要是自己近期在做毕业设计(连续手语识别)时候写的几个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" )