【制作coco数据集】

        由于最近任务的模型需要采用coco数据集格式,只能将现有数据的xml格式进行转换。查阅了网上很多xml转coco数据集的资料,由于每个人都数据集格式都不一样,发现其实很多细节都对不上,还是得自己重新写一个代码确保最后数据集格式的正确性。记录一下自己的工作。

此处反复研究了coco数据集的格式,主要参考以下两个帖子:

https://blog.csdn.net/weixin_44052271/article/details/120475779
https://blog.csdn.net/weixin_50727642/article/details/122892088

首先先创建一个用于储存数据的图片类似coco数据集的文件夹,包括了以下几个文件夹,我这里训练和验证集已经分好了,不用重新分,所以直接把图片复制粘贴到对应文件夹下就好了

       然后再把所有图片和对应xml的名字都改成000000000001 这种形式,一开始没改,名字里面有字母,对应json文件里面的id就是一串字符,然后模型训练就报错了,所以经验就是改了最好。然后再统一一下图片格式都转化为jpg。

        xml标注文件类似:

 以下是进行转换完整代码

import json
from xml.dom.minidom import parse
import os

def open_xml(xml_path,id):#从xml获得filename,height,width
    domTree = parse(xml_path)
    # 获得根节点
    rootNode = domTree.documentElement
    filename=rootNode.getElementsByTagName('filename')[0].childNodes[0].data
    size=rootNode.getElementsByTagName('size')
    h=size[0].getElementsByTagName('height')[0].childNodes[0].data
    w=size[0].getElementsByTagName('width')[0].childNodes[0].data
    id=id  #id获取重复了,懒得删
    return filename,h,w,id

def images_json(filename,h,w,id):#每张图片生成一个image字典添加到dict_total={'images':[]中
    images={
                'file_name': '',
                'height': 0,
                'width': 0,
                'id':0
            }
    images['file_name']=filename
    images['height']=int(h)
    images['width'] =int(w)
    images['id']=int(id)
    return images

def categories_json():
    categories=[
        {'supercategory': 'person', 'id': 1, 'name': 'mask'},
        {'supercategory': 'person', 'id': 2, 'name': 'nomask'}]
    return categories

def extract_xml(xml_path,id):#得到annotations里的对应信息
    id=id
    area=[]
    box=[]
    name=[]
    domTree = parse(xml_path)
    # 获得根节点
    rootNode = domTree.documentElement
    object = rootNode.getElementsByTagName('object')
    for i in range(len(object)):
        name_item=object[i].getElementsByTagName('name')[0].childNodes[0].data
        name.append(name_item)
        box_xmin=object[i].getElementsByTagName('bndbox')[0].getElementsByTagName('xmin')[0].childNodes[0].data
        box_ymin=object[i].getElementsByTagName('bndbox')[0].getElementsByTagName('ymin')[0].childNodes[0].data
        box_xmax=object[i].getElementsByTagName('bndbox')[0].getElementsByTagName('xmax')[0].childNodes[0].data
        box_ymax=object[i].getElementsByTagName('bndbox')[0].getElementsByTagName('ymax')[0].childNodes[0].data
        area_item=(float(box_xmax)-float(box_xmin))*(float(box_ymax)-float(box_ymin))
        area.append(float(area_item))
        w=float(box_xmax)-float(box_xmin)
        h=float(box_ymax)-float(box_ymin)
        box_item=[float(box_xmin),float(box_ymin),w,h]
        box.append(box_item)
    return  area,id,box,name,len(object)

def annotations_json(area,id,box,name,count):
    annotations={
        'segmentation': [[]],  #忽略
        'area': 240.000,   #面积需要计算
        'iscrowd': 0,    #忽略
        'image_id': 289343,   #就是id
        'bbox': [0., 0., 60., 40.],
        'category_id': 1,
        'id': 1768}  #bbbox序号
    annotations['area']=float(area)
    annotations['image_id'] = int(id)
    annotations['bbox'] = box
    if name=='mask':
        annotations['category_id'] = 1
    else:
        annotations['category_id'] = 2
    annotations['id'] = count
    return annotations

url=r"C:\Users\dogbark\Desktop\datasets\val\Annotations"
file = os.listdir(url)
dict_total={'images':[],'annotations':[],'categories':[]}#总的json字典

for f in file:#这部分操作只生成了images字段
    real_url = os.path.join(url, f)
    id = os.path.splitext(f)
    _, h, w, id0 = open_xml(real_url, id[0])
    filename=id[0]+'.jpg'
    image = images_json(filename, h, w, id0)
    dict_total['images'].append(image)
print(len(dict_total['images'])) #检验生成字段数量是否完整

#接下来是categories字段
categories=categories_json()
dict_total['categories']=categories

#最后是annotations字段
count=0
for f in file:#这部分操作只生成了images字段
    real_url = os.path.join(url, f)
    id = os.path.splitext(f)
    area, id0, box, name,n= extract_xml(real_url, id[0])
    for j in range(n):
        count+=1
        annotations = annotations_json(area[j], id0, box[j], name[j], count)
        dict_total['annotations'].append(annotations)
print(count)

with open(r"C:\\Users\dogbark\Desktop\datasets\\record.json", "w") as f:
    json.dump(dict_total, f) #写入json文件
    print("加载入文件完成...")

        编程能力有待增强,有错的或者写的不简洁的地方勿怪。以上许多地方出现重复,主要因为是一个字段一个字段地生成,然后再在原本代码上添加新的字段生成的代码,还有一个比较悲惨的原因是以为队友能接手一下我的工作,每人完成一个字段生成的代码,结果发现他太慢了只能含泪自己一个人搞完,虽然工作不多,但是扣的细节不少还是很让人心烦。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值