YOLO训练KITTI数据集(二):KITTI数据集的标签转换成YOLOv5所需要的标签格式并进行分割

1.对数据集标签进行合并

modify_annotations_txt.py。这里忽略了Dontcare、Misc并将Person_sitting类合并到了Pedestrian类,可以按照自己的需求进行修改。
里面的路径,跟自身的文件位置修改。
这里是在E:/datasets/yolov5-6.0/mydata/labels/train/文件夹下,输出直接覆盖源文件

# modify_annotations_txt.py
import glob

import string

txt_list = glob.glob('E:/datasets/yolov5-6.0/mydata/labels/train/*.txt') # 存储Labels文件夹所有txt文件路径

print(txt_list)
def show_category(txt_list):
    category_list= []
    for item in txt_list:
        try:
            with open(item) as tdf:
                for each_line in tdf:
                    labeldata = each_line.strip().split(' ') # 去掉前后多余的字符并把其分开
                    category_list.append(labeldata[0]) # 只要第一个字段,即类别
        except IOError as ioerr:
            print('File error:'+str(ioerr))
    print(set(category_list)) # 输出集合

def merge(line):
    each_line=''
    for i in range(len(line)):
        if i!= (len(line)-1):
            each_line=each_line+line[i]+' '
        else:
            each_line=each_line+line[i] # 最后一条字段后面不加空格
    each_line=each_line+'\n'
    return (each_line)

print('before modify categories are:\n')
show_category(txt_list)

for item in txt_list:
    new_txt=[]
    try:
        with open(item, 'r') as r_tdf:
            for each_line in r_tdf:
                labeldata = each_line.strip().split(' ')
                # if labeldata[0] in ['Truck','Van','Tram']: # 合并汽车类
                #     labeldata[0] = labeldata[0].replace(labeldata[0],'Car')
                if labeldata[0] == 'Person_sitting': # 合并行人类
                    labeldata[0] = labeldata[0].replace(labeldata[0],'Pedestrian')
                if labeldata[0] == 'DontCare': # 忽略Dontcare类
                    continue
                if labeldata[0] == 'Misc': # 忽略Misc类
                    continue
                new_txt.append(merge(labeldata)) # 重新写入新的txt文件
        with open(item,'w+') as w_tdf: # w+是打开原文件将内容删除,另写新内容进去
            for temp in new_txt:
                w_tdf.write(temp)
    except IOError as ioerr:
        print('File error:'+str(ioerr))

print('\nafter modify categories are:\n')
show_category(txt_list)


2、将txt文件转换成xml文件

将KITTI的txt标签转化为voc的xml格式:kitti_txt_to_xml.py
这里是将E:/datasets/yolov5-6.0/mydata/labels/train转换到E:/datasets/yolov5-6.0/mydata/labels/test/文件夹下

# kitti_txt_to_xml.py
# encoding:utf-8
# 根据一个给定的XML Schema,使用DOM树的形式从空白文件生成一个XML
from xml.dom.minidom import Document
import cv2
import glob
import os
def generate_xml(name,split_lines,img_size,class_ind):
    doc = Document() # 创建DOM文档对象
    annotation = doc.createElement('annotation')
    doc.appendChild(annotation)
    title = doc.createElement('folder')
    title_text = doc.createTextNode('KITTI')
    title.appendChild(title_text)
    annotation.appendChild(title)
    img_name=name+'.jpg'
    title = doc.createElement('filename')
    title_text = doc.createTextNode(img_name)
    title.appendChild(title_text)
    annotation.appendChild(title)
    source = doc.createElement('source')
    annotation.appendChild(source)
    title = doc.createElement('database')
    title_text = doc.createTextNode('The KITTI Database')
    title.appendChild(title_text)
    source.appendChild(title)
    title = doc.createElement('annotation')
    title_text = doc.createTextNode('KITTI')
    title.appendChild(title_text)
    source.appendChild(title)
    size = doc.createElement('size')
    annotation.appendChild(size)
    title = doc.createElement('width')
    title_text = doc.createTextNode(str(img_size[1]))
    title.appendChild(title_text)
    size.appendChild(title)
    title = doc.createElement('height')
    title_text = doc.createTextNode(str(img_size[0]))
    title.appendChild(title_text)
    size.appendChild(title)
    title = doc.createElement('depth')
    title_text = doc.createTextNode(str(img_size[2]))
    title.appendChild(title_text)
    size.appendChild(title)
    for split_line in split_lines:
        line=split_line.strip().split()
        if line[0] in class_ind:
            object = doc.createElement('object')
            annotation.appendChild(object)
            title = doc.createElement('name')
            title_text = doc.createTextNode(line[0])
            title.appendChild(title_text)
            object.appendChild(title)
            bndbox = doc.createElement('bndbox')
            object.appendChild(bndbox)
            title = doc.createElement('xmin')
            title_text = doc.createTextNode(str(int(float(line[4]))))
            title.appendChild(title_text)
            bndbox.appendChild(title)
            title = doc.createElement('ymin')
            title_text = doc.createTextNode(str(int(float(line[5]))))
            title.appendChild(title_text)
            bndbox.appendChild(title)
            title = doc.createElement('xmax')
            title_text = doc.createTextNode(str(int(float(line[6]))))
            title.appendChild(title_text)
            bndbox.appendChild(title)
            title = doc.createElement('ymax')
            title_text = doc.createTextNode(str(int(float(line[7]))))
            title.appendChild(title_text)
            bndbox.appendChild(title)
    # 将DOM对象doc写入文件
    f = open('E:/datasets/yolov5-6.0/mydata/labels/test/'+name+'.xml','w')#xml
    f.write(doc.toprettyxml(indent = ''))
    f.close()
if __name__ == '__main__':
    class_ind=('Car', 'Cyclist', 'Truck', 'Van', 'Pedestrian', 'Tram')
    # cur_dir=os.getcwd()
    labels_dir= "E:/datasets/yolov5-6.0/mydata/labels/train"
    # labels_dir=os.path.join(cur_dir,'label_2')
    for parent, dirnames, filenames in os.walk(labels_dir):# 分别得到根目录,子目录和根目录下文件
        for file_name in filenames:
            full_path=os.path.join(parent, file_name) # 获取文件全路径
            f=open(full_path)
            split_lines = f.readlines() #以行为单位读
            name= file_name[:-4] # 后四位是扩展名.txt,只取前面的文件名
            img_name=name+'.png'
            img_path=os.path.join('E:/datasets/yolov5-6.0/mydata/images/train',img_name) # 路径需要自行修改
            img_size=cv2.imread(img_path).shape
            generate_xml(name,split_lines,img_size,class_ind)
            print('txts has converted into xmls')

3.将xml文件转换成txt文件

将xml格式的标签转化为yolo训练需要的txt格式:xml_to_yolo_txt.py
这里是将E:/datasets/yolov5-6.0/mydata/labels/test/里面的xml文件转换成txt并保存在源文件夹下。

# xml_to_yolo_txt.py
# 此代码和VOC_KITTI文件夹同目录
import glob
import xml.etree.ElementTree as ET
# 这里的类名为我们xml里面的类名,顺序现在不需要考虑
class_names = ['Car', 'Cyclist', 'Truck', 'Van', 'Pedestrian', 'Tram']
# xml文件路径
path = 'E:/datasets/yolov5-6.0/mydata/labels/test/'

# 转换一个xml文件为txt
def single_xml_to_txt(xml_file):
    tree = ET.parse(xml_file)
    root = tree.getroot()
    # 保存的txt文件路径
    # txt_file = xml_file.split('.')[0]+'.txt'
    txt_file = xml_file.split('.')[0] + '.' + xml_file.split('.')[1] + '.txt'
    with open(txt_file, 'w') as txt_file:
        for member in root.findall('object'):
            print('xmls has converted into txts')
            #filename = root.find('filename').text
            picture_width = int(root.find('size')[0].text)
            picture_height = int(root.find('size')[1].text)
            class_name = member[0].text
            # 类名对应的index
            class_num = class_names.index(class_name)

            box_x_min = int(member[1][0].text) # 左上角横坐标
            box_y_min = int(member[1][1].text) # 左上角纵坐标
            box_x_max = int(member[1][2].text) # 右下角横坐标
            box_y_max = int(member[1][3].text) # 右下角纵坐标
            # 转成相对位置和宽高
            x_center = float(box_x_min + box_x_max) / (2 * picture_width)
            y_center = float(box_y_min + box_y_max) / (2 * picture_height)
            width = float(box_x_max - box_x_min) /  picture_width
            height = float(box_y_max - box_y_min) /  picture_height
            print(class_num, x_center, y_center, width, height)
            txt_file.write(str(class_num) + ' ' + str(x_center) + ' ' + str(y_center) + ' ' + str(width) + ' ' + str(height) + '\n')

# 转换文件夹下的所有xml文件为txt
def dir_xml_to_txt(path):
    for xml_file in glob.glob(path + '*.xml'):
        print(xml_file)
        single_xml_to_txt(xml_file)

dir_xml_to_txt(path)

四、数据集划分,训练/验证/测试 = 7/1.5/1.5

生成train.txt、val.txt、test.txt三个文件,存放训练集、验证集和测试集图片的位置和名字。
图片的位置为E:/datasets/yolov5-6.0/mydata/images/,txt文件输出的位置E:/datasets/yolov5-6.0/mydata
在这里插入图片描述

import os
import random

pngfilepath = r'E:/datasets/yolov5-6.0/mydata/images/'
saveBasePath = r"E:/datasets/yolov5-6.0/mydata"

temp_png = os.listdir(pngfilepath)
total_png = []
for png in temp_png:
    if png.endswith(".png"):
        total_png.append(png)

train_percent = 0.7
val_percent = 0.15
test_percent = 0.15

num = len(total_png)
# train = random.sample(num,0.9*num)
list = list(range(num))

num_train = int(num * train_percent)
num_val = int(num * val_percent)


train = random.sample(list, num_train)
num1 = len(train)
for i in range(num1):
    list.remove(train[i])

val_test = [i for i in list if not i in train]
val = random.sample(val_test, num_val)
num2 = len(val)
for i in range(num2):
    list.remove(val[i])

# for i in train:
#      if i in list:
#          list.remove(i)

ftrain = open(os.path.join(saveBasePath, 'train.txt'), 'w')
fval = open(os.path.join(saveBasePath, 'val.txt'), 'w')
ftest = open(os.path.join(saveBasePath, 'test.txt'), 'w')

for i in train:
    name = 'E:/datasets/yolov5-6.0/mydata/images/' + total_png[i][:-4] + '.png' + '\n'
    ftrain.write(name)

for i in val:
    name = 'E:/datasets/yolov5-6.0/mydata/images/' + total_png[i][:-4] + '.png' + '\n'
    fval.write(name)

for i in list:
    name = 'E:/datasets/yolov5-6.0/mydata/images/' + total_png[i][:-4] + '.png' + '\n'
    ftest.write(name)

ftrain.close()

  • 9
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论
你可以按照以下步骤将KITTI数据集转换为YOLOv5格式: 1. 下载KITTI数据集:访问KITTI官方网站(http://www.cvlibs.net/datasets/kitti/)并注册账号,下载所需的训练图像和标签文件。 2. 安装YOLOv5:按照YOLOv5的官方文档(https://github.com/ultralytics/yolov5)中提供的说明,安装YOLOv5。 3. 创建YOLOv5格式标签文件:打开一个文本编辑器,并按照以下格式为每个图像创建标签文件: ``` <object-class> <x_center> <y_center> <width> <height> ``` 其中,`<object-class>` 表示目标类别,`<x_center>` 和 `<y_center>` 表示目标边界框中心的归一化坐标(范围为0到1),`<width>` 和 `<height>` 表示边界框的归一化宽度和高度。 4. 将KITTI标签转换为YOLOv5格式:使用脚本 `kitti2yolo.py` 将KITTI标签文件转换为YOLOv5格式标签文件。你可以在GitHub上找到多个这样的转换脚本,例如 `https://github.com/pjreddie/darknet/blob/master/scripts/kitti2yolo.py`。 5. 将图像和标签文件分成训练和验证集:根据需要,将图像和标签文件分成训练集和验证集。 6. 创建YOLOv5数据集配置文件:在YOLOv5的 `data` 目录下创建一个配置文件,例如 `kitti.yaml`,并按照以下格式填写: ``` train: path/to/train/images val: path/to/val/images nc: <number-of-classes> names: [class1, class2, ...] ``` 7. 训练YOLOv5模型:使用YOLOv5提供的命令行工具和创建的数据集配置文件,训练YOLOv5模型。 以上是将KITTI数据集转换为YOLOv5格式的基本步骤。请注意,具体的实现细节可能会因所使用的工具和脚本而有所不同。如果需要更详细的指导,请参考YOLOv5的官方文档或其他相关资源。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

anthony-36

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值