统计xml文件中标记框的特性

统计xml文件中标记框的特性

统计xml文件中标记框的特性

使用labelimg对图片进行标记之后保存为xml文件,运行脚本统计xml文件中的标记框的特征。

代码如下:

 import os
    import sys
    filedir = os.path.dirname(sys.argv[0])      #获取脚本所在目录
    os.chdir(filedir)       #将脚本所在的目录设置为工作目录
    wdir = os.getcwd()
    print('当前工作目录:{}\n'.format(wdir))      #打印当前工作目录
    
    from xml.dom.minidom import parse
    
    def xml_parser( xml_file ):
        '''
        Parse an xml file and return the annotation info in the file
    
        :param xml_file: the xml file name to be parsed
        :return: file_name, width, height, objects.
            file_name, filename of the xml file (without extension)
            width, width of the annotated image
            height, height of the annotated image
            objects, annotated objects in the image
            object, (object_name, xmin, ymin, xmax, ymax)
                object_name, name of the annotated object
                xmin, ymin, xmax, ymax, coordinate of the bounding box of the object
    
        '''
        DOMTree = parse( xml_file )
        collection = DOMTree.documentElement #得到xml文件的根节点
        file_name_xml = collection.getElementsByTagName( 'filename' )[0]
        objects_xml = collection.getElementsByTagName( 'object' )
        size_xml = collection.getElementsByTagName( 'size' )
    
        file_name = file_name_xml.childNodes[0].data
    
        for size in size_xml:
            width = size.getElementsByTagName( 'width' )[0]
            height = size.getElementsByTagName( 'height' )[0]
    
            width = width.childNodes[0].data
            height = height.childNodes[0].data
    
        objects = []
        for object_xml in objects_xml:
            object_name = object_xml.getElementsByTagName( 'name' )[0]
            bdbox = object_xml.getElementsByTagName( 'bndbox' )[0]
            xmin = bdbox.getElementsByTagName( 'xmin' )[0]
            ymin = bdbox.getElementsByTagName( 'ymin' )[0]
            xmax = bdbox.getElementsByTagName( 'xmax' )[0]
            ymax = bdbox.getElementsByTagName( 'ymax' )[0]
    
            object = [ object_name.childNodes[0].data,
                       float(xmin.childNodes[0].data),
                       float(ymin.childNodes[0].data),
                       float(xmax.childNodes[0].data),
                       float(ymax.childNodes[0].data) ]
    
            objects.append( object )
    
        return file_name, int(width), int(height), objects
        
    image_dir = 'images'    
    xml_dir = 'labels'
    xml_files = os.listdir(xml_dir)
    image_files = os.listdir(image_dir)
    image_ext = image_files[0].split('.')[-1] #图片文件的扩展名
    print(image_ext)
    if len(image_files) == len(xml_files):
        print('共有{:d}个xml文件。'.format(len(xml_files)))
    else:
        print('图片数量和xml文件数量不一致。')
    obj_dict = {}
    for xml_file in xml_files:
        annotation = xml_parser(os.path.join(xml_dir, xml_file))
        name_1 = xml_file.split('.')[0] + '.' + image_ext.lower()
        name_2 = xml_file.split('.')[0] + '.' + image_ext.upper()
        if  name_1 not in image_files and name_2 not in image_files:
            print('{:s}没有对应的图片。'.format(xml_file))
        for obj in annotation[-1]:
            key = obj[0]
            x = (obj[1] + obj[3])/2
            y = (obj[2] + obj[4])/2
            width = obj[3] - obj[1]
            height = obj[4] - obj[2]
            box = [x,y,width,height]
            if key in obj_dict:
                obj_dict[key][0] += 1
                n = obj_dict[key][0]
                obj_dict[key][1:5] = [ (i*(n-1)+j)/(n) for i,j in zip(obj_dict[key][1:5] , box)]
                #obj_dict[key][5:9] = [ i if i>=j else j for i,j in zip(obj_dict[key][5:9] , box)]
                #obj_dict[key][9:] = [ i if i>=j else j for i,j in zip(obj_dict[key][9:] , box)]
            else:
                obj_dict[key] = []
                obj_dict[key].append(1)  # 0,个数
                obj_dict[key] += box     # 1-4, 平均坐标
                #obj_dict[key] += box     # 5-8, 最大值
                #obj_dict[key] += box     # 9-12,最小值
    for key,value in obj_dict.items():
        print('一共有 {:4d} 个 {:20s},其边框平均位置为{:4.0f} *{:4.0f};平均尺寸为{:3.0f} *{:3.0f}。'.format(value[0],key,*value[1:]))
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/2173.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • SpringCloud功能简介

    SpringCloud功能简介SpringCloud功能简介

    2022年4月23日
    51
  • 在微型计算机中1gb等于多少字节,1GB等于多少字节「建议收藏」

    在微型计算机中1gb等于多少字节,1GB等于多少字节「建议收藏」1GB=1073741824字节。1KB=1024字节1M=1024KB1G=1024MB一小组相邻的二进制数码称为字节。通常是8位作为一个字节。它是构成信息的一个小单位,并作为一个整体来参加操作,比字小,是构成字的单位。扩展资料:数据的存储是以“字节”(Byte)为单位,数据传输大多是以“位”(bit,又名“比特”)为单位,一个位就代表一个0或1(即二进制),每8个位(bit,简写为b)组成一个…

    2022年5月9日
    71
  • 80×86汇编小站站长简单介绍

    80×86汇编小站站长简单介绍[人生格言]1]一生都用头脑而不是情绪解决这个问题2]仅仅有偏执狂才会成功3]在最困难时都要保持一份幽默感4]吾生也有涯,而知也无涯,以有涯随无涯,殆已[简历]我的生日:1981.XX.XX

    2022年7月2日
    18
  • 程序,进程,线程的区别和联系

    程序,进程,线程的区别和联系进程和程序区别和联系表现在以下方面:1)程序只是一组指令的有序集合,它本身没有任何运行的含义,它只是一个静态的实体。而进程则不同,它是程序在某个数据集上的执行。进程是一个动态的实体,它有自己的生命周期。它因创建而产生,因调度而运行,因等待资源或事件而被处于等待状态,因完成任务而被撤消。反映了一个程序在一定的数据集上运行的全部动态过程。2)进程和程序并不是一一对应的,一个程序执行在不同的数据集上…

    2022年7月15日
    13
  • accept 函数_可以使用throw语句来抛出异常

    accept 函数_可以使用throw语句来抛出异常AcceptEx函数的第一个参数listen_socket和第二个参数accept_sock不能相同。并且第一个参数listen_socket必须开启监听,否则会返回10022错误。AcceptEx函数的缓冲区如果设为0字节,那么每次发到客户端将延迟10ms左右,底层原因。。如果收到连接请求,GetQueuedCompletionStatus函数的lpCompletionKey参数将是调用CreateIoCompletionPort绑定listen_socket到完成端口的第三个参数。…

    2022年9月29日
    3
  • CSDN 赚积分&C币方法[通俗易懂]

    CSDN 赚积分&C币方法[通俗易懂]于2019-03-20补充下载积分规则(2019-03-20)项目名称 获得细则 积分数量 普通资源被下载 100分封顶,下载自己资源无积分 资源分*下载量 获得C币规则(2019-03-20)1.撰写博文获得C币现在去发博文行为 获得数量 说明 博客专家每月原创文章数>=4 10 月度奖励,于下月月初结算…

    2022年5月29日
    701

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号