划分后的路径如下(YOLO格式):
-------**/DataSet
| |-----train
|-----images-----|-----val
| |-----test
|
| |-----train
|-----labels-----|-----val
|-----test
一,导入所需库
import splitfolders
import os
import shutil # 文件移动所需的库
二,设置路径
图片所在原始路径,切分后训练集,验证集,测试集三个文件夹所在路径。此处根据所需改动
标签所在原路径,测试集路径,验证集路径
input_path = "D:\\Pycharm\\pythonProject1\\SOTP\\images" ##原始数据集所在文件夹路径,使用时必须要修改
file_name = "train" #原始数据集所在文件夹名
filepath = input_path + '\\' + file_name ##原始数据集路径,使用时必须要修改
output_path = "D:\\Pycharm\\pythonProject1\\SOTP\\images" ##划分后的训练集,验证集,测试集输出路径
label_path = "D:\\Pycharm\\pythonProject1\\SOTP\\labels\\train" ##标签文件所在文件夹
vallabel_patn = "D:\\Pycharm\\pythonProject1\\SOTP\\labels\\val" #验证标签所在文件夹
testlabel_path = "D:\\Pycharm\\pythonProject1\\SOTP\\labels\\test" #测试标签所在文件夹
三,将原始数据集文件按ratio中的比例切分train:val:test
输入为数据集图片文件夹所在的文件夹input_path
splitfolders.ratio(input=input_path, output=output_path, seed=1234, ratio=(0.6, 0.2, 0.2)) ##切分按ratio比例
此时切分后图片训练集,验证集,测试集所在位置如下
**/SOTP
| |-----train-----train(原来图片所在文件夹名称)
|-----images-----|-----val-----train(原来图片所在文件夹名称)
|-----test-----train(原来图片所在文件夹名称)
四,删除原始图片,(只删除图片,不删除文件夹,需要指定后缀名)
##移除原始图片
def del_file(filepath):
files = os.listdir(filepath)
for file in files:
if '.' in file:
suffix = file.split('.')[-1]
# 指定删除jpg的后缀名文件
if suffix == 'jpg':
os.remove(os.path.join(filepath, file))
del_file(filepath)
五,移动文件到正确位置(将如上最高层train中的文件移动到上一层train,val,test目录)
##移动文件到正确位置
# 想要移动文件所在的目录
####此处不需修改
trainf =input_path + '\\' + 'train' + '\\' + file_name
valf =input_path + '\\' + 'val' + '\\' + file_name
testf =input_path + '\\' + 'test' + '\\' + file_name
######想要移动的目标路径
train_path = input_path + '\\' + 'train' # train目标路径
val_path = input_path + '\\' + 'val' # val目标路径
test_path = input_path + '\\' + 'test' # test目标路径
# 获取目录下文件名清单
files = os.listdir(trainf)
##train图像文件移动
for file in files:
if '.jpg' in file: # 因为索要移动的文件名均有‘_’,因此利用此判断其是否是所需要移动的文件
full_path = os.path.join(trainf, file) # 文件当前的完整的路径
shutil.move(full_path, train_path) # 移动文件到目标路径
# 获取目录下文件名清单
files = os.listdir(valf)
##val图像文件移动
for file in files:
if '.jpg' in file: # 因为索要移动的文件名均有‘_’,因此利用此判断其是否是所需要移动的文件
full_path = os.path.join(valf, file) # 完整的路径
shutil.move(full_path, val_path) # 移动文件到目标路径
# 获取目录下文件名清单
files = os.listdir(testf)
##test图像文件移动
for file in files:
if '.jpg' in file: # 因为索要移动的文件名均有‘_’,因此利用此判断其是否是所需要移动的文件
full_path = os.path.join(testf, file) # 完整的路径
shutil.move(full_path, test_path) # 移动文件到目标路径
##删除文件夹
shutil.rmtree(trainf)
shutil.rmtree(valf)
shutil.rmtree(testf)
此时移动后图片训练集,验证集,测试集所在位置如下
**/SOTP
| |-----train
|-----images-----|-----val
|-----test
五,将标签数据根据图片的划分,划分为对应的训练集,验证集,测试集
主要采用的思想:获取测试集中图片名(去掉后缀的)存放在val_name列表中,获取测试集中图片名存放在test_name列表中,获取存放标签文件名的二维列表labelfilename(name和后缀分开了);然后判断labelfilename中文件名在val_name和test_name中的文件分别存放在val和test文件中。
获取测试集图片名列表val_name,和测试集图片列表test_name。
os.chdir(val_path) # 设置验证图片文件夹所在的位置
filename = os.listdir(".")
val_name = [] ##存放验证集图片名列表
for i in filename:
portion = os.path.splitext(i) # 把文件名拆分为名字和后缀
val_name.append(portion[0])
os.chdir(test_path) # 设置测试图片文件夹所在的位置
filename = os.listdir(".")
test_name = [] ##存放测试集图片名列表
for i in filename:
portion = os.path.splitext(i) # 把文件名拆分为名字和后缀
test_name.append(portion[0])
del filename ##释放内存
gc.collect() ##del后内存不会立马释放,加上这一句后内存立马就释放了
判断labelfilename中的文件名在val_name和test_name中的文件分别存放在val和test文件中。
os.chdir(label_path) ##设置标签所在文件夹位置
labelfilenames = os.listdir(".")
os.mkdir(vallabel_patn) ##创建val标签文件夹
os.mkdir(testlabel_path) ##创建test标签文件夹
for i in labelfilenames:
portion = os.path.splitext(i)
if portion[0] in val_name:
txt_path = os.path.join(label_path, i) # 文件当前的完整的路径
shutil.move(txt_path, vallabel_patn) # 移动label文件到验证集标签文件夹
elif portion[0] in test_name:
txt_path = os.path.join(label_path, i) # 文件当前的完整的路径
shutil.move(txt_path, testlabel_path) # 移动文件到目标路径
else:
continue
此时切分好的数据如下:
-------**/SOTP
| |-----train
|-----images-----|-----val
| |-----test
|
| |-----train
|-----labels-----|-----val
|-----test
完整代码如下:
import splitfolders
import os
import shutil # 文件移动所需的库
import gc
###################设置相应的路径########################
##此处数据为每次使用需要修改的内容,如输出结构相同(YOLO格式),仅需修改该处路径内容仅可
input_path = "D:\\Pycharm\\pythonProject1\\SOTP\\images" ##原始数据集所在文件夹路径,使用时必须要修改
file_name = "train" #原始数据集所在文件夹名
filepath = input_path + '\\' + file_name
output_path = "D:\\Pycharm\\pythonProject1\\SOTP\\images" ##划分后的训练集,验证集,测试集输出路径
label_path = "D:\\Pycharm\\pythonProject1\\SOTP\\labels\\train" ##标签文件所在文件夹
vallabel_patn = "D:\\Pycharm\\pythonProject1\\SOTP\\labels\\val" #验证标签所在文件夹
testlabel_path = "D:\\Pycharm\\pythonProject1\\SOTP\\labels\\test" #测试标签所在文件夹
###############将图片划分为训练集,验证集,数据集####################
splitfolders.ratio(input=input_path, output=output_path, seed=1234, ratio=(0.6, 0.2, 0.2)) ##切分按ratio比例
##移除原始图片
def del_file(filepath):
files = os.listdir(filepath)
for file in files:
if '.' in file:
suffix = file.split('.')[-1]
# 指定删除jpg的后缀名文件
if suffix == 'jpg':
os.remove(os.path.join(filepath, file))
del_file(filepath)
##移动文件到正确位置
# 想要移动文件所在的目录
####此处不需修改
trainf =input_path + '\\' + 'train' + '\\' + file_name
valf =input_path + '\\' + 'val' + '\\' + file_name
testf =input_path + '\\' + 'test' + '\\' + file_name
######想要移动的目标路径
train_path = input_path + '\\' + 'train' # train目标路径
val_path = input_path + '\\' + 'val' # val目标路径
test_path = input_path + '\\' + 'test' # test目标路径
# 获取目录下文件名清单
files = os.listdir(trainf)
##train图像文件移动
for file in files:
if '.jpg' in file: # 因为索要移动的文件名均有‘_’,因此利用此判断其是否是所需要移动的文件
full_path = os.path.join(trainf, file) # 文件当前的完整的路径
shutil.move(full_path, train_path) # 移动文件到目标路径
# 获取目录下文件名清单
files = os.listdir(valf)
##val图像文件移动
for file in files:
if '.jpg' in file: # 因为索要移动的文件名均有‘_’,因此利用此判断其是否是所需要移动的文件
full_path = os.path.join(valf, file) # 完整的路径
shutil.move(full_path, val_path) # 移动文件到目标路径
# 获取目录下文件名清单
files = os.listdir(testf)
##test图像文件移动
for file in files:
if '.jpg' in file: # 因为索要移动的文件名均有‘_’,因此利用此判断其是否是所需要移动的文件
full_path = os.path.join(testf, file) # 完整的路径
shutil.move(full_path, test_path) # 移动文件到目标路径
##删除文件夹
shutil.rmtree(trainf)
shutil.rmtree(valf)
shutil.rmtree(testf)
##########################将标签数据根据图片的划分,划分为对应的训练集,验证集,测试集###################
os.chdir(val_path) # 设置验证图片文件夹所在的位置
filename = os.listdir(".")
val_name = [] ##存放验证集图片名列表
for i in filename:
portion = os.path.splitext(i) # 把文件名拆分为名字和后缀
val_name.append(portion[0])
os.chdir(test_path) # 设置测试图片文件夹所在的位置
filename = os.listdir(".")
test_name = [] ##存放测试集图片名列表
for i in filename:
portion = os.path.splitext(i) # 把文件名拆分为名字和后缀
test_name.append(portion[0])
del filename ##释放内存
gc.collect() ##del后内存不会立马释放,加上这一句后内存立马就释放了
os.chdir(label_path) ##设置标签所在文件夹位置
labelfilenames = os.listdir(".")
os.mkdir(vallabel_patn) ##创建val标签文件夹
os.mkdir(testlabel_path) ##创建test标签文件夹
for i in labelfilenames:
portion = os.path.splitext(i)
if portion[0] in val_name:
txt_path = os.path.join(label_path, i) # 文件当前的完整的路径
shutil.move(txt_path, vallabel_patn) # 移动label文件到验证集标签文件夹
elif portion[0] in test_name:
txt_path = os.path.join(label_path, i) # 文件当前的完整的路径
shutil.move(txt_path, testlabel_path) # 移动文件到目标路径
else:
continue