coco数据集的voc数据集的相互转化

在训练自己的数据集时,难免要将数据集制作成标准数据集,现在主要流行的有两种coco和voc

一,coco数据集转voc数据集

coco数据集主要是由图片目录和标注文件.json格式组成
之前在网上找的用pycocotools的转换代码,在训练时出现错误,说标注问题??
我百思不得其解,于是想起用labelimg打开标注文件和图片,发现竟然没有框,证明转换失败了,于是自己用json写了个:


from xml.dom import minidom
import json
import glob
import os
from shutil import copyfile
# 将self.orderDict中的信息写入本地xml文件,参数filename是xml文件名

def Convert_coco_to_voc(annotation_path,JPEGImage_path,out_path):
    '''
    将coco数据转换为voc数据
    :param annotation_path:coco标记文件的地址
    :param JPEGImage_path: coco图片数据集的位置
    :param out_path: 生成的voc数据集保存的位置
    :return:
    '''
    #先创建voc输出文件夹标准格式
    outdir = out_path
    # 创建各级文件夹
    train_xml_out = os.path.join(outdir, 'VOC2007/Annotations')
    if not os.path.exists(train_xml_out ):
        os.makedirs(train_xml_out)
    train_img_out = os.path.join(outdir, 'VOC2007/JPEGImages')
    if not os.path.exists(train_img_out):
        os.makedirs(train_img_out)


    data = json.load(open(annotation_path, 'r'))
    imgs = data['images']
    annotations = data['annotations']
    categorie=data["categories"]
    cate_list=list()
    print('JSON文件中_图片总数:' + str(len(imgs)))
    for i  in range(len(categorie)):
        for ca in categorie:
            if ca["id"]==i:
                cate_list.append(ca["supercategory"])
    print("JSON文件中_标注类别:" + str(cate_list))

    #遍历图片json列表
    for img in imgs:
        filename = img['file_name']
        print(filename)
        img_w = img['width']
        img_h = img['height']
        img_id = img['id']
        ana_txt_name = filename.split('.')[0] + '.txt'
        roi_list=list()
        #遍历图片标注信息列表
        for ann in annotations:
            if ann['image_id'] == img_id:
                #图片和标记匹配
                box = convert_boxshape((img_w, img_h), ann['bbox'])
                roi_list.append([cate_list[ann['category_id']],box[0], box[1], box[2], box[3]])
                print(box)
        get_xml(filename, [img_w,img_h,3], roi_list,train_xml_out)
        copyfile(os.path.join(JPEGImage_path, filename),os.path.join(train_img_out, filename,))
def convert_boxshape(size, box):
    '''
    coco数据集标注是xmin,ymin,width,height 而voc和yolo是xmin ymin xmax ynax 需要进行转换
    :param size: 图片宽 图片高
    :param box:
    :return:
    '''
    dw = size[0]   # 图像实际宽度
    dh = size[1]  # 图像实际高度
    #x=box[0]
    #y=box[1]
    x = box[0]  #标注区域X坐标
    y = box[1]  #标注区域Y坐标
    w = box[2]   # 标注区域宽度
    h = box[3]   #标注区域高度

    xmin=int(x)
    ymin=int(y)
    xmax=int(x+w)
    ymax=int(y+h)
    return (xmin, ymin, xmax, ymax)


def get_xml(img_name,size,roi,outpath):
    '''
    传入每张图片的名称 大小 和标记点列表生成和图片名相同的xml标记文件
    :param img_name: 图片名称
    :param size:[width,height,depth]
    :param roi:[["label1",xmin,ymin,xmax,ymax]["label2",xmin,ymin,xmax,ymax].....]
    :return:
    '''
    impl = minidom.getDOMImplementation()
    doc = impl.createDocument(None, None, None)
    #创建根节点
    orderlist = doc.createElement("annotation")
    doc.appendChild(orderlist)
    #c创建二级节点
    filename=doc.createElement("filename")
    filename.appendChild(doc.createTextNode(img_name))
    orderlist.appendChild(filename)
    #size节点
    sizes=doc.createElement("size")
    width=doc.createElement("width")
    width.appendChild(doc.createTextNode(str(size[0])))
    height=doc.createElement("height")
    height.appendChild(doc.createTextNode(str(size[1])))
    depth=doc.createElement("depth")
    depth.appendChild(doc.createTextNode(str(size[2])))
    sizes.appendChild(width)
    sizes.appendChild(height)
    sizes.appendChild(depth)
    orderlist.appendChild(sizes)
    #object 节点
    for ri in roi:
        object=doc.createElement("object")
        name=doc.createElement("name")
        name.appendChild(doc.createTextNode(ri[0]))
        object.appendChild(name)
        bndbox=doc.createElement("bndbox")

        xmin=doc.createElement("xmin")
        xmin.appendChild(doc.createTextNode(str(ri[1])))
        bndbox.appendChild(xmin)
        ymin=doc.createElement("ymin")
        ymin.appendChild(doc.createTextNode(str(ri[2])))
        bndbox.appendChild(ymin)
        xmax=doc.createElement("xmax")
        xmax.appendChild(doc.createTextNode(str(ri[3])))
        bndbox.appendChild(xmax)
        ymax=doc.createElement("ymax")
        ymax.appendChild(doc.createTextNode(str(ri[4])))
        bndbox.appendChild(ymax)
        object.appendChild(bndbox)
        orderlist.appendChild(object)
         # 将dom对象写入本地xml文件

    # 打开test.xml文件 准备写入
    f = open(os.path.join(outpath,img_name[:-4]+'.xml'), 'w')
    # 写入文件
    doc.writexml(f, addindent='  ', newl='\n')
    # 关闭
    f.close()

if __name__ == "__main__":
    #传入coco的annotations.json地址,image文件存放的地址 和输出的voc数据存放地址
    Convert_coco_to_voc("C:/Users/chengyangkj/Desktop/chongqing1_round1_train1_20191223/annotations.json","C:/Users/chengyangkj/Desktop/chongqing1_round1_train1_20191223/images","C:/Users/chengyangkj/Desktop/testout",)

注意标注名不能为中文,这样转换后的voc数据集终于就能在labelimg中成功打开了

二,voc数据集转coco数据集

待完善…

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值