目录
1 事先准备的文件:
1.1 需要训练的图片
要求路径中有一个子目录名称是 images (或 imgs ) ,训练程序需要通过 /images/ (或 /imgs/ ) 替换为 /labels/ 找同名.txt文件提取标注数据
默认情况下,yolov5是 images, yolov4是 imgs
图片无需拷贝到yolo目录
1.2 标注的xml文件
# 支持xml格式 或 voc 格式,可用标注精灵或labelimg。后者是python程序,但连续标注效率高,推荐使用
2 功能:
1)将标注数据转为yolo格式,保存到 <labeltxtpath>/<img>.txt
# <labeltxtpath>=<imgpath> 中最后一个 images (或 imgs ) 换为 labels,扩展名改为txt
2)生成 data/obj.names,类别名称列表
3)创建清单文件 data/train.txt,val.txt,test.txt
# 三者按指定比例随机比例, 不重复。5000-1万以上的图片,建议val 500左右,test 100 左右
3 用法:
1) 测试、调整图片配比
python make_label_yolo.py --runtest yes --imgpath E:\models\test1\images --labelxmlpath E:\models\test1\xmls --train_percent 0.9 --val_percent 0.08 --test_percent 0.02
2) 正式转换
python make_label_yolo.py --imgpath E:\models\test1\images --labelxmlpath E:\models\test1\xmls --train_percent 0.9 --val_percent 0.08 --test_percent 0.02
4 注意事项:
#1)忽略 images 和 labelsxml 以.开头的文件;
#2)labelsxml中的标签文件,只有在 imgpath 存在同名图片才采用。
#3)需要训练的图片无需拷贝到 <yolo>/data/images
#4)根据yolo要求,txt标注文件生成在实际图片 images (或 imgs ) 并列目录 labels
#5)训练用到的文件清单描述文件,保存在 <yolo>/data/train.txt, val.txt, test.txt
#6)跳过宽w或高h小于指定大小的标注
#7)train/训练,val/校准,test/测验配比默认为 0.9 0.08 0.02,命令行参数修改
#8)视频提取的图片文件名称带 grp_ 前缀,这些文件不参与训练时校准val、测验test
脚本文件1: make_label_yolo.py,转换格式、随机分配 train val test清单
# 事先准备的文件:
# 需要训练的图片
# 要求路径中有一个子目录名称是 images (或 imgs ) ,训练程序需要通过 /images/ (或 /imgs/ ) 替换为 /labels/ 找同名.txt文件提取标注数据
# 默认情况下,yolov5是 images, yolov4是 imgs
# 图片无需拷贝到yolo目录
# 标注的xml文件 # xml格式 或 voc 格式
# 功能:
# 1)将标注数据转为yolo格式,保存到 <labeltxtpath>/<img>.txt # <labeltxtpath>=<imgpath> 中最后一个 images (或 imgs ) 换为 labels,扩展名改为txt
# 3)生成 data/obj.names
# 4)创建清单文件 data/train.txt,val.txt,test.txt # 三者分配比例由命令行参数确定, 不重复
# 5)坐标越界的标注,会自动纠正,所以不应担心中间异常数据导致中途退出
# 用法:
# 测试、调整图片配比
# python make_label_yolo.py --runtest yes --imgpath E:\models\test1\images --labelxmlpath E:\models\test1\xmls --train_percent 0.9 --val_percent 0.08 --test_percent 0.02
# 正式转换
# python make_label_yolo.py --imgpath E:\models\test1\images --labelxmlpath E:\models\test1\xmls --train_percent 0.9 --val_percent 0.08 --test_percent 0.02
#注意事项:
#1)忽略 images 和 labelsxml 以.开头的文件;
#2)labelsxml中的标签文件,只有在 imgpath 存在同名图片才采用。
#3)需要训练的图片无需拷贝到 <yolo>/data/images
#4)根据yolo要求,txt标注文件生成在实际图片 images (或 imgs ) 并列目录 labels
#5)训练用到的文件清单描述文件,保存在 <yolo>/data/train.txt, val.txt, test.txt
#6)跳过宽w或高h小于指定大小的标注
#7)train/训练,val/校准,test/测验配比默认为 0.9 0.08 0.02,命令行参数修改
#8)视频提取的图片文件名称带 grp_ 前缀,这些文件不参与训练时校准val、测验test
# 入参 see def parse_opt(known=False):
import time
import xml.etree.ElementTree as ET
import os
import random
# from os import listdir, getcwd
# from os.path import join
from pathlib import Path
import argparse
import sys
FILE = Path(__file__).resolve()
ROOT = FILE.parents[0] # YOLOv5 root directory
if str(ROOT) not in sys.path:
sys.path.append(str(ROOT)) # add ROOT to PATH
ROOT = Path(os.path.relpath(ROOT, Path.cwd())) # relative
# IMG_FORMATS = 'bmp', 'dng', 'jpeg', 'jpg', 'mpo', 'png', 'tif', 'tiff', 'webp' # include image suffixes
file_ext_sets = ['.jpg', '.jpeg','.png','.bmp','.tif','.tiff','.ppm','.webp']
clsfilename="data/obj.names"
g_fileprefix="grp_"
label_totalnum=0
label_oldfilenum=0
label_newfilenum=0
label_skipnum=0
classes = []
gPicFileList= []
gPicFilemap= {}
# 不存在xml标注文件的图片文件名称,make_yololabel()
skipPicList_nolabelxml=[] # print(f"not exist xmlfile={xmlfile}, p={lastps}")
# 没有合格标签而被删除标签文件的图片文件名称,make_yololabel() --> convert_annotation()
skipPicList_annotation=[] # print(f"skip {image_filename} when convert_annotation, no suitable labels ")
# 不存在标签文件的图片文件名称, make_trainvaltest_list()
skipPicList_nolabeltxt=[] # print(f"skip {fn} when make_trainvaltest_list,not exist labelFile={labelFile1}")
# 分析标注文件列表,分配 train test val 清单,其中 val 随机选择
# 要求必须在imgpath存在同名的图片文件, 如果已经生成 yolo的txt标注,则还需在该目录存在同名文件
def make_trainvaltest_list():
global label_totalnum
global skipPicList_nolabeltxt
global g_fileprefix
labelsxmlpath=opt.labelxmlpath
labelstxtpath=getlabelpath(opt.imgpath)
if not os.path.exists(labelstxtpath):
os.makedirs(labelstxtpath)
filetype = ""
global gPicFileList
if len(gPicFileList)<=0:
gPicFileList=getPicfilelist(opt.imgpath)
total_pic=[] # not grp 文件, total_pic.clear()
total_pic_grp=[] # grp文件, 不参与 val test
for file1 in gPicFileList: #遍历所有文件
st1 = os.path.splitext(file1)
fn = st1[0]
ext= st1[1]
if file1.startswith('.'):
continue
xmlfile=os.path.join(labelsxmlpath,fn+".xml")
if not os.path.exists(xmlfile):
xmlfile=os.path.join(labelsxmlpath,fn+".XML")
if not os.path.exists(xmlfile):
# print(f"not exist xmlfile={xmlfile}")
continue
if label_totalnum>0: # 目前判断已生成 yolo txt的策略。如果有变化,相应做修改
labelFile1=os.path.join(labelstxtpath, fn+'.txt')
if not os.path.exists(labelFile1):
# print(f"skip {fn} when make_trainvaltest_list,not exist labelFile={labelFile1}")
skipPicList_nolabeltxt.append(fn)
continue
if file1.startswith(g_fileprefix):
total_pic_grp.append(file1)
else:
total_pic.append(file1)