Convert YOLO format to VOC format

Table of contents

Preface

1. Introduction to VOC format and YOLO format?

1.VOC format

2.YOLO format

2. Usage steps

1. Import the library

2. Set the file address and image information

3. Traverse and parse YOLO files

4. Create XML file and write information

5.Total code

 



Preface

This article describes how to convert YOLO format to XML format. See another article for converting XML format to YOLO format.


1. Introduction to VOC format and YOLO format?

1.VOC format

The format of the VOC data set is XML format. The following is an example:

<annotation>
   <folder>img</folder>
   <filename>pikaqiu.jpg</filename>
   <path>E:\cv_code\image_processing\test\img\pikaqiu.jpg</path>
   <source>
      <database>Unknown</database>
   </source>
   <size>
      <width>1062</width>
      <height>974</height>
      <depth>3</depth>
   </size>
   <segmented>0</segmented>
   <object>
      <name>pikaqiu</name>
      <pose>Unspecified</pose>
      <truncated>0</truncated>
      <difficult>0</difficult>
      <bndbox>
         <xmin>83</xmin>
         <ymin>74</ymin>
         <xmax>987</xmax>
         <ymax>920</ymax>
      </bndbox>
   </object>
</annotation>

The information we need to use includes the picture name: <filename>pikaqiu.jpg</filename>, the width, height, and channel number information of the picture: <size> <width>1062</width> <height>974</height > <depth>3</depth> </size>, category name: <name>pikaqiu</name>, box information: <xmin>83</xmin> <ymin>74</ymin> <xmax>987< /xmax> <ymax>920</ymax>.

2.YOLO format

(class,xCenter,yCenter,w,h), which respectively represent the internal classification, the center coordinates of the label box, and the relative width and length of the label box.

2. Usage steps

1. Import the library

import xml.etree.ElementTree as ET
import os

2. Set the file address and image information

# Yolo格式文件所在目录
yolo_dir = "E:/cv_code/image_processing/aug_datasets/label/"
# XML文件保存目录
xml_dir = "E:/cv_code/image_processing/aug_datasets/Annotations/"
# 图像尺寸
img_width, img_height = 1062, 974

# 类别数字标签和名称的映射
class_map = {"pikaqiu": 0}

3. Traverse and parse YOLO files

# 遍历Yolo格式文件夹中的所有文件
for yolo_file in os.listdir(yolo_dir):
    if not yolo_file.endswith(".txt"):
        continue

    # 解析Yolo格式文件
    with open(os.path.join(yolo_dir, yolo_file), "r") as f:
        lines = f.readlines()

    # 获取图像名称
    img_file = os.path.splitext(yolo_file)[0] + ".jpg"

4. Create XML file and write information

xmin=width*(x-0.5w)

ymin=height*(y-0.5h)

xmax=weight*(x+0.5w)

ymax=height*(y+0.5h)

    # 创建XML文件
    #创建根节点
    root = ET.Element("annotation")
    #创建子节点
    filename = ET.SubElement(root, "filename")
    #添加文本
    filename.text = img_file
    size = ET.SubElement(root, "size")
    width = ET.SubElement(size, "width")
    width.text = str(img_width)
    height = ET.SubElement(size, "height")
    height.text = str(img_height)
    depth = ET.SubElement(size, "depth")
    depth.text = "3"

    # 遍历所有目标
    for line in lines:
        parts = line.strip().split()
        if len(parts) < 5:
            continue

        cls_id = int(parts[0])


        if cls_id  in class_map:
            continue

        for k, v in class_map.items():
            cls_name = None
            if v == cls_id:
                cls_name = k
                break

        # cls_name = class_map[cls_id]
        x = float(parts[1])
        y = float(parts[2])
        w = float(parts[3])
        h = float(parts[4])

        # 计算边界框坐标
        xmin = int((x - w / 2) * img_width)
        ymin = int((y - h / 2) * img_height)
        xmax = int((x + w / 2) * img_width)
        ymax = int((y + h / 2) * img_height)

        # 将信息写入XML文件
        obj = ET.SubElement(root, "object")
        name = ET.SubElement(obj, "name")
        name.text = cls_name
        bndbox = ET.SubElement(obj, "bndbox")
        xmin_node = ET.SubElement(bndbox, "xmin")
        xmin_node.text = str(xmin)
        ymin_node = ET.SubElement(bndbox, "ymin")
        ymin_node.text = str(ymin)
        xmax_node = ET.SubElement(bndbox, "xmax")
        xmax_node.text = str(xmax)
        ymax_node = ET.SubElement(bndbox, "ymax")
        ymax_node.text = str(ymax)
    #将树写入文件
    tree = ET.ElementTree(root)
    tree.write(xml_dir + os.path.splitext(yolo_file)[0] + ".xml")

5.Total code

import os
import xml.etree.ElementTree as ET

# Yolo格式文件所在目录
yolo_dir = "E:/cv_code/image_processing/aug_datasets/label/"
# XML文件保存目录
xml_dir = "E:/cv_code/image_processing/aug_datasets/Annotations/"
# 图像尺寸
img_width, img_height = 1062, 974

# 类别数字标签和名称的映射
class_map = {"pikaqiu": 0}

# 遍历Yolo格式文件夹中的所有文件
for yolo_file in os.listdir(yolo_dir):
    if not yolo_file.endswith(".txt"):
        continue

    # 解析Yolo格式文件
    with open(os.path.join(yolo_dir, yolo_file), "r") as f:
        lines = f.readlines()

    # 获取图像文件名
    img_file = os.path.splitext(yolo_file)[0] + ".jpg"

    # 创建XML文件
    #创建根节点
    root = ET.Element("annotation")
    #创建子节点
    filename = ET.SubElement(root, "filename")
    #添加文本
    filename.text = img_file
    size = ET.SubElement(root, "size")
    width = ET.SubElement(size, "width")
    width.text = str(img_width)
    height = ET.SubElement(size, "height")
    height.text = str(img_height)
    depth = ET.SubElement(size, "depth")
    depth.text = "3"

    # 遍历所有目标
    for line in lines:
        parts = line.strip().split()
        if len(parts) < 5:
            continue

        cls_id = int(parts[0])

        if cls_id  in class_map:
            continue

        for k, v in class_map.items():
            cls_name = None
            if v == cls_id:
                cls_name = k
                break

        x = float(parts[1])
        y = float(parts[2])
        w = float(parts[3])
        h = float(parts[4])

        # 计算边界框坐标
        xmin = int((x - w / 2) * img_width)
        ymin = int((y - h / 2) * img_height)
        xmax = int((x + w / 2) * img_width)
        ymax = int((y + h / 2) * img_height)

        # 将信息写入XML文件
        obj = ET.SubElement(root, "object")
        name = ET.SubElement(obj, "name")
        name.text = cls_name
        bndbox = ET.SubElement(obj, "bndbox")
        xmin_node = ET.SubElement(bndbox, "xmin")
        xmin_node.text = str(xmin)
        ymin_node = ET.SubElement(bndbox, "ymin")
        ymin_node.text = str(ymin)
        xmax_node = ET.SubElement(bndbox, "xmax")
        xmax_node.text = str(xmax)
        ymax_node = ET.SubElement(bndbox, "ymax")
        ymax_node.text = str(ymax)
    #将数据写入文件
    tree = ET.ElementTree(root)
    tree.write(xml_dir + os.path.splitext(yolo_file)[0] + ".xml")

 

Guess you like

Origin blog.csdn.net/qq_51511878/article/details/129791739