【目标检测适用】批量修改xml文件中的name字段

转载:【目标检测适用】批量修改xml文件中的name字段.

前言:使用labelimg进行标注的时候,由于都是用的是默认的名称,有时候类的名字会出现拼写错误,比如我想要写的是“cow” 结果打上去的是“cwo”, 一出错就错一片,这很常见,所以参考了:https://www.jianshu.com/p/cf12bef0872c 的代码,修改了冗余的代码,并添加了新的模块以后,将代码分享给大家。

1. xml文件展示

<annotation>
	<folder>part3</folder>
	<filename>0015-1150.jpg</filename>
	<path>I:\part3\0015-1150.jpg</path>
	<source>
		<database>Unknown</database>
	</source>
	<size>
		<width>1280</width>
		<height>720</height>
		<depth>3</depth>
	</size>
	<segmented>0</segmented>
	<object>
		<name>cow</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>459</xmin>
			<ymin>88</ymin>
			<xmax>567</xmax>
			<ymax>163</ymax>
		</bndbox>
	</object>
	<object>
		<name>cow</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>543</xmin>
			<ymin>92</ymin>
			<xmax>630</xmax>
			<ymax>163</ymax>
		</bndbox>
	</object>
	<object>
		<name>cow</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>659</xmin>
			<ymin>156</ymin>
			<xmax>773</xmax>
			<ymax>263</ymax>
		</bndbox>
	</object>
	<object>
		<name>cow</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>497</xmin>
			<ymin>171</ymin>
			<xmax>677</xmax>
			<ymax>315</ymax>
		</bndbox>
	</object>
	<object>
		<name>cow</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>584</xmin>
			<ymin>303</ymin>
			<xmax>715</xmax>
			<ymax>395</ymax>
		</bndbox>
	</object>
	<object>
		<name>cow</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>537</xmin>
			<ymin>389</ymin>
			<xmax>814</xmax>
			<ymax>497</ymax>
		</bndbox>
	</object>
	<object>
		<name>cow</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>750</xmin>
			<ymin>303</ymin>
			<xmax>918</xmax>
			<ymax>434</ymax>
		</bndbox>
	</object>
	<object>
		<name>cow</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>770</xmin>
			<ymin>223</ymin>
			<xmax>958</xmax>
			<ymax>285</ymax>
		</bndbox>
	</object>
	<object>
		<name>cow</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>974</xmin>
			<ymin>477</ymin>
			<xmax>1152</xmax>
			<ymax>636</ymax>
		</bndbox>
	</object>
	<object>
		<name>cow</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>66</xmin>
			<ymin>454</ymin>
			<xmax>308</xmax>
			<ymax>696</ymax>
		</bndbox>
	</object>
	<object>
		<name>cow</name>
		<pose>Unspecified</pose>
		<truncated>1</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>347</xmin>
			<ymin>548</ymin>
			<xmax>550</xmax>
			<ymax>720</ymax>
		</bndbox>
	</object>
	<object>
		<name>cow</name>
		<pose>Unspecified</pose>
		<truncated>0</truncated>
		<difficult>0</difficult>
		<bndbox>
			<xmin>996</xmin>
			<ymin>154</ymin>
			<xmax>1128</xmax>
			<ymax>245</ymax>
		</bndbox>
	</object>
</annotation>

 
 

2. 将文件夹中所有name进行批量更改

2.1 将某类别名称更改

def changeName(xml_fold, origin_name, new_name):
    '''
    xml_fold: xml存放文件夹
    origin_name: 原始名字,比如弄错的名字,原先要cow,不小心打成cwo
    new_name: 需要改成的正确的名字,在上个例子中就是cow
    '''
    files = os.listdir(xml_fold)
    cnt = 0 
    for xmlFile in files:
        file_path = os.path.join(xml_fold, xmlFile)
        dom = parse(file_path)
        root = dom.getroot()
        for obj in root.iter('object'):#获取object节点中的name子节点
            tmp_name = obj.find('name').text
            if tmp_name == origin_name: # 修改
                obj.find('name').text = new_name
                print("change %s to %s." % (origin_name, new_name))
                cnt += 1
        dom.write(file_path, xml_declaration=True)#保存到指定文件
    print("有%d个文件被成功修改。" % cnt)

 
 

    效果如下:
    在这里插入图片描述

    2.2 将某文件夹所有类别都统一成某个类别

    适用于只有一个类,并且进行改名的时候。

    def changeAll(xml_fold,new_name):
        '''
        xml_fold: xml存放文件夹
        new_name: 需要改成的正确的名字,在上个例子中就是cow
        '''
        files = os.listdir(xml_fold)
        cnt = 0 
        for xmlFile in files:
            file_path = os.path.join(xml_fold, xmlFile)
            dom = parse(file_path)
            root = dom.getroot()
            for obj in root.iter('object'):#获取object节点中的name子节点
                tmp_name = obj.find('name').text
                obj.find('name').text = new_name
                print("change %s to %s." % (tmp_name, new_name))
                cnt += 1
            dom.write(file_path, xml_declaration=True)#保存到指定文件
        print("有%d个文件被成功修改。" % cnt)

    效果:
    在这里插入图片描述

    2.3 统计每个类别实际目标的个数

    def countAll(xml_fold):
        '''
        xml_fold: xml存放文件夹
        '''
        files = os.listdir(xml_fold)
        dict={}
        for xmlFile in files:
            file_path = os.path.join(xml_fold, xmlFile)
            dom = parse(file_path)
            root = dom.getroot()
            for obj in root.iter('object'):#获取object节点中的name子节点
                tmp_name = obj.find('name').text
                if tmp_name not in dict:
                    dict[tmp_name] = 0
                else:
                    dict[tmp_name] += 1
            dom.write(file_path, xml_declaration=True)#保存到指定文件
        print("统计结果如下:")
        print("-"*10)
        for key,value in dict.items():
            print("类别为%s的目标个数为%d." % (key, value))
        print("-"*10)

    在这里插入图片描述

    3. 全部代码

    import os
    import os.path
    from xml.etree.ElementTree import parse, Element
    def changeName(xml_fold, origin_name, new_name):
        '''
        xml_fold: xml存放文件夹
        origin_name: 原始名字,比如弄错的名字,原先要cow,不小心打成cwo
        new_name: 需要改成的正确的名字,在上个例子中就是cow
        '''
        files = os.listdir(xml_fold)
        cnt = 0 
        for xmlFile in files:
            file_path = os.path.join(xml_fold, xmlFile)
            dom = parse(file_path)
            root = dom.getroot()
            for obj in root.iter('object'):#获取object节点中的name子节点
                tmp_name = obj.find('name').text
                if tmp_name == origin_name: # 修改
                    obj.find('name').text = new_name
                    print("change %s to %s." % (origin_name, new_name))
                    cnt += 1
            dom.write(file_path, xml_declaration=True)#保存到指定文件
        print("有%d个文件被成功修改。" % cnt)
    def changeAll(xml_fold,new_name):
        '''
        xml_fold: xml存放文件夹
        new_name: 需要改成的正确的名字,在上个例子中就是cow
        '''
        files = os.listdir(xml_fold)
        cnt = 0 
        for xmlFile in files:
            file_path = os.path.join(xml_fold, xmlFile)
            dom = parse(file_path)
            root = dom.getroot()
            for obj in root.iter('object'):#获取object节点中的name子节点
                tmp_name = obj.find('name').text
                obj.find('name').text = new_name
                print("change %s to %s." % (tmp_name, new_name))
                cnt += 1
            dom.write(file_path, xml_declaration=True)#保存到指定文件
        print("有%d个文件被成功修改。" % cnt)
    def countAll(xml_fold):
        '''
        xml_fold: xml存放文件夹
        '''
        files = os.listdir(xml_fold)
        dict={}
        for xmlFile in files:
            file_path = os.path.join(xml_fold, xmlFile)
            dom = parse(file_path)
            root = dom.getroot()
            for obj in root.iter('object'):#获取object节点中的name子节点
                tmp_name = obj.find('name').text
                if tmp_name not in dict:
                    dict[tmp_name] = 0
                else:
                    dict[tmp_name] += 1
            dom.write(file_path, xml_declaration=True)#保存到指定文件
        print("统计结果如下:")
        print("-"*10)
        for key,value in dict.items():
            print("类别为%s的目标个数为%d." % (key, value))
        print("-"*10)
    if __name__ == '__main__':
        path = r"I:\dongpeijiePickup\assignment\part2_xml" #xml文件所在的目录
        # changeName(path, "cattle", "cow")
        # changeAll(path, "cattle")
        countAll(path)
    • 6
      点赞
    • 14
      收藏
      觉得还不错? 一键收藏
    • 6
      评论
    评论 6
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值