python 读取voc格式的标注xml文件

本文介绍了一种从测试集中的XML文件读取并统计车牌尺寸信息的方法,旨在为设置priorbox尺寸提供参考,通过解析XML文件获取图像尺寸及车牌边界框坐标,计算并统计了车牌宽度、高度及比例等关键数据。
#coding : utf-8
import os
import cv2
import abc
import xml.dom.minidom as xml
import math
import matplotlib.pyplot as plt


'''
读取测试集中的xml文件,统计下测试图片中车牌的大小信息,可以用来参考设置priorbox的大小
'''

class XmlReader(object):
    __metaclass__ = abc.ABCMeta
    def __init__(self):
        pass
    def read_content(self,filename):
        content = None
        if (False == os.path.exists(filename)):
            return content
        filehandle = None
        try:
            filehandle = open(filename,'rb')
        except FileNotFoundError as e:
            print(e.strerror)
        try:
            content = filehandle.read()
        except IOError as e:
            print(e.strerror)
        if (None != filehandle):
            filehandle.close()
        if(None != content):
            return content.decode("utf-8","ignore")
        return content

    @abc.abstractmethod
    def load(self,filename):
        pass

class XmlTester(XmlReader):
    def __init__(self):
        XmlReader.__init__(self)
    def load(self, filename):
        filecontent = XmlReader.read_content(self,filename)
        if None != filecontent:
            dom = xml.parseString(filecontent)
            root = dom.getElementsByTagName('annotation')[0]
            im_size = root.getElementsByTagName('size')[0]

            im_w = int((im_size.getElementsByTagName('width')[0]).childNodes[0].data)
            im_h = int((im_size.getElementsByTagName("height")[0]).childNodes[0].data)
            im_shape=[im_w,im_h]

            obj = dom.getElementsByTagName('object')[0]
            box = obj.getElementsByTagName('bndbox')[0]

            b_xmin=int((box.getElementsByTagName("xmin")[0]).childNodes[0].data)
            b_ymin=int((box.getElementsByTagName("ymin")[0]).childNodes[0].data)
            b_xmax=int((box.getElementsByTagName("xmax")[0]).childNodes[0].data)
            b_ymax=int((box.getElementsByTagName("ymax")[0]).childNodes[0].data)

            bbox=[b_xmin,b_ymin,b_xmax,b_ymax]

            return im_shape,bbox


if __name__ == "__main__":
    xml_dir="E:/dataset/CarPlate/cucumber_test/Annotations"
    xmls=os.listdir(xml_dir)
    sizes=[]
    ws=[]
    hs=[]
    ratios=[]
    ratios_320=[]
    for xml_file in xmls:
        reader = XmlTester()
        xml_path=xml_dir+"/"+xml_file
        #bboxes,im_w,im_h=GetAnnotBoxLoc(xml_dir+"/"+xml)
        im_shape,bbox=reader.load(xml_path)
        #priorbox大小是针对输入图像的大小的,这里输入图像被resize成了320x320,所以bbox的大小也要缩放
        w_r=320.0/im_shape[0]
        h_r=320.0/im_shape[1]
        ratios.append(im_shape[0]*1.0/im_shape[1])
        bbox_w=int((bbox[2]-bbox[0])* w_r)
        bbox_h=int((bbox[3]-bbox[1])* h_r)
        sizes.append(math.sqrt(bbox_w*bbox_h))
        ws.append(bbox_w)
        hs.append(bbox_h)
        #print (bbox_w,bbox_h)
        ratios_320.append(bbox_w*1.0/bbox_h)
        print (bbox_w*1.0/bbox_h)
        
    print ("max w:",max(ws))
    print("min w:",min(ws))
    print ("max h:",max(hs))
    print("min h:",min(hs))
    print("max side:",int(max(sizes)))
    print("min side:",int(min(sizes)))
    print("max ratio:",max(ratios))
    print("min ratio:",min(ratios))
    

    # plt.hist(sizes)
    # plt.show()
    # plt.hist(ws)
    # plt.show()
    # plt.hist(hs)
    # plt.show()
    plt.hist(ratios)
    plt.show()

    '''
    bbox信息如下
    max w: 139
    min w: 17
    max h: 95
    min h: 7
    max side: 96  (正方形边长)
    min side: 13
    '''

 

### 使用 Python 实现批量创建图像标签的 XML 文件 为了实现这一目标,可以采用 `xml.etree.ElementTree` 库来构建和保存 XML 文档。下面是一个完整的解决方案,展示了如何基于一组预定义的对象信息为多个图片文件生成相应的 XML 标签文件。 #### 准备工作环境 确保安装必要的库: ```bash pip install lxml pillow numpy opencv-python-headless ``` #### 创建 XML 结构模板 首先设计好 XML 的基本结构,这通常包括根节点 `<annotation>` 及其子元素如 `<filename>`, `<size>`, 和对象描述部分 `<object>` 等: ```python import os from xml.etree.ElementTree import Element, SubElement, tostring from xml.dom.minidom import parseString def create_xml_template(image_name, image_size, objects_info): """ 构建单张图片对应的XML标注文件 参数: image_name (str): 图片名称. image_size (tuple of int): 宽度高度通道数三元组. objects_info (list of dict): 对象列表及其属性字典. 返回值: str: 整形美化后的XML字符串表示形式. """ annotation = Element('annotation') folder = SubElement(annotation, "folder").text = 'VOC2012' filename = SubElement(annotation, "filename").text = f"{image_name}.jpg" size = SubElement(annotation, "size") width = SubElement(size, "width").text = str(image_size[0]) height = SubElement(size, "height").text = str(image_size[1]) depth = SubElement(size, "depth").text = str(image_size[2]) for obj in objects_info: object_elem = SubElement(annotation, "object") name = SubElement(object_elem, "name").text = obj['class'] pose = SubElement(object_elem, "pose").text = 'Unspecified' truncated = SubElement(object_elem, "truncated").text = '0' difficult = SubElement(object_elem, "difficult").text = '0' bndbox = SubElement(object_elem, "bndbox") xmin = SubElement(bndbox, "xmin").text = str(obj['bbox'][0]) ymin = SubElement(bndbox, "ymin").text = str(obj['bbox'][1]) xmax = SubElement(bndbox, "xmax").text = str(obj['bbox'][2]) ymax = SubElement(bndbox, "ymax").text = str(obj['bbox'][3]) rough_string = tostring(annotation, 'utf-8') reparsed = parseString(rough_string) return reparsed.toprettyxml(indent=" ") ``` 此方法接收三个参数:图片名、尺寸以及包含类别和边界框坐标的对象详情数组,并返回格式化的 XML 字符串[^1]。 #### 批量处理逻辑 接下来编写主程序循环遍历待处理的每一张图片并调用上述辅助函数完成 XML 文件的创建与保存操作: ```python if __name__ == '__main__': images_dir = './images' # 存放原始图片的位置 output_dir = './annotations' # 输出目录用于存放新产生的XML文件 if not os.path.exists(output_dir): os.makedirs(output_dir) sample_objects = [ {'class': 'dog', 'bbox': [50, 60, 200, 220]}, {'class': 'cat', 'bbox': [300, 400, 500, 700]} ] # 这里只是一个例子,在实际应用中应该根据具体需求动态获取这些信息 for img_file in os.listdir(images_dir): if img_file.endswith('.jpg'): base_name = os.path.splitext(img_file)[0] with open(os.path.join(output_dir, f'{base_name}.xml'), 'w') as out_f: content = create_xml_template( image_name=base_name, image_size=(800, 600, 3), # 此处应替换为真实的图片分辨率 objects_info=sample_objects ) out_f.write(content) ``` 这段代码会读取指定文件夹内的所有 JPG 格式图片文件,对于每一个找到的图片都会依据给定的信息构造一个新的 XML 文件存入另一个预先设定好的输出路径下[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值