一、通过labeling工具保存Voc数据
1.使用labeling编制图片主体
操作步骤如下:
*(注:简易操作流程,想更进一步了解labeling工具使用,请自行搜索教程)
2.检查保存Voc数据
操作成功,请在图片所属文件夹下核查下同名xml文件是否存在。(尽量保持图片与xml文件在同一目录及名称名称相对应,如:1.png --1.xml)
二、创建Train.txt,valid.txt
4.创建PaddleDetection要求文件夹
在dataset文件中创建自己训练数据文件夹“roadsign_voc”,并在“roadsign_voc”文件夹中创建“images”文件夹(将上一步图片和xml都拷贝至images文件夹),如下图:
5.执行create_list.py脚本
(1)拷贝create_list.py 至 roadsign_voc文件夹下
create_list.py 脚本源码在第三节,自行拷贝。下载地址
(2)在 roadsign_voc 目录下执行cmd 控制台
在地址栏中输入 cmd ,再按回车,即可弹出cmd控制台窗体,如下图:
(3)在控制台执行脚本
python create_list.py 如下图:
(4)检查train.txt valid.txt
create_list.py 执行后,生成2个文件,1个文件夹(将images文件夹中xml,移动到此文件夹)
(5)label_list.txt 自行处理,labelimg中也能生成。
完成上述过程,即可拥有可执行的训练数据。**
(P:吐槽下加了很多次官方QQ群,未果;官方例子部分环节说明不清晰。。。于是乎,自行摸爬滚打,如有坑,请自行排雷。)
三、脚本代码
import os
import os.path as osp
import re
import random
import shutil
# roadsign_voc
# ---annotations
# ------*.xml
# ---images
# ------*.png
# ---train.txt
# ---valid.txt
# ---create_list.py
# roadsign_voc文件夹下运行cmd,python create_list.py
devkit_dir = './'
annotation_dir = 'annotations'
img_dir = 'images'
copy_xml = True
# 私有参数
_train_list = list()
_valid_list = list()
# 拼接路径
def get_dir(devkit_dir, type):
return osp.join(devkit_dir, type)
def SearchFile(directory, fileName):
for root, subDirs, files in os.walk(directory):
for Cur_fileName in files:
if Cur_fileName.startswith(fileName):
return Cur_fileName
return ''
# 根据后缀名筛选文件
def SearchFiles(directory, fileType):
fileList = []
for root, subDirs, files in os.walk(directory):
for fileName in files:
if fileName.endswith(fileType):
fileList.append(os.path.join(root, fileName))
return fileList
def walk_dir(param_list):
result_list = []
for itm in param_list:
xml_file = SearchFile(annotation_dir, itm)
img_file = SearchFile(img_dir, itm)
if xml_file == '' or img_file == '':
continue
testStr = "{0} {1}".format(os.path.join(
img_dir, img_file), os.path.join(annotation_dir, xml_file))
testStr=testStr.replace('\\', '/')
print(testStr)
result_list.append(testStr)
return result_list
# 转移xml路径
def MoveXml_to_Annotations():
# 获取所有xml
file_list = SearchFiles(img_dir, "xml")
if not os.path.exists(annotation_dir):
os.makedirs(annotation_dir)
if len(file_list) > 0:
for file_itm in file_list:
# 把xml文件复制到annotation文件夹
shutil.move(file_itm, annotation_dir)
def ComputeTrain_Valid():
train_precent = 0.8 # 拆分系数 train与valid 八二开
total_xml = os.listdir(annotation_dir)
num = len(total_xml)
list = range(num)
tr = int(num*train_precent)
train = random.sample(list, tr)
# 循环拆分
for i in range(num):
name = total_xml[i][:-4]
if i in train:
_train_list.append(name)
else:
_valid_list.append(name)
# 生成train.txt,valid.txt
def prepare_filelist():
trainval_list =walk_dir(_train_list)
test_list =walk_dir(_valid_list)
random.shuffle(trainval_list)
with open(osp.join(devkit_dir, 'train.txt'), 'w') as ftrainval:
for item in trainval_list:
ftrainval.write(item + '\n')
with open(osp.join(devkit_dir, 'valid.txt'), 'w') as ftest:
for item in test_list:
ftest.write(item + '\n')
if __name__ == '__main__':
annotation_dir = get_dir(devkit_dir, 'annotations')
img_dir = get_dir(devkit_dir, 'images')
if copy_xml:
MoveXml_to_Annotations()
# 根据xml 计算 train , valid 集合
ComputeTrain_Valid()
# 生成train.txt,valid.txt
prepare_filelist()