200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > 目标检测各类数据集格式互转以及处理方法(VOC COCO txt)

目标检测各类数据集格式互转以及处理方法(VOC COCO txt)

时间:2019-11-06 15:24:02

相关推荐

目标检测各类数据集格式互转以及处理方法(VOC  COCO  txt)

数据集互转目录

coco转voc格式voc转coco格式voc数据格式的处理txt注释格式转coco

在做目标检测时,我个人比较喜欢VOC格式的数据集,所以遇到COCO格式的数据集习惯转为VOC的,再进行处理。

代码地址

coco转voc格式

需要修改的只有路径以及jsonFileName 这个列表,都已经标明了比较清晰的注释。

'''Author: TuZhouVersion: 1.0Date: -08-29 16:32:52LastEditTime: -08-29 17:44:57LastEditors: TuZhouDescription: FilePath: \My_Yolo\datasets\coco_to_voc.py'''from pycocotools.coco import \COCO # 这个包可以从git上下载/cocodataset/cocoapi/tree/master/PythonAPI,也可以直接用修改后的coco.pyimport os, cv2, shutilfrom lxml import etree, objectifyfrom tqdm import tqdmfrom PIL import Image#要生成的voc格式图片路径image_dir = './datasets/RoadSignsPascalVOC_Voc/images'#要生成的voc格式xml标注路径anno_dir = './datasets/RoadSignsPascalVOC_Voc/annotations'#---------------------------------------------##你的coco格式的json类型和文件名,前者表示是train类型的json,后者表示该json文件的名字,类型名最好是与你的对应类型图片保存文件夹名一致#我的json目录只有一个train类型,如果你有测试集的json文件,则可写成[['train', 'instance_train'], ['test', 'instance_test']]jsonFileName = [['train', 'instance_train']]#----------------------------------------------#'''Author: TuZhouDescription: 若模型保存文件夹不存在,创建模型保存文件夹,若存在,删除重建param {*} path 文件夹路径return {*}'''def mkr(path):if os.path.exists(path):shutil.rmtree(path)os.mkdir(path)else:os.mkdir(path) '''Author: TuZhouDescription: 保存xml文件param {*} filenameparam {*} objsparam {*} filepathreturn {*}'''def save_annotations(filename, objs, filepath):annopath = anno_dir + "/" + filename[:-3] + "xml" # 生成的xml文件保存路径#print("filename", filename)dst_path = image_dir + "/" + filenameimg_path = filepathimg = cv2.imread(img_path)#此处时对非RGB图像筛选,可注释# im = Image.open(img_path)# if im.mode != "RGB":#print(filename + " not a RGB image")#im.close()#return# im.close()shutil.copy(img_path, dst_path) # 把原始图像复制到目标文件夹E = objectify.ElementMaker(annotate=False)anno_tree = E.annotation(E.folder('1'),E.filename(filename),E.source(E.database('CKdemo'),E.annotation('VOC'),E.image('CK')),E.size(E.width(img.shape[1]),E.height(img.shape[0]),E.depth(img.shape[2])),E.segmented(0))for obj in objs:E2 = objectify.ElementMaker(annotate=False)anno_tree2 = E2.object(E.name(obj[0]),E.pose(),E.truncated("0"),E.difficult(0),E.bndbox(E.xmin(obj[2]),E.ymin(obj[3]),E.xmax(obj[4]),E.ymax(obj[5])))anno_tree.append(anno_tree2)etree.ElementTree(anno_tree).write(annopath, pretty_print=True)def showbycv(coco, dataType, img, classes, origin_image_dir, verbose=False):filename = img['file_name']#NOTE:dataType表示coco格式中训练集或者测试集的图片文件夹名,但是我所有图片都放在JPEGImages文件夹中,所以此处为空,有需要的可以修改#dataType就是jsonFileName中的json类型,如果你的类型名和你的图片文件夹名一致,则可注释下行dataType = ''filepath = os.path.join(origin_image_dir, dataType, filename)I = cv2.imread(filepath)annIds = coco.getAnnIds(imgIds=img['id'], iscrowd=None)anns = coco.loadAnns(annIds)objs = []for ann in anns:name = classes[ann['category_id']]if 'bbox' in ann:bbox = ann['bbox']xmin = (int)(bbox[0])ymin = (int)(bbox[1])xmax = (int)(bbox[2] + bbox[0])ymax = (int)(bbox[3] + bbox[1])obj = [name, 1.0, xmin, ymin, xmax, ymax]objs.append(obj)if verbose:cv2.rectangle(I, (xmin, ymin), (xmax, ymax), (255, 0, 0))cv2.putText(I, name, (xmin, ymin), 3, 1, (0, 0, 255))save_annotations(filename, objs, filepath)if verbose:cv2.imshow("img", I)cv2.waitKey(0)def catid2name(coco): # 将名字和id号建立一个字典classes = dict()for cat in coco.dataset['categories']:classes[cat['id']] = cat['name']# print(str(cat['id'])+":"+cat['name'])return classes'''Author: TuZhouDescription: param {*} origin_anno_dir 原始coco的json文件目录param {*} origin_image_dir 原始coco的图片保寸目录param {*} verbosereturn {*}'''def get_CK5(origin_anno_dir, origin_image_dir, verbose=False):for dataType, annoName in jsonFileName:#annFile = 'instances_{}.json'.format(dataType)annFile = annoName + '.json'annpath = os.path.join(origin_anno_dir, annFile)coco = COCO(annpath)classes = catid2name(coco)imgIds = coco.getImgIds()# imgIds=imgIds[0:1000]#测试用,抽取10张图片,看下存储效果for imgId in tqdm(imgIds):img = coco.loadImgs(imgId)[0]showbycv(coco, dataType, img, classes, origin_image_dir, verbose=False)def main():base_dir = './datasets/RoadSignsPascalVOC_Voc' # step1 这里是一个新的文件夹,存放转换后的图片和xml标注image_dir = os.path.join(base_dir, 'images') # 在上述文件夹中生成images,annotations两个子文件夹anno_dir = os.path.join(base_dir, 'annotations')mkr(image_dir)mkr(anno_dir)origin_image_dir = './datasets/RoadSignsPascalVOC/JPEGImages' # step 2原始的coco的图像存放位置origin_anno_dir = './datasets/RoadSignsPascalVOC_Coco/Annotations' # step 3 原始的coco的标注存放位置verbose = True # 是否需要看下标记是否正确的开关标记,若是true,就会把标记展示到图片上get_CK5(origin_anno_dir, origin_image_dir, verbose)if __name__ == "__main__":main()

voc转coco格式

import xml.etree.ElementTree as ETimport osimport jsoncoco = dict()coco['images'] = []coco['type'] = 'instances'coco['annotations'] = []coco['categories'] = []category_set = dict()image_set = set()category_item_id = -1image_id = 0000000annotation_id = 0def addCatItem(name):global category_item_idcategory_item = dict()category_item['supercategory'] = 'none'category_item_id += 1category_item['id'] = category_item_idcategory_item['name'] = namecoco['categories'].append(category_item)category_set[name] = category_item_idreturn category_item_iddef addImgItem(file_name, size):global image_idif file_name is None:raise Exception('Could not find filename tag in xml file.')if size['width'] is None:raise Exception('Could not find width tag in xml file.')if size['height'] is None:raise Exception('Could not find height tag in xml file.')image_id += 1image_item = dict()image_item['id'] = image_idimage_item['file_name'] = file_nameimage_item['width'] = size['width']image_item['height'] = size['height']coco['images'].append(image_item)image_set.add(file_name)return image_iddef addAnnoItem(object_name, image_id, category_id, bbox):global annotation_idannotation_item = dict()annotation_item['segmentation'] = []seg = []# bbox[] is x,y,w,h# left_topseg.append(bbox[0])seg.append(bbox[1])# left_bottomseg.append(bbox[0])seg.append(bbox[1] + bbox[3])# right_bottomseg.append(bbox[0] + bbox[2])seg.append(bbox[1] + bbox[3])# right_topseg.append(bbox[0] + bbox[2])seg.append(bbox[1])annotation_item['segmentation'].append(seg)annotation_item['area'] = bbox[2] * bbox[3]annotation_item['iscrowd'] = 0annotation_item['ignore'] = 0annotation_item['image_id'] = image_idannotation_item['bbox'] = bboxannotation_item['category_id'] = category_idannotation_id += 1annotation_item['id'] = annotation_idcoco['annotations'].append(annotation_item)def parseXmlFiles(xml_path):for f in os.listdir(xml_path):if not f.endswith('.xml'):continuebndbox = dict()size = dict()current_image_id = Nonecurrent_category_id = Nonefile_name = Nonesize['width'] = Nonesize['height'] = Nonesize['depth'] = Nonexml_file = os.path.join(xml_path, f)print(xml_file)tree = ET.parse(xml_file)root = tree.getroot()if root.tag != 'annotation':raise Exception('pascal voc xml root element should be annotation, rather than {}'.format(root.tag))# elem is <folder>, <filename>, <size>, <object>for elem in root:current_parent = elem.tagcurrent_sub = Noneobject_name = Noneif elem.tag == 'folder':continueif elem.tag == 'filename':file_name = elem.textif file_name in category_set:raise Exception('file_name duplicated')# add img item only after parse <size> tagelif current_image_id is None and file_name is not None and size['width'] is not None:if file_name not in image_set:current_image_id = addImgItem(file_name, size)print('add image with {} and {}'.format(file_name, size))else:raise Exception('duplicated image: {}'.format(file_name))# subelem is <width>, <height>, <depth>, <name>, <bndbox>for subelem in elem:bndbox['xmin'] = Nonebndbox['xmax'] = Nonebndbox['ymin'] = Nonebndbox['ymax'] = Nonecurrent_sub = subelem.tagif current_parent == 'object' and subelem.tag == 'name':object_name = subelem.textif object_name not in category_set:current_category_id = addCatItem(object_name)else:current_category_id = category_set[object_name]elif current_parent == 'size':if size[subelem.tag] is not None:raise Exception('xml structure broken at size tag.')size[subelem.tag] = int(subelem.text)# option is <xmin>, <ymin>, <xmax>, <ymax>, when subelem is <bndbox>for option in subelem:if current_sub == 'bndbox':if bndbox[option.tag] is not None:raise Exception('xml structure corrupted at bndbox tag.')bndbox[option.tag] = int(option.text)# only after parse the <object> tagif bndbox['xmin'] is not None:if object_name is None:raise Exception('xml structure broken at bndbox tag')if current_image_id is None:raise Exception('xml structure broken at bndbox tag')if current_category_id is None:raise Exception('xml structure broken at bndbox tag')bbox = []# xbbox.append(bndbox['xmin'])# ybbox.append(bndbox['ymin'])# wbbox.append(bndbox['xmax'] - bndbox['xmin'])# hbbox.append(bndbox['ymax'] - bndbox['ymin'])print('add annotation with {},{},{},{}'.format(object_name, current_image_id, current_category_id,bbox))addAnnoItem(object_name, current_image_id, current_category_id, bbox)if __name__ == '__main__':xml_path = './datasets/RoadSignsPascalVOC/Annotations' # 这是xml文件所在的地址json_file = './datasets/RoadSignsPascalVOC_Coco/Annotations/train.json' # 这是你用xml_path下的xml文件生成的json文件 parseXmlFiles(xml_path) # 只需要改动这两个参数就行了json.dump(coco, open(json_file, 'w'))

转换好的coco格式的json文件我还未在训练中验证,但是我将转换后的json文件又通过第一份转voc的代码又转回voc格式,部署到训练中没有问题。

voc数据格式的处理

首先你的voc格式的数据集目录应该是这样的:

——annotations

——ImageSets

————Main

——images

其中annotations为你的xml标注文件,images为你的图片目录。

Main中保存划分数据集后的txt文件

来看看process_dataset.py中的代码:

'''Author: TuZhouVersion: 1.0Date: -08-21 19:53:22LastEditTime: -08-29 17:05:35LastEditors: TuZhouDescription: 划分数据集,将xml文件中的标注信息提取出与图片路径保存到新的txt文件中FilePath: \My_Yolo\datasets\process_dataset.py'''from pathlib import Pathimport yamlimport xml.etree.ElementTree as ETfrom os import getcwdimport osimport random random.seed()#自定义数据集配置文件的路径yaml_path = './cfg/dataset.yaml'#----------------------------------------------------------------------## 想要增加测试集修改trainval_percent# train_percent不需要修改#----------------------------------------------------------------------#trainval_percent = 0.9 #所有数据集中训练集+验证集的比例train_percent = 1 #训练集+验证集中训练集的比例(可不管)默认1即可'''Author: TuZhouDescription: 读取数据集配置文件param {*} yaml_pathreturn {*}返回配置文件中信息字典'''def read_dataset_yaml(yaml_path = './cfg/dataset.yaml'):yaml_file = Path(yaml_path)with open(yaml_file, encoding='utf-8') as f:yaml_dict = yaml.safe_load(f)return yaml_dict'''Author: TuZhouDescription: 从数据集中划分训练集,验证集,测试集,txt文件保存在ImageSets的Main文件夹中param {*} xmlfilepath 数据集xml标注文件保存路径param {*} saveSplitePath 数据集划分txt文件保存路径return {*}'''def splite_dataset(xmlfilepath, saveSplitePath):#读取所有xml文件,存入列表中temp_xml = os.listdir(xmlfilepath)total_xml = []for xml in temp_xml:if xml.endswith(".xml"):total_xml.append(xml)#图片总数num = len(total_xml) list = range(num) numbers_tv = int(num * trainval_percent) #获取训练和验证集数量numbers_train = int(numbers_tv * train_percent) random.seed()trainval = random.sample(list, numbers_tv)#从list中选取生成训练验证集的随机列表 random.seed()train = random.sample(trainval, numbers_train) #从训练验证集中选取生成训练集的随机列表print("train and val size: ", numbers_tv)print("train size: ", numbers_train)print("test size: ", num - numbers_tv)ftrainval = open(os.path.join(saveSplitePath,'trainval.txt'), 'w') ftest = open(os.path.join(saveSplitePath,'test.txt'), 'w') ftrain = open(os.path.join(saveSplitePath,'train.txt'), 'w') fval = open(os.path.join(saveSplitePath,'val.txt'), 'w') for i in list: name=total_xml[i][:-4]+'\n' if i in trainval: ftrainval.write(name) if i in train: ftrain.write(name) else: fval.write(name) else: ftest.write(name) ftrainval.close() ftrain.close() fval.close() ftest .close()def convert_annotation(xmlfilepath, image_id, list_file, classes):#in_file = open('VOCdevkit/VOC%s/Annotations/%s.xml'%(year, image_id), encoding='utf-8')in_file = open(xmlfilepath + '%s.xml'%(image_id), encoding='utf-8')tree=ET.parse(in_file)root = tree.getroot()for obj in root.iter('object'):difficult = 0 if obj.find('difficult')!=None:difficult = obj.find('difficult').textcls = obj.find('name').textif cls not in classes or int(difficult)==1:continuecls_id = classes.index(cls)xmlbox = obj.find('bndbox')b = (int(float(xmlbox.find('xmin').text)), int(float(xmlbox.find('ymin').text)), int(float(xmlbox.find('xmax').text)), int(float(xmlbox.find('ymax').text)))list_file.write(" " + ",".join([str(a) for a in b]) + ',' + str(cls_id))#print(" " + ",".join([str(a) for a in b]) + ',' + str(cls_id))def save_dataset_info(yaml_dict):wd = getcwd()sets = yaml_dict['sets']saveSplitePath = yaml_dict['saveSplitePath']xmlfilepath = yaml_dict['xmlfilepath']processedPath = yaml_dict['DatasetPath']ImagesDir = yaml_dict['ImagesDir']classes = yaml_dict['classes']image_format = yaml_dict['image_format']for image_set in sets:# image_ids = open('VOCdevkit/VOC%s/ImageSets/Main/%s.txt'%(year, image_set), encoding='utf-8').read().strip().split()# list_file = open('%s_%s.txt'%(year, image_set), 'w', encoding='utf-8')#读取划分后的图片名文件image_ids = open(saveSplitePath + '%s.txt'%(image_set), encoding='utf-8').read().strip().split()#创建要保存路径和标注的txt文件list_file = open(processedPath + '%s.txt'%(image_set), 'w', encoding='utf-8')for image_id in image_ids:#list_file.write('%s/VOCdevkit/VOC%s/JPEGImages/%s.jpg'%(wd, year, image_id))list_file.write(wd + ImagesDir + image_id + image_format)convert_annotation(xmlfilepath, image_id, list_file, classes)list_file.write('\n')list_file.close()if __name__ == '__main__':yaml_dict = read_dataset_yaml(yaml_path)#划分数据集xmlfilepath, saveSplitePath = yaml_dict['xmlfilepath'], yaml_dict['saveSplitePath']splite_dataset(xmlfilepath, saveSplitePath)#保存数据集信息,即图片路径以及标注信息save_dataset_info(yaml_dict)

注意我对路径的一些配置保存在dataset.yaml文件中,你可先创建一个yaml文件保存一些配置。比如我的:

#数据集配置文件信息#数据集xml标注文件保存路径xmlfilepath: './datasets/RoadSignsPascalVOC_Voc/annotations/'#数据集划分保存路径saveSplitePath: './datasets/RoadSignsPascalVOC_Voc/ImageSets/Main/'#数据集目录DatasetPath: './datasets/RoadSignsPascalVOC_Voc/'#图片路径,注意该路径开头前面要拼接根目录路径的,所以前面不要加'.'了ImagesDir: '/datasets/RoadSignsPascalVOC_Voc/images/' #图片的格式image_format: '.png'# 分类种类数量numbers_classes: 4# 分类名classes: ["trafficlight", "stop", "speedlimit", "crosswalk"]#classes: ["hero", "grass", "wild_monster", "dragon", "soldier", "tower", "buff", "crystal"]#处理后的文件名,存放图片保存路径以及其对应的标注信息,可默认不修改#sets: [('', 'train'), ('', 'val'), ('', 'test')]sets: ['train', 'val', 'test']

经过处理后你的数据集会被划分,并且xml文件中的内容会被提取出来。

Main文件夹中会生成这么几个文件:

里面保存的是划分后的图片文件名。

另外在你的数据集目录下会生成存储提取的xml信息的txt文件。

其中保存了每张图片的路径以及该图片的标注信息。

前面为图片路径,后面每五个数字为一组,表示图片中目标的左上角右下角x,y坐标以及对应的类别。

如果要处理的voc数据集中全部为测试集,可以更改process_dataset.py中的trainval_percent变量,将其赋值为0即可。

txt注释格式转coco

有的人拿到的数据集既不是voc,也不是coco格式,就直接就是处理好的txt格式,但是代码却是coco数据集或者voc数据集处理的形式,对于编码困难的可以试试以下转换方法,可以将txt转为coco,如果是voc格式,可以先转coco再通过上面的coco转voc再转换为voc格式。

注意你的txt注释文件形式是这样的:

annotations.txt:

图片文件名 x1 y1 x2 y2 label…

从左到右为图片文件名,目标左上角x坐标,目标左上角y坐标,目标右下角x坐标,目标右下角y坐标,目标所属类别

注意我的label是直接就是类别名,而不是int编号,为编号的直接category_id等于label就可

代码中几处需要修改的部分已经使用TODO中的NOTE标注出来了。

'''Author: TuZhouVersion: 1.0Date: -09-11 16:50:47LastEditTime: -09-12 09:42:32LastEditors: TuZhouDescription: FilePath: \python_test\txt_to_coco.py'''import jsonimport cv2import pathimport os#第一个coco json类型bnd_id_start = 1#NOTE:你的分类class_map = {"tamper":0}#你的图片id,可自定义my_image_id = 0000000times = 0json_dict = {"images": [],"type" : "instances","annotations": [],"categories" : []}'''Author: TuZhouDescription: param {*} L1:你的标注列表信息,注意只包含x1,y1,x2,y2,label,如[234,43,345,213,'person',34,54,23,34,'dog']param {*} numbers:你要切分的长度,x1,y1,x2,y2,label长度为5return {*}返回包含所有目标信息的二维列表'''def get_list_value(L1, numbers):obj_list = []for i in range(0, len(L1), numbers):l2 = L1[i: i + numbers]obj_list.append(l2)return obj_list# NOTE:这里是你的txt文件的读取with open(r'E:\user\baidu_pan\CASIA_object_detection\annotations.txt','r') as f:data = f.readlines()bnd_id = bnd_id_start#NOTE:这是你的图片格式,如果支持多种图片文件images_format = ['.jpg', '.tif']for d in data:content = d.strip().split(" ")print(content)filename = content[0]#这里可能修改,txt文件每一行第一个属性是图片路径,通过split()函数把图像名分离出来就行for image_format in images_format:#NOTE:你的图片文件路径要改image_path = 'E:\\user\\baidu_pan\\CASIA_object_detection\\CAISA_Train_Images\\' + content[0] + image_formatif os.path.exists(image_path):breakimg = cv2.imread(image_path)print(image_path)try:height,width = img.shape[0],img.shape[1]image_id = my_image_idmy_image_id += 1except:times +=1print('file is error')# type 已经填充#定义image 填充到images里面image = {'file_name' : filename, #文件名'height' : height, #图片的高'width': width,#图片的宽'id' : image_id #图片的id,和图片名对应的}json_dict['images'].append(image)#print(content[5])# start_index = 1# if start_index != len(content) - 1:obj_lists = get_list_value(content[1:],5)for obj_list in obj_lists:#print(c)#xmin,ymin,xmax,ymax,label = c.strip().split(" ")xmin = int(obj_list[0])ymin = int(obj_list[1])xmax = int(obj_list[2])ymax = int(obj_list[3])o_width = abs(int(xmax) - int(xmin))o_height = abs(int(ymax) - int(ymin))area = o_width * o_heightcategory_id = class_map[obj_list[4]]# #定义annotationhbannotation = {'area': area, #'iscrowd' : 0,'image_id': image_id, #图片的id'bbox':[xmin, ymin, o_width,o_height],'category_id' : int(category_id), #类别的id 通过这个id去查找category里面的name'id' : bnd_id, #唯一id ,可以理解为一个框一个Id'ignore' : 0,'segmentation' : []}print(category_id)json_dict['annotations'].append(annotation)bnd_id += 1##定义categories#你得类的名字(cid,cate)对应classes = ['tamper']for i in range(len(classes)):cate = classes[i]cid = icategory = {'supercategory' : 'none','id' : cid, #类别的id ,一个索引,主键作用,和别的字段之间的桥梁'name': cate #类别的名字比如房子,船,汽车}json_dict['categories'].append(category)json_fp = open("train.json",'w')json_str = json.dumps(json_dict)json_fp.write(json_str)json_fp.close()

我知道还有的小伙伴的txt文件注释格式可以和我的不一样,是不是这样的?

image_path xmin,ymin,xmax,ymax,label …

首个是图片路径而不是图片名,坐标等信息时通过逗号分隔而不是空格。

问题不大,代码很好改。

'''Author: TuZhouVersion: 1.0Date: -01-14 10:10:06LastEditTime: -01-14 10:58:49LastEditors: TuZhouDescription: FilePath: \My_Mobile_csp_Yolo2\datasets\txt_to_coco.py'''import jsonimport cv2#第一个coco json类型bnd_id_start = 1times = 0#分类部分在下面的代码#你的图片id,可自定义my_image_id = 0000000json_dict = {"images": [],"type" : "instances","annotations": [],"categories" : []}# 这里是你的txt文件的读取with open(r'C:\Users\TuZhou\Desktop\desktop_code\My_Mobile_csp_Yolo2\datasets\RoadSignsPascalVOC\train.txt','r') as f:data = f.readlines()bnd_id = bnd_id_startfor d in data:content = d.split(" ")filename = content[0].split("/")[-1]#这里可能修改,txt文件每一行第一个属性是图片路径,通过split()函数把图像名分离出来就行img = cv2.imread(content[0])try:height,width = img.shape[0],img.shape[1]image_id = my_image_idmy_image_id += 1except:times +=1print('file is error')# type 已经填充#定义image 填充到images里面image = {'file_name' : filename, #文件名'height' : height, #图片的高'width': width,#图片的宽'id' : image_id #图片的id,和图片名对应的}json_dict['images'].append(image)#for c in content[1:]:#NOTE:注意这里你的坐标信息是通过逗号隔开,所以split(","),但是你也许是通过空格隔开,直接split(" ")就可。xmin,ymin,xmax,ymax,label = c.strip().split(",")xmin = int(xmin)ymin = int(ymin)xmax = int(xmax)ymax = int(ymax)o_width = abs(int(xmax) - int(xmin))o_height = abs(int(ymax) - int(ymin))area = o_width * o_heightcategory_id = label.strip()# #定义annotationhbannotation = {'area': area, #'iscrowd' : 0,'image_id': image_id, #图片的id'bbox':[xmin, ymin, o_width,o_height],'category_id' : int(category_id), #类别的id 通过这个id去查找category里面的name'id' : bnd_id, #唯一id ,可以理解为一个框一个Id'ignore' : 0,'segmentation' : []}print(category_id)json_dict['annotations'].append(annotation)bnd_id += 1##定义categories#NOTE:你得类的名字(cid,cate)对应# classes = ['0','1','2','3']classes = ["trafficlight", "stop", "speedlimit", "crosswalk"]for i in range(len(classes)):cate = classes[i]cid = icategory = {'supercategory' : 'none','id' : cid, #类别的id ,一个索引,主键作用,和别的字段之间的桥梁'name': cate #类别的名字比如房子,船,汽车}json_dict['categories'].append(category)json_fp = open(r"C:\Users\TuZhou\Desktop\desktop_code\My_Mobile_csp_Yolo2\datasets\RoadSignsPascalVOC\train.json",'w')json_str = json.dumps(json_dict)json_fp.write(json_str)json_fp.close()

参考1

参考2

参考3

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。