VOC格式转COCO格式

VOC和coco格式数据集结构如下图:

 

 其中最主要的是 将VOC的xml文件转换成json格式,train.json中的信息由VOC-main-train.txt中的所有索引文件组成,val和test类似。本demo生成的json如下图:

附代码xml2json.py:

"""
    本脚本用于将VOC数据集转换成coco格式 ***仅限目标检测***
    代码适用于一个类别的情况
    如有多类需进行微调
"""
import json
import os
import xml.etree.ElementTree as ET

CATEGORIES = [
    {
        "category": "1",
        "id": 0,
        "name": "fire"
    },
]


def voc2coco(xml_path, txt_path, json_path):
    """
    本函数从txt_path中的txt文件读取需要处理的文件,在xml_path中找到对应文件写入json
    :param xml_path: xml文件的目录路径
    :param txt_path: txt的绝对路径,主要存放需要处理的文件名索引
    :param json_path: json保存的路径
    :return:
    """
    xml_files = os.listdir(xml_path)
    files_process = []
    with open(txt_path, 'r') as ft:
        for line in ft:
            line = line.rstrip('\n')
            files_process.append(line)

    coco_output = {
        "images": [],
        "categories": CATEGORIES,
        "annotations": []
    }

    annotation_id = 0
    image_id = 0
    is_crowd = 0
    for xml_file in xml_files:
        xml_t = os.path.join(xml_path, xml_file)
        tree = ET.parse(xml_t)
        root = tree.getroot()

        filename = root.find('filename').text
        if filename.split('.')[0] in files_process:
            print(f"Processing {image_id} pic: {filename}...")
            width = root.find('size').find('width').text
            height = root.find('size').find('height').text

            image_info = {
                "id": image_id,
                "file_name": filename,
                "width": width,
                "height": height,
            }
            coco_output["images"].append(image_info)

            category_id = 0  # 注意这里对多个类别需小作修改
            for obj in root.findall('object'):
                bndbox = obj.find('bndbox')
                xmin = int(bndbox.find('xmin').text)
                xmax = int(bndbox.find('xmax').text)
                ymin = int(bndbox.find('ymin').text)
                ymax = int(bndbox.find('ymax').text)
                x = int(xmin)
                y = int(ymin)
                w = int(xmax-xmin)
                h = int(ymax-ymin)
                bounding_box = [x,
                                y,
                                w,
                                h]
                annotation_info = {
                    "id": annotation_id,
                    "image_id": image_id,
                    "category_id": category_id,
                    "iscrowd": is_crowd,
                    "bbox": bounding_box,
                }
                coco_output['annotations'].append(annotation_info)
                save_path = os.path.join(json_path, "test.json")
                with open(save_path, 'w') as output_json_file:
                    json.dump(coco_output, output_json_file, indent=4)
                annotation_id += 1
            image_id += 1


if __name__ == '__main__':
    xml_path = r"E:\python_workdir\dataset\VOC2007\Annotations"
    txt_path = r"E:\python_workdir\dataset\VOC2007\ImageSets\Main\test.txt"
    json_path = r"E:\python_workdir\dataset\tmp_test\tmp_pth2"

    voc2coco(xml_path=xml_path, txt_path=txt_path, json_path=json_path)

注:本demo适用于单类的情况,如涉及多类,需要修改CATEGORIES以及增加一个记录class信息的输入。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
你可以使用一些工具和代码来将VOC格式的数据换为COCO格式,以便在mmdetection中使用。以下是一种可能的方法: 1. 首先,确保你已经安装了`mmcv`和`mmdet`库。你可以使用以下命令安装它们: ``` pip install mmcv-full mmdet ``` 2. 下载并解压VOC数据集,并将其组织为以下结构: ``` VOCdevkit/ ├── VOC2007 │ ├── Annotations │ ├── ImageSets │ └── JPEGImages └── VOC2012 ├── Annotations ├── ImageSets └── JPEGImages ``` 3. 创建一个Python脚本,例如`voc2coco.py`,并使用以下代码来进行VOCCOCO格式换: ```python import os import json from xml.etree.ElementTree import Element, SubElement, tostring from xml.dom.minidom import parseString def parse_voc_annotation(ann_dir, img_dir, labels=[]): # 读取VOC标注文件和图像文件夹 ann_files = sorted(os.listdir(ann_dir)) img_files = sorted(os.listdir(img_dir)) assert len(ann_files) == len(img_files), "Number of annotation files doesn't match number of image files" # 构建COCO格式标注数据结构 coco_data = { "images": [], "annotations": [], "categories": [] } category_id = 0 for i, ann_file in enumerate(ann_files): img_file = img_files[i] img_id = i + 1 # 解析VOC标注文件 ann_path = os.path.join(ann_dir, ann_file) tree = parseString(open(ann_path).read()) root = tree.documentElement # 获取图像信息 img_width = int(root.getElementsByTagName("width")[0].childNodes[0].data) img_height = int(root.getElementsByTagName("height")[0].childNodes[0].data) img_name = img_file.split(".")[0] # 添加图像信息到coco_data["images"] coco_data["images"].append({ "file_name": img_file, "height": img_height, "width": img_width, "id": img_id }) # 解析VOC标注信息 objects = root.getElementsByTagName("object") for obj in objects: name = obj.getElementsByTagName("name")[0].childNodes[0].data if name not in labels: labels.append(name) category_id = labels.index(name) + 1 bbox = obj.getElementsByTagName("bndbox")[0] xmin = int(bbox.getElementsByTagName("xmin")[0].childNodes[0].data) ymin = int(bbox.getElementsByTagName("ymin")[0].childNodes[0].data) xmax = int(bbox.getElementsByTagName("xmax")[0].childNodes[0].data) ymax = int(bbox.getElementsByTagName("ymax")[0].childNodes[0].data) width = xmax - xmin height = ymax - ymin # 添加标注信息到coco_data["annotations"] coco_data["annotations"].append({ "image_id": img_id, "category_id": category_id, "bbox": [xmin, ymin, width, height], "area": width * height, "iscrowd": 0, "id": len(coco_data["annotations"]) + 1 }) # 构建coco_data["categories"] for i, label in enumerate(labels): coco_data["categories"].append({ "id": i + 1, "name": label, "supercategory": "object" }) return coco_data if __name__ == '__main__': ann_dir = 'VOCdevkit/VOC2007/Annotations' img_dir = 'VOCdevkit/VOC2007/JPEGImages' labels = [] coco_data = parse_voc_annotation(ann_dir, img_dir, labels) # 保存为COCO格式JSON文件 with open('annotations.json', 'w') as f: json.dump(coco_data, f) ``` 4. 运行`voc2coco.py`脚本,它将生成一个名为`annotations.json`的COCO格式标注文件。 现在,你可以使用这个生成的COCO格式的标注文件在mmdetection中进行训练或评估。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值