python 批量修改 labelImg 生成的xml文件的方法
概述
自己在用labelImg打好標(biāo)簽后,想只用其中幾類訓(xùn)練,不想訓(xùn)練全部類別,又不想重新打標(biāo)生成.xml文件,因此想到這個辦法:直接在.xml文件中刪除原有的不需要的標(biāo)簽類及其屬性。
打標(biāo)時標(biāo)簽名出現(xiàn)了大小寫(工程量大時可能會手滑),程序中有改寫標(biāo)簽值為小寫的過程,因?yàn)槲易鰌y-faster-rcnn 訓(xùn)練時,標(biāo)簽必須全部為小寫。
以如下的.xml文件為例,我故意把標(biāo)簽增加了大寫
<annotation verified="yes"> <filename>test.jpg</filename> <path>C:\Users\yasin\Desktop\test</path> <source> <database>Unknown</database> </source> <size> <width>400</width> <height>300</height> <depth>3</depth> </size> <segmented>0</segmented> <object> <name>People</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>80</xmin> <ymin>69</ymin> <xmax>144</xmax> <ymax>89</ymax> </bndbox> </object> <object> <name>CAT</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>40</xmin> <ymin>69</ymin> <xmax>143</xmax> <ymax>16</ymax> </bndbox> </object> <object> <name>dog</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>96</xmin> <ymin>82</ymin> <xmax>176</xmax> <ymax>87</ymax> </bndbox> </object> </annotation>
具體實(shí)現(xiàn)
假如我們只想保留圖片上的people和cat類,其他都刪除,代碼如下:
from xml.etree.ElementTree import ElementTree from os import walk, path def read_xml(in_path): tree = ElementTree() tree.parse(in_path) return tree def write_xml(tree, out_path): tree.write(out_path, encoding="utf-8", xml_declaration=True) def find_nodes(tree, path): return tree.findall(path) def del_node_by_target_classes(nodelist, target_classes_lower, tree_root): for parent_node in nodelist: children = parent_node.getchildren() if (parent_node.tag == "object" and children[0].text.lower() not in target_classes_lower): tree_root.remove(parent_node) elif (parent_node.tag == "object" and children[0].text.lower() in target_classes_lower): children[0].text = children[0].text.lower() def get_fileNames(rootdir): data_path = [] prefixs = [] for root, dirs, files in walk(rootdir, topdown=True): for name in files: pre, ending = path.splitext(name) if ending != ".xml": continue else: data_path.append(path.join(root, name)) prefixs.append(pre) return data_path, prefixs if __name__ == "__main__": # get all the xml paths, prefixes if not used here paths_xml, prefixs = get_fileNames("/home/yasin/old_labels/") target_classes = ["PEOPLE", "CAT"] # target flags you want to keep target_classes_lower = [] for i in range(len(target_classes)): target_classes_lower.append(target_classes[i].lower()) # make sure your target is lowe-case # print(target_classes_lower) for i in range(len(paths_xml)): # rename and save the corresponding xml tree = read_xml(paths_xml[i]) # get tree node tree_root = tree.getroot() # get parent nodes del_parent_nodes = find_nodes(tree, "./") # get target classes and delete target_del_node = del_node_by_target_classes(del_parent_nodes, target_classes_lower, tree_root) # save output xml, 000001.xml write_xml(tree, "/home/yasin/new_labels/{}.xml".format("%06d" % i))
按照上述代碼,示例.xml變?yōu)槿缦?xml,可以看出我們刪除了除people和cat類的類別(即dog類),并把保留類別的打標(biāo)改成了小寫:
<?xml version='1.0' encoding='utf-8'?> <annotation verified="yes"> <filename>test.jpg</filename> <path>C:\Users\yasin\Desktop\test</path> <source> <database>Unknown</database> </source> <size> <width>400</width> <height>300</height> <depth>3</depth> </size> <segmented>0</segmented> <object> <name>people</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>80</xmin> <ymin>69</ymin> <xmax>144</xmax> <ymax>89</ymax> </bndbox> </object> <object> <name>cat</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>40</xmin> <ymin>69</ymin> <xmax>143</xmax> <ymax>16</ymax> </bndbox> </object> </annotation>
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python獲取運(yùn)行目錄與當(dāng)前腳本目錄的方法
這篇文章主要介紹了Python獲取運(yùn)行目錄與當(dāng)前腳本目錄的方法,涉及Python目錄操作與系統(tǒng)相關(guān)變量的獲取技巧,需要的朋友可以參考下2015-06-06Python 讀取xml數(shù)據(jù),cv2裁剪圖片實(shí)例
這篇文章主要介紹了Python 讀取xml數(shù)據(jù),cv2裁剪圖片實(shí)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03python和websocket構(gòu)建實(shí)時日志跟蹤器的步驟
這篇文章主要介紹了python和websocket構(gòu)建實(shí)時日志跟蹤器的步驟,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下2021-04-04淺談Django學(xué)習(xí)migrate和makemigrations的差別
這篇文章主要介紹了淺談Django學(xué)習(xí)migrate和makemigrations的差別,具有一定借鑒價值,需要的朋友可以參考下2018-01-01Python深度學(xué)習(xí)實(shí)戰(zhàn)PyQt5信號與槽的連接
本文講解信號與槽的連接機(jī)制,詳細(xì)示范各種類型的信號/槽連接的實(shí)現(xiàn)方法,這是圖形用戶界面的核心內(nèi)容。還將介紹面向?qū)ο蟮某绦蛟O(shè)計(jì),這是圖形用戶界面的基本思想2021-10-10Python 實(shí)現(xiàn)簡單的客戶端認(rèn)證
這篇文章主要介紹了Python 如何實(shí)現(xiàn)簡單的客戶端認(rèn)證,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07