数据集格式转换二:DarkLabelToVOC

数据集格式转换二:DarkLabelToVOC

1. 写在前面的话(重要)

==请注意:在训练目标检测模型时,千万不要直接用转出的VOC数据集,由于图片帧之间差距过小,特别容易造成过拟合,选取图片时请让间隔大一些,将选中的图片和标签文件作检测数据集。(ps:别问我怎么知道的,说多了都是泪)

2. 参考

参考pprpp大神的文章:https://www.jianshu.com/p/f36a45236044

3. 代码

import glob
import os
import shutil

'''
将darklabel做的数据集转化位VOC数据集
# 假设darklabel生成的追踪文件名称格式为:dir_gt.txt(dir为其图片所在父目录)
# 假设每个文件夹下的gt文件没有跳帧的现象(就是没有中间隔着几张没有标注的现象,一般没问题)
# 假设图片大小均为1280,720,且图片格式为.jpg格式(可以修改程序中的<width, height = 1280, 720  # 图片宽高>这一行)
# 假设新生成的图片及标签名称格式为8位

# 将darklabel标注完成的数据集放某一目录下,在程序中用root_path表示。<root_path = 'D:/dltovoc/'>
# 新生成的VOC数据集图片位置 D:/dltovocnew/JPEGImages  <JPEGImages_path = os.path.join('D:/dltovocnew', 'JPEGImages')>
# 新生成的VOC数据集标签位置 D:/dltovocnew/Annotations <Annotations_path = os.path.join('D:/dltovocnew', 'Annotations')>

'''

def genXML(line, xml_dir, outname, width, height):   # 对于每一行,写一个xml文件
    # 每一行,得到bbox的位置和类别信息
    item = line[:-1]
    items = item.split(',')
    frame_id, num_of_cow = items[0], items[1]       # 注意一下frame_id如何处理,直接一行一个就行了
    bboxes = []
    for i in range(int(num_of_cow)):
        obj_id = items[1 + i * 6 + 1]
        obj_x1, obj_y1 = int(items[1 + i * 6 + 2]), int(items[1 + i * 6 + 3])
        obj_x2, obj_y2 = int(items[1 + i * 6 + 4]), int(items[1 + i * 6 + 5])
        class_name = items[1 + i * 6 + 6]
        # preprocess the coords
        obj_x1 = max(1, obj_x1)
        obj_y1 = max(1, obj_y1)
        obj_x2 = min(width, obj_x2)
        obj_y2 = min(height, obj_y2)
        bboxes.append([obj_x1, obj_y1, obj_x2, obj_y2, class_name])
    # 写xml文件
    # 每一行写一个xml文件
    xml_file = open((xml_dir + '/' + outname + '.xml'), 'w')
    xml_file.write('<annotation>\n')
    xml_file.write('    <folder>Annotations</folder>\n')
    xml_file.write('    <filename>' + outname + '.jpg' + '</filename>\n')
    #xml_file.write('    <path>' + outname + '.jpg' + '</path>\n')
    xml_file.write('    <size>\n')
    xml_file.write('        <width>' + str(width) + '</width>\n')
    xml_file.write('        <height>' + str(height) + '</height>\n')
    xml_file.write('        <depth>3</depth>\n')
    xml_file.write('    </size>\n')

    for bbox in bboxes:
        x1, y1, x2, y2, class_name = bbox
        xml_file.write('    <object>\n')
        xml_file.write('        <name>' + class_name + '</name>\n')
        xml_file.write('        <pose>Unspecified</pose>\n')
        xml_file.write('        <truncated>0</truncated>\n')
        xml_file.write('        <difficult>0</difficult>\n')
        xml_file.write('        <bndbox>\n')
        xml_file.write('            <xmin>' + str(x1) + '</xmin>\n')
        xml_file.write('            <ymin>' + str(y1) + '</ymin>\n')
        xml_file.write('            <xmax>' + str(x2) + '</xmax>\n')
        xml_file.write('            <ymax>' + str(y2) + '</ymax>\n')
        xml_file.write('        </bndbox>\n')
        xml_file.write('    </object>\n')

    xml_file.write('</annotation>')

# 获取文件夹下文件数量(最大数量)。
# 方案一:读取各个文件夹下的照片数量
if __name__ == '__main__':
    root_path = 'D:/dltovoc2/dl'
    JPEGImages_path = os.path.join('D:/dltovoc2/VOC', 'JPEGImages')     # 图片位置
    Annotations_path = os.path.join('D:/dltovoc2/VOC', 'Annotations')   # 标签位置
    index = 0                                               # 图片总数量
    dir_list = os.listdir(root_path)  # 读取FilePath下的子文件夹名称

    if dir_list is None:
        print("文件夹下无文件")
    else:
        for dirname in dir_list:  # 对于每一个子文件夹
            # 获取每个子文件夹下的图片信息
            img_dir = os.path.join(root_path,dirname)       # 原图片的父目录
            width, height = 1280, 720                       # 图片宽高
            img_glob_path = os.path.join(root_path,dirname+'/*.jpg') # 原图片格式位置:D:/dltovoc/001/*.jpg
            img_num=len(glob.glob(img_glob_path))           #获取子文件夹某种格式文件的数量,这里读的是.jpg图片
            # 打开每个子文件夹下的gt文件,按行读取
            darklabel_gt_path = os.path.join(root_path, dirname, dirname + '_gt.txt')
            txt_file = open(darklabel_gt_path, "r")  # 打开gt文件
            content = txt_file.readlines()  # 按行读取

            # 对图片进行复制,重命名后粘贴的工作可以
            # 获取子文件夹下的图片,当进行到第二个文件夹之后,需要对图片进行重命名后,然后放到JPEGImages文件夹下。(重命名规则:总数量+1,8位)
            img_list = os.listdir(img_dir)  # 读取子文件夹下的图片
            list_index = 1    # 第几张图片,这里假设图片和gt.txt中没有中间跳过几帧的情况 对于每个子文件夹都会更新
            for img_file in img_list:           # 00000001.jpg
                if img_file.endswith('.jpg'):   # 如果文件是图片文件
                    print('这是当前文件夹下第几张图片',list_index)
                    print(img_file)             # 这个名字的数量大小和下边应该是一样的才对
                    index = index + 1           # 当前图片在总文件夹下的索引值,index全局变量,不会更新
                    print('总索引值',index)
                    img_ini_path = os.path.join(img_dir,img_file)                   # 图片文件原文件夹
                    index_format = str(index).zfill(8)
                    print(index_format)
                    img_new_path = os.path.join(JPEGImages_path, index_format+'.jpg')      # 图片文件目标文件夹
                    print(img_new_path)
                    shutil.copyfile(img_ini_path, img_new_path)  # 将路径为img_ini_path的文件,复制到img_new_path路径中
                    # 每一张图片对应的xml文件
                    genXML(content[list_index-1], Annotations_path, index_format,  width=1280, height=720)

                    list_index = list_index + 1
                else:       # 此时是各个子文件夹下的gt.txt文件,不用管
                    continue
            # 对于每个子文件夹下的每一张图片和标签文件操作结束

4. 验证工作

如何知道我们转化成功,并且没有错误呢?
使用LabelIMG打开图片文件夹和XML文件夹,进行速览发现bbox位置和标签信息正确即可。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值