• python文件操作之xml转txt


     在使用yolo进行深度学习训练时,我们所使用的标签文件都是txt格式的,但是有的人使用的标注软件生成的可能是xml文件,那么就需要使用python工具写一个格式转换脚本。

    首先导入库,并定义标注的图片地址、生成的标签文件xml地址、存储结果txt的地址。

    1. import cv2
    2. import os
    3. import math
    4. import xml.dom.minidom
    5. path_img = r'/home/pc/下载/qq_file/test/img/'
    6. path_xml = r'/home/pc/下载/qq_file/test/xml/'
    7. path_txt = r'/home/pc/下载/qq_file/test/txt/'

    files = os.listdir(path_xml)这句话的files存储了path_xml路径下的所有xml文件

    1. if __name__ == "__main__":
    2. files = os.listdir(path_xml)
    3. print("文件数量: " + str(len(files)))
    4. for file in files:
    5. print(file)

    如上代码的file打印结果就应该为目标文件夹下所有xml文件的文件名,如246.xml。

    1. if __name__ == "__main__":
    2. files = os.listdir(path_xml)
    3. print("文件数量: " + str(len(files)))
    4. for file in files:
    5. print(file)
    6. xmlname = file.split('.')
    7. txtname = xmlname[0] + '.txt'
    8. imgname = xmlname[0] + '.jpg'
    9. txtpath = path_txt + txtname
    10. imgpath = path_img + imgname
    11. xmlpath = path_xml + xmlname[0] + '.' + xmlname[1]

    接下来用“ . ”来分割xml文件的文件名和后缀,其中xmlname[0] = 文件名,xmlname[1] = xml。由此可以定义每一个xml、txt、jpg的路径。

    1. if __name__ == "__main__":
    2. files = os.listdir(path_xml)
    3. print("文件数量: " + str(len(files)))
    4. for file in files:
    5. print(file)
    6. xmlname = file.split('.')
    7. txtname = xmlname[0] + '.txt'
    8. imgname = xmlname[0] + '.jpg'
    9. txtpath = path_txt + txtname
    10. imgpath = path_img + imgname
    11. xmlpath = path_xml + xmlname[0] + '.' + xmlname[1]
    12. # print(xmlpath)
    13. file_txt = open(txtpath, 'w+')
    14. frame = cv2.imread(imgpath)
    15. pixel_size = frame.shape[0]
    16. print(pixel_size)

    接下来定义file_txt为文件夹下每一个txt文件,并可进行write操作。

    1. # 将解析xml文件的结果存在dom变量下
    2. dom = xml.dom.minidom.parse(xmlpath)
    3. # 获取xml文件的根元素
    4. root = dom.documentElement
    5. objects = root.getElementsByTagName('object')
    6. for obj in objects:
    7. name = obj.getElementsByTagName('name')[0] # [0]可能代表包含标签数值的一个集合(这里可能包含标签数值,地址等)
    8. if name.childNodes[0].data == 'armor_red': # 通过调用name.childNodes[0].data方法获取标签数值
    9. file_txt.write('0 ')
    10. elif name.childNodes[0].data == 'full_red':
    11. file_txt.write('1 ')
    12. elif name.childNodes[0].data == 'R_red':
    13. file_txt.write('2 ')
    14. else:
    15. print(file + ":label error")
    16. robodbox = obj.getElementsByTagName('robodbox')
    17. cx = obj.getElementsByTagName('cx')[0]
    18. cy = obj.getElementsByTagName('cy')[0]
    19. w = obj.getElementsByTagName('w')[0]
    20. h = obj.getElementsByTagName('h')[0]
    21. angle = obj.getElementsByTagName('angle')[0]
    22. # print(f"cx = {cx.childNodes[0]}, cy = {cy.childNodes[0].data}, w = {w.childNodes[0].data}, h = {h.childNodes[0].data}, "
    23. # f"angle = {angle.childNodes[0].data}")
    24. temp_cx = str(float(cx.childNodes[0].data) / pixel_size)
    25. temp_cy = str(float(cy.childNodes[0].data) / pixel_size)
    26. temp_h = str(float(h.childNodes[0].data) / pixel_size)
    27. temp_w = str(float(w.childNodes[0].data) / pixel_size)
    28. temp_angle = str(float(angle.childNodes[0].data) / math.pi*180)

    接下来对xml文件进行解析,调用dom = xml.dom.minidom.parse(xmlpath),将解析xml文件的结果存在dom变量下;root = dom.documentElement,获取xml文件的根元素root;objects = root.getElementsByTagName('object'),获得object;使用for循环遍历每一个object,使用name = obj.getElementsByTagName('name')[0]来获得每一个object的name,这里[0]可能代表包含标签数值的一个集合(这里可能包含标签数值,地址等),然后判断

    if name.childNodes[0].data == 'armor_red'

    file_txt.write('0 ')

    通过调用name.childNodes[0].data方法获取标签数值,写入txt文件作为第一个数值,即“类别“。

    1. robodbox = obj.getElementsByTagName('robodbox')
    2. cx = obj.getElementsByTagName('cx')[0]
    3. cy = obj.getElementsByTagName('cy')[0]
    4. w = obj.getElementsByTagName('w')[0]
    5. h = obj.getElementsByTagName('h')[0]
    6. angle = obj.getElementsByTagName('angle')[0]
    7. # print(f"cx = {cx.childNodes[0]}, cy = {cy.childNodes[0].data}, w = {w.childNodes[0].data}, h = {h.childNodes[0].data}, "
    8. # f"angle = {angle.childNodes[0].data}")
    9. temp_cx = str(float(cx.childNodes[0].data) / pixel_size)
    10. temp_cy = str(float(cy.childNodes[0].data) / pixel_size)
    11. temp_h = str(float(h.childNodes[0].data) / pixel_size)
    12. temp_w = str(float(w.childNodes[0].data) / pixel_size)
    13. temp_angle = str(float(angle.childNodes[0].data) / math.pi*180)
    14. file_txt.write(temp_cx + ' ')
    15. file_txt.write(temp_cy + ' ')
    16. file_txt.write(temp_w + ' ')
    17. file_txt.write(temp_h + ' ')
    18. file_txt.write(temp_angle + ' ')
    19. file_txt.write('\n')

    类别信息获取后,接下来对矩形框数值进行解析,使用同样的方法获取数据,并进行归一化写入txt。

    完整代码如下

    1. import cv2
    2. import os
    3. import math
    4. import xml.dom.minidom
    5. path_img = r'/home/pc/下载/qq_file/test/img/'
    6. path_xml = r'/home/pc/下载/qq_file/test/xml/'
    7. path_txt = r'/home/pc/下载/qq_file/test/txt/'
    8. if __name__ == "__main__":
    9. files = os.listdir(path_xml)
    10. print("文件数量: " + str(len(files)))
    11. for file in files:
    12. print(file)
    13. xmlname = file.split('.')
    14. txtname = xmlname[0] + '.txt'
    15. imgname = xmlname[0] + '.jpg'
    16. txtpath = path_txt + txtname
    17. imgpath = path_img + imgname
    18. xmlpath = path_xml + xmlname[0] + '.' + xmlname[1]
    19. # print(xmlpath)
    20. file_txt = open(txtpath, 'w+')
    21. frame = cv2.imread(imgpath)
    22. pixel_size = frame.shape[0]
    23. # print(pixel_size)
    24. # 将解析xml文件的结果存在dom变量下
    25. dom = xml.dom.minidom.parse(xmlpath)
    26. # 获取xml文件的根元素
    27. root = dom.documentElement
    28. objects = root.getElementsByTagName('object')
    29. for obj in objects:
    30. name = obj.getElementsByTagName('name')[0] # [0]可能代表包含标签数值的一个集合(这里可能包含标签数值,地址等)
    31. if name.childNodes[0].data == 'armor_red': # 通过调用name.childNodes[0].data方法获取标签数值
    32. file_txt.write('0 ')
    33. elif name.childNodes[0].data == 'full_red':
    34. file_txt.write('1 ')
    35. elif name.childNodes[0].data == 'R_red':
    36. file_txt.write('2 ')
    37. else:
    38. print(file + ":label error")
    39. robodbox = obj.getElementsByTagName('robodbox')
    40. cx = obj.getElementsByTagName('cx')[0]
    41. cy = obj.getElementsByTagName('cy')[0]
    42. w = obj.getElementsByTagName('w')[0]
    43. h = obj.getElementsByTagName('h')[0]
    44. angle = obj.getElementsByTagName('angle')[0]
    45. # print(f"cx = {cx.childNodes[0]}, cy = {cy.childNodes[0].data}, w = {w.childNodes[0].data}, h = {h.childNodes[0].data}, "
    46. # f"angle = {angle.childNodes[0].data}")
    47. temp_cx = str(float(cx.childNodes[0].data) / pixel_size)
    48. temp_cy = str(float(cy.childNodes[0].data) / pixel_size)
    49. temp_h = str(float(h.childNodes[0].data) / pixel_size)
    50. temp_w = str(float(w.childNodes[0].data) / pixel_size)
    51. temp_angle = str(float(angle.childNodes[0].data) / math.pi*180)
    52. file_txt.write(temp_cx + ' ')
    53. file_txt.write(temp_cy + ' ')
    54. file_txt.write(temp_w + ' ')
    55. file_txt.write(temp_h + ' ')
    56. file_txt.write(temp_angle + ' ')
    57. file_txt.write('\n')
    58. print("ok")
    59. file_txt.close()

  • 相关阅读:
    应急响应-Linux常用应急溯源命令
    欧冠比赛数据集(梅西不哭-离开巴萨也可能再创巅峰)
    校招VIP】前端算法考察之排序
    .NET性能优化-推荐使用Collections.Pooled(补充)
    flutter plugins插件【二】【FlutterAssetsGenerator】
    C语言 动态内存管理
    Twitter 审核研究联盟 - 深入了解 Twitter 上对话的安全性和完整性。
    LeetCode500. 键盘行
    VB.NET—DataGridView控件教程详解
    人脸匹配——OpenCV
  • 原文地址:https://blog.csdn.net/qq_46454669/article/details/134478596