目标检测数据集json和xml格式互转

本文内容: coco数据集格式json文件转xml文件 (针对目标检测框)
xml或者yolo格式标签转labelme的json文件格式

COCO数据集的格式

annotation.json文件内容,主要有四个部分需要关注。

{
   
    "categories": [   // 类别组,是一个列表,长度等于类别数。列表的每个元素存放的是数据集的类别,每个类别又是一个字典格式
        {
   
            "supercategory": "父类",  // 该项表示类别的父类 如果不是特殊情况,通常可以与name相同
            "id": 1,             // 该项表示类别的序号
            "name": "类别1的名字"  // 该项表示类别的名字 
        },
          {
   
            "supercategory": "父类",  
            "id": 2,             
            "name": "类别2"  
        }
    ],
    
      "images"[   // 图像组,也是一个字典组成的列表。 长度是数据集中的图像数量
    {
   
            "file_name": "img_0175153.jpg",  // 该项表示图像文件名
            "width": 4096,  // 图像宽高
            "id": 1,         // 图像的id序号,这个序号是人为规定的,比如,有n张图,id从1变化到n
            "height": 3000
        },
        {
   
            "file_name": "img_0172993.jpg",
            "width": 4096,
            "id": 2,
            "height": 3000
        }
    ],

 "annotations": [  // 标注部分 也是字典构成的列表,它的长度不等于图像文件名,而是 每一个图像的每一个目标 作为列表元素,因此,该列表的长度是 数据集中全部目标的数量
        {
   
            "area": 2993,  // 该目标区域的面积
            "iscrowd": 0,  // 是否分块,如果是1,表示一组对象。即该目标被遮挡导致有多个小块
            "image_id": 1,  // 图片的序号id
            "bbox": [  // 该区域的mask外接矩形
                2500,
                1268,
                41,
                73
            ],
            "segmentation":[[x1,y1,x2,y2,x3,y3] ],  // 掩膜轮廓区域坐标 每相邻xy表示一个点
            "category_id": 12,  // 目标的类别序号
            "id": 1  // 目标的序号id,即在annotation类别中的序号。
        },
}

coco的json标签转xml文件

从coco转换到xml格式,只需要从json文件中提取到图像的信息,包括文件名/路径、宽高和标注信息,标注信息只需要类别id和区域的bbox。

具体代码如下,pretty_xml是用于缩进xml文件,进行美化(忘了是在哪个博客看到的了)。write函数用于写入一个xml文件,函数接受一个字典输入info,其key是图像名,value是一个列表,每个元素是图像中的一个目标,以x y w h label的顺序表示,或者x1 y1 x2 y2 label的顺序,shape参数是该图像的hwc,如果没有传入,会试图通过读取文件名来获取该信息。

写入xml的内容都必须是字符串,不能是整数或者浮点数,因此write函数中写入一些数字类型的数据,如坐标、宽高等要转成str。

import time
import cv2
import numpy as np
from PIL import Image
import json
import xml.etree.ElementTree as ET 
import random

def pretty_xml(element, indent, newline, level=0):  # elemnt为传进来的Elment类,参数indent用于缩进,newline用于换行
    if element:  # 判断element是否有子元素    
        if (element.text is None) or element.text.isspace():  # 如果element的text没有内容
            element.text = newline + indent * (level + 1)
        else:
            element.text = newline + indent * (level + 1) + element.text.strip() + newline + indent * (level + 1)
            # else:  # 此处两行如果把注释去掉,Element的text也会另起一行
            # element.text = newline + indent * (level + 1) + element.text.strip() + newline + indent * level
    temp = list(element)  # 将element转成list
    for subelement in temp:
        if temp.index(subelement) < (len(temp) - 1):  # 如果不是list的最后一个元素,说明下一个行是同级别元素的起始,缩进应一致
            subelement.tail = newline + indent * (level + 1)
        else:  # 如果是list的最后一个元素, 说明下一行是母元素的结束,缩进应该少一个    
            subelement.tail = newline + indent * level
        pretty_xml(subelement, indent, newline, level=level + 1)  # 对子元素进行递归操作



# 送入的是dict {图像名字 :框信息} 框信息是[[x1,y1,w,h,label], [x1,y1,w,h,label],[]]
def write(infos,shape=None):

    root = ET.Element('annotation'
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值