1. 程式人生 > 其它 >標註資料集處理---Python製作VOC標註格式的xml標註檔案

標註資料集處理---Python製作VOC標註格式的xml標註檔案

引:

    近期做CV方面演算法,分享幾個簡單的視訊、圖片處理指令碼

    指令碼中均有print除錯程式碼,,方便更改

 

Python製作VOC格式xml的函式方法:

import os
import xml.dom.minidom


def write_xml(folder: str, img_name: str, path: str, img_width: int, img_height: int, tag_num: int, tag_name: str, box_list:list):
    '''
    VOC標註xml檔案生成函式
    :param folder: 資料夾名
    :param img_name:
    :param path:
    :param img_width:
    :param img_height:
    :param tag_num: 圖片內的標註框數量
    :param tag_name: 標註名稱
    :param box_list: 標註座標,其資料格式為[[xmin1, ymin1, xmax1, ymax1],[xmin2, ymin2, xmax2, ymax2]....]
    :return: a standard VOC format .xml file, named "img_name.xml"
    '''
    # 建立dom樹物件
    doc = xml.dom.minidom.Document()

    # 建立root結點annotation,並用dom物件新增根結點
    root_node = doc.createElement("annotation")
    doc.appendChild(root_node)

    # 建立結點並加入到根結點
    folder_node = doc.createElement("folder")
    folder_value = doc.createTextNode(folder)
    folder_node.appendChild(folder_value)
    root_node.appendChild(folder_node)

    filename_node = doc.createElement("filename")
    filename_value = doc.createTextNode(img_name)
    filename_node.appendChild(filename_value)
    root_node.appendChild(filename_node)

    path_node = doc.createElement("path")
    path_value = doc.createTextNode(path)
    path_node.appendChild(path_value)
    root_node.appendChild(path_node)

    source_node = doc.createElement("source")
    database_node = doc.createElement("database")
    database_node.appendChild(doc.createTextNode("Unknown"))
    source_node.appendChild(database_node)
    root_node.appendChild(source_node)

    size_node = doc.createElement("size")
    for item, value in zip(["width", "height", "depth"], [img_width, img_height, 3]):
        elem = doc.createElement(item)
        elem.appendChild(doc.createTextNode(str(value)))
        size_node.appendChild(elem)
    root_node.appendChild(size_node)

    seg_node = doc.createElement("segmented")
    seg_node.appendChild(doc.createTextNode(str(0)))
    root_node.appendChild(seg_node)

    for i in range(tag_num):
        obj_node = doc.createElement("object")
        name_node = doc.createElement("name")
        name_node.appendChild(doc.createTextNode(tag_name))
        obj_node.appendChild(name_node)

        pose_node = doc.createElement("pose")
        pose_node.appendChild(doc.createTextNode("Unspecified"))
        obj_node.appendChild(pose_node)

        trun_node = doc.createElement("truncated")
        trun_node.appendChild(doc.createTextNode(str(0)))
        obj_node.appendChild(trun_node)

        trun_node = doc.createElement("difficult")
        trun_node.appendChild(doc.createTextNode(str(0)))
        obj_node.appendChild(trun_node)

        bndbox_node = doc.createElement("bndbox")
        for item, value in zip(["xmin", "ymin", "xmax", "ymax"], box_list[i]):
            elem = doc.createElement(item)
            elem.appendChild(doc.createTextNode(str(value)))
            bndbox_node.appendChild(elem)
        obj_node.appendChild(bndbox_node)
        root_node.appendChild(obj_node)

    with open(img_name.split('.')[-2] + ".xml", "w", encoding="utf-8") as f:
        # writexml()第一個引數是目標檔案物件,第二個引數是根節點的縮排格式,第三個引數是其他子節點的縮排格式,
        # 第四個引數制定了換行格式,第五個引數制定了xml內容的編碼。
        doc.writexml(f, indent='', addindent='\t', newl='\n', encoding="utf-8")

  

方法使用演示(以lp-annot.idl為例) :

if __name__ == '__main__':
    f = open("./lp-annot.idl", "r")
    lines = f.readlines()  # 讀取全部內容 ,並以列表方式返回
    for line in lines:
        try:
            line_list = line.split(":-1")
            # print(f'line_list: {line_list}\nlen(line_list):{len(line_list)}\n')
            temp_line0_file_name = line_list[0].split(':')[0].split('"')[1].split('/')[-1]
            temp_line0_tag = line_list[0].split(':')[1]
            print(f'temp_line0_file_name: {temp_line0_file_name}       temp_line0_tag: {temp_line0_tag}')
            new_line_list = list()
            new_line_list.append(temp_line0_tag)
            for i in range(1, len(line_list) - 1):
                new_line_list.append(line_list[i])
            print(f'new_line_list:  {new_line_list}')
            box_list = []
            for i in range(len(new_line_list)):
                print(f'new_line_list[i]: {new_line_list[i]}')
                box = new_line_list[i].split("(")[1].split(',')
                box[3] = box[3].split(')')[0]
                print(f"box: {box}")
                x1, y1, x2, y2 = box[0], box[1], box[2], box[3]
                # if (int(x2) - int(x1)) >= (50*(float(img_width)/640.0)) and (int(y2) - int(y1)) >= (50*(float(img_height)/640.0)):
                if (int(x2) - int(x1)) >= 40 and (int(y2) - int(y1)) >= 70:
                    box_list.append(box[:])
            print(f"box_list: {box_list}")
            if len(box_list) == 0:
                continue
            write_xml(folder='VOC2014_instance/person', img_name='lp-annot_' + temp_line0_file_name,
                      path=temp_line0_file_name, img_width=640, img_height=480, tag_num=len(box_list),
                      tag_name='person', box_list=box_list)
        except Exception as e:
            print("ERROR, e----------------------------------------------\n:", e, "\n--------------------------------")