BDD100K数据集介绍:
BDD100K的道路目标检测部分总共有10类:bus,traffic light,traffic sign,person,bike,truck,moter,car,train,rider。
BDD100K数据集的下载(百度云)

链接:https://pan.baidu.com/s/1fFSzGJt6Op4k7Gyo9QjtYA
提取码:kuld

一般只需要下载解压bdd100k_labels.zip和bdd100k_images.zip,会出现两个bdd100k文件夹,这两个文件夹内分别存储了images和labels两个子文件夹,其中images文件夹内存放了1280x720的图片,labels存放了json格式的标签文件,我们把两个子文件夹合并到一个bdd100k文件夹内,方便查看和处理。文件目录树如下:

├── bdd100k
│   ├── images
│   │   ├── 100k
│   │   │   ├── test    # 20k测试集图片
│   │   │   ├── train   # 70k训练集图片
│   │   │   └── val     # 10k验证集图片
│   │   └── 10k
│   │   ├── test    # 2k测试集图片
│   │   ├── train    # 7k测试集图片
│   │   └── val    # 1k验证集图片
│   ├── labels
│   │   └── 100k
│   │   ├── train  # 70k训练集标签
│   │   ├── val     # 10k验证集标签,这里没有提供20k测试集标签

首先,我们需要两个辅助脚本:parseJson.py(用来解析json里面的对象检测部分的数据)和pascal_voc_io.py(创建VOC格式的xml,并把json文件的数据填充到xml)。
parseJson.py

#!/usr/bin/env python
# -*- coding: utf8 -*-
#parse json,input json filename,output info needed by vocimport json
#这里是我需要的10个类别
categorys = ['car', 'bus', 'person', 'bike', 'truck', 'motor', 'train', 'rider', 'traffic sign', 'traffic light']def parseJson(jsonFile):'''params:jsonFile -- BDD00K数据集的一个json标签文件return:返回一个列表的列表,存储了一个json文件里面的方框坐标及其所属的类,形如:[[325, 342, 376, 384, 'car'], [245, 333, 336, 389, 'car']]'''objs = []obj = []f = open(jsonFile)info = json.load(f)objects = info['frames'][0]['objects']for i in objects:if(i['category'] in categorys):obj.append(int(i['box2d']['x1']))obj.append(int(i['box2d']['y1']))obj.append(int(i['box2d']['x2']))obj.append(int(i['box2d']['y2']))obj.append(i['category'])objs.append(obj)obj = []#print("objs",objs)return objs#test
#result = parseJson("/media/xavier/SSD256/global_datasets/BDD00K/bdd100k/labels/100k/val/b1c9c847-3bda4659.json")
#print(len(result))
#print(result)

pascal_voc_io.py`

#!/usr/bin/env python
# -*- coding: utf8 -*-
import sys
import os
from xml.etree import ElementTree
from xml.etree.ElementTree import Element, SubElement
from lxml import etree
from xml.dom.minidom import parseStringclass PascalVocWriter:def __init__(self, foldername, filename, imgSize, databaseSrc='Unknown', localImgPath=None):'''params:foldername -- 要存储的xml文件的父目录filename -- xml文件的文件名imgSize -- 图片的尺寸databaseSrc -- 数据库名,这里不需要,默认为UnknownlocalImaPath -- xml文件里面的<path></path>标签的内容'''self.foldername = foldernameself.filename = filenameself.databaseSrc = databaseSrcself.imgSize = imgSizeself.boxlist = []self.localImgPath = localImgPathdef prettify(self, elem):"""params:elem -- xml的根标签,以<annotation>开始return:返回一个美观输出的xml(用到minidom),本质是一个str"""xml = ElementTree.tostring(elem)dom = parseString(xml)
#        print(dom.toprettyxml('  '))prettifyResult = dom.toprettyxml('    ')return prettifyResultdef genXML(self):"""return:生成一个VOC格式的xml,返回一个xml的根标签,以<annotation>开始"""# Check conditionsif self.filename is None or \self.foldername is None or \self.imgSize is None or \len(self.boxlist) <= 0:return Nonetop = Element('annotation') # 创建一个根标签<annotation>folder = SubElement(top, 'folder')  # 在根标签<annotation>下创建一个子标签<folder>folder.text = self.foldername       # 用self.foldername的数据填充子标签<folder>filename = SubElement(top, 'filename')  # 在根标签<annotation>下创建一个子标签<filename>filename.text = self.filename           # 用self.filename的数据填充子标签<filename>localImgPath = SubElement(top, 'path')  # 在根标签<annotation>下创建一个子标签<path>localImgPath.text = self.localImgPath   # 用self.localImgPath的数据填充子标签<path>source = SubElement(top, 'source')          # 在根标签<annotation>下创建一个子标签<source>database = SubElement(source, 'database')   # 在根标签<source>下创建一个子标签<database>database.text = self.databaseSrc            # 用self.databaseSrc的数据填充子标签<database>size_part = SubElement(top, 'size')         # 在根标签<annotation>下创建一个子标签<size>width = SubElement(size_part, 'width')      # 在根标签<size>下创建一个子标签<width>height = SubElement(size_part, 'height')    # 在根标签<size>下创建一个子标签<height>depth = SubElement(size_part, 'depth')      # 在根标签<size>下创建一个子标签<depth>width.text = str(self.imgSize[1])           # 用self.imgSize[1]的数据填充子标签<width>height.text = str(self.imgSize[0])          # 用self.imgSize[0]的数据填充子标签<height>if len(self.imgSize) == 3:                  # 如果图片深度为3,则用self.imgSize[2]的数据填充子标签<height>,否则用1填充depth.text = str(self.imgSize[2])else:depth.text = '1'segmented = SubElement(top, 'segmented')segmented.text = '0'return topdef addBndBox(self, xmin, ymin, xmax, ymax, name):'''将检测对象框坐标及其对象类别作为一个字典加入到self.boxlist中params:xmin -- 检测框的左上角的x坐标ymin -- 检测框的左上角的y坐标xmax -- 检测框的右下角的x坐标ymax -- 检测框的右下角的y坐标name -- 检测框内的对象类别名'''bndbox = {'xmin': xmin, 'ymin': ymin, 'xmax': xmax, 'ymax': ymax}bndbox['name'] = nameself.boxlist.append(bndbox)def appendObjects(self, top):'''在xml文件中加入检测框的坐标及其对象类别名params:top -- xml的根标签,以<annotation>开始'''for each_object in self.boxlist:object_item = SubElement(top, 'object')name = SubElement(object_item, 'name')name.text = str(each_object['name'])pose = SubElement(object_item, 'pose')pose.text = "Unspecified"truncated = SubElement(object_item, 'truncated')truncated.text = "0"difficult = SubElement(object_item, 'Difficult')difficult.text = "0"bndbox = SubElement(object_item, 'bndbox')xmin = SubElement(bndbox, 'xmin')xmin.text = str(each_object['xmin'])ymin = SubElement(bndbox, 'ymin')ymin.text = str(each_object['ymin'])xmax = SubElement(bndbox, 'xmax')xmax.text = str(each_object['xmax'])ymax = SubElement(bndbox, 'ymax')ymax.text = str(each_object['ymax'])def save(self, targetFile=None):'''以美观输出的xml格式来保存xml文件params:targetFile -- 存储的xml文件名,不包括.xml部分'''root = self.genXML()self.appendObjects(root)out_file = Nonesubdir = self.foldername.split('/')[-1]if not os.path.isdir(subdir):os.mkdir(subdir)if targetFile is None:with open(self.foldername+'/'+self.filename + '.xml', 'w') as out_file:prettifyResult = self.prettify(root)out_file.write(prettifyResult)out_file.close()else:with open(targetFile, 'w') as out_file:prettifyResult = self.prettify(root)out_file.write(prettifyResult)out_file.close()class PascalVocReader:def __init__(self, filepath):# shapes type:# [labbel, [(x1,y1), (x2,y2), (x3,y3), (x4,y4)], color, color]self.shapes = []self.filepath = filepathself.parseXML()def getShapes(self):return self.shapesdef addShape(self, label, bndbox):xmin = int(bndbox.find('xmin').text)ymin = int(bndbox.find('ymin').text)xmax = int(bndbox.find('xmax').text)ymax = int(bndbox.find('ymax').text)points = [(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax)]self.shapes.append((label, points, None, None))def parseXML(self):assert self.filepath.endswith('.xml'), "Unsupport file format"parser = etree.XMLParser(encoding='utf-8')xmltree = ElementTree.parse(self.filepath, parser=parser).getroot()filename = xmltree.find('filename').textfor object_iter in xmltree.findall('object'):bndbox = object_iter.find("bndbox")label = object_iter.find('name').textself.addShape(label, bndbox)return True# tempParseReader = PascalVocReader('test.xml')
# print tempParseReader.getShapes()
#"""
# Test
#tmp = PascalVocWriter('temp','test', (10,20,3))
#tmp.addBndBox(10,10,20,30,'chair')
#tmp.addBndBox(1,1,600,600,'car')
#tmp.save()
#"""

其次,我们创建一个脚本bdd2voc.py将两个辅助脚本整合起来。

bdd2voc.py

# -*- coding: utf8 -*-
import os
import pascal_voc_io
import parseJsondef main(srcDir, dstDir):i = 1# os.walk()# dirName是你所要遍历的目录的地址, 返回的是一个三元组(root,dirs,files)# root所指的是当前正在遍历的这个文件夹的本身的地址# dirs是一个 list ,内容是该文件夹中所有的目录的名字(不包括子目录)# files 同样是 list , 内容是该文件夹中所有的文件(不包括子目录)for dirpath, dirnames, filenames in os.walk(srcDir):
#        print(dirpath, dirnames, filenames)for filepath in filenames:fileName = os.path.join(dirpath,filepath)print(fileName)print("processing: {}, {}".format(i, fileName))i = i + 1xmlFileName = filepath[:-5] # remove ".json" 5 character# 解析该json文件,返回一个列表的列表,存储了一个json文件里面的所有方框坐标及其所属的类objs = parseJson.parseJson(str(fileName)) # 如果存在检测对象,创建一个与该json文件具有相同名的VOC格式的xml文件if len(objs):tmp = pascal_voc_io.PascalVocWriter(dstDir, xmlFileName, (720,1280,3), fileName)for obj in objs:tmp.addBndBox(obj[0],obj[1],obj[2],obj[3],obj[4])tmp.save()else:print(fileName)if __name__ == '__main__':# test# these paths should be your own path
#    srcDir = '/media/xavier/SSD256/global_datasets/BDD00K/bdd100k/labels/100k/val'
#    dstDir = '/media/xavier/SSD256/global_datasets/BDD00K/bdd100k/Annotations/val'srcDir = '/media/xavier/SSD256/global_datasets/BDD00K/bdd100k/labels/100k/train'dstDir = '/media/xavier/SSD256/global_datasets/BDD00K/bdd100k/Annotations/train'main(srcDir, dstDir)

运行脚本bdd2voc.py,将会在指定目录下生成xml标签)

使用YOLOv3训练BDD100K数据集之标签格式转换相关推荐

  1. BDD100K数据集转YOLO格式

    前言 BDD100K由伯克利大学AI实验室(BAIR)发布,是目前最大规模.内容最具多样性的公开驾驶数据集.BDD100K 数据集包含10万段高清视频,每个视频约40秒,720p,30 fps .每个 ...

  2. WIN10 +pytorch版yolov3训练自己数据集

    pytorch版yolov3训练自己数据集 目录 1. 环境搭建 2. 数据集构建 3. 训练模型 4. 测试模型 5. 评估模型 6. 可视化 7. 高级进阶-网络结构更改 1. 环境搭建 将git ...

  3. yolov3 训练及数据集准备【记录】

    ------------------------------ 本文仅供学习交流,如有错误,望交流指教 ------------------------------ yolov3 训练及数据集准备[记录 ...

  4. Yolov5-5.0源码分享以及环境配置——Yolov5训练及测试教程(超详细含数据集制作,格式转换,数据集划分)

    yolov5-5.0百度网盘连接 链接: https://pan.baidu.com/s/1Hd2KKBixuEWRv3jcH6Bcsw 提取码: g6xf 复制这段内容后打开百度网盘手机App,操作 ...

  5. mmdetection实战,训练扑克牌数据集(VOC格式)并测试计算mAP

    mmdetection实战,训练扑克牌数据集(VOC格式)并测试计算mAP 一.数据集准备 二.mmdetection的安装 三.修改相关文件 1. 修改class_names.py文件 2. 修改v ...

  6. 使用YOLOV7训练BDD100K数据集(数据格式转化+训练全流程)

    目录 1. 前言 1.1 BDD100K数据集详细介绍(此节可跳过) 1.2 BDD100K数据集简要介绍 1.3 下载必要文件 2. bdd100k转yolo数据集格式 2.1 为什么要转格式 2. ...

  7. HRSID舰船检测数据集标签格式转换,json转为xml

    HRSID数据集介绍参考原文:https://ieeexplore.ieee.org/document/9127939 数据集下载链接:https://github.com/chaozhong2010 ...

  8. (官方步骤)YOLO-V3训练VOC数据集

    前提:编译好darknet,教程参考本人链接:https://blog.csdn.net/qq_34806812/article/details/81167836 开始: darknet目录下新建VO ...

  9. 行人检测-Caltech Pedestrian Dataset 数据集下载及格式转换

    Caltech Pedestrian Dataset 数据集 加理工(caltech)提供的数据集, 该数据集主要包括 训练集+测试集:seq格式的数据: 行人标签数据:vbb(video bound ...

最新文章

  1. Iphone 指触行为会
  2. Linux使用错误小结(CentOS)- yum更新软件失败
  3. 前端学习(1432):模板引擎概述
  4. 某储云商城系统源码V1.782 绿色版
  5. 【开发工具】之source insight 4常用设置
  6. 速修复!开源 IT 基础设施管理解决方案 Salt 被曝多个严重漏洞
  7. 数据集:科研经费投入对生产能力提高的影响
  8. 计算机病毒与恶意代码期末总结
  9. 人大金仓数据库Docker部署
  10. Linux内核API手册——简略版
  11. java数据结构与算法之栈(Stack)设计与实现
  12. 激光雷达+imu_激光雷达slam-激光点云畸变补偿
  13. warning CS0108: `___' hides inherited member `___'. Use the new keyword if hiding was intended解决办法
  14. ​复盘共享经济2020:陷入艰难求生困境,转型能否拯救亏损怪圈
  15. 如何从初级程序员顺利晋升到高级程序员?
  16. vue中实现输入字数限制
  17. jxls对比_久别重逢 QQ影音4.0跟旧版对比更新了什么?
  18. 第二章 2.1 机器视觉——图像《2022年斯坦福AI指数报告》中文全解读
  19. Java Swing实现仿win7计算器
  20. 星策社区发起人谭中意:用开源方式推进企业智能化转型

热门文章

  1. teams测试性分析软件官网,基于TEAMS的双馈风力发电机测试性建模与分析
  2. COVID-19 和数字化要务
  3. GIS基础简介:基本概念、互联网坐标系、WebGIS实操
  4. 数据结构实验九 下三角矩阵的压缩存储
  5. appium+mitmdump+夜神模拟器抓取抖音app
  6. html百度地图拖动,百度地图为marker添加拖拽事件
  7. Python3 多线程
  8. Linux 防火墙操作指令
  9. 如何判断QQ号码长度是否“合法”?
  10. CAD软件中如何定义设备表?