• 【Xml Tool】 裁剪某个区域重新生成xml


     

    该代码功能:
    对已经标注好的xml文件进行操作
    比如,label A 区域中,有多个label B。
    现在我希望我能截取label A区域的图片,并根据原始xml生成lable B 的标注文件

    注:label B部分区域在label A 外面的话,则扩大label A裁剪区域,使其包括 label B


    xml里面 x为w轴

    1. '''
    2. 该代码功能:
    3. 对已经标注好的xml文件进行操作
    4. 比如,label A 区域中,有多个label B。
    5. 现在我希望我能截取label A区域的图片,并根据原始xml生成lable B 的标注文件
    6. 注:label B部分区域在label A 外面的话,则扩大label A裁剪区域,使其包括 label B
    7. xml里面 x为w轴
    8. '''
    9. import os
    10. import cv2
    11. import xml.etree.ElementTree as ET
    12. import traceback
    13. import copy
    14. images_path="/media/hxzh/SB@home/hxzh/MH_dataset/Towers/dataset_insulator_clip/images"
    15. xmls_path="/media/hxzh/SB@home/hxzh/MH_dataset/Towers/dataset_insulator_clip/xmls"
    16. save_image_path="/media/hxzh/SB@home/hxzh/MH_dataset/Towers/dataset_insulator_clip/save_images"
    17. save_xmls_path="/media/hxzh/SB@home/hxzh/MH_dataset/Towers/dataset_insulator_clip/save_xmls"
    18. #所要裁剪区域的标签名字
    19. crop_name="100_0_0"
    20. #要生成的标签名
    21. label_name="100_1_0"
    22. def read_xml(filename):
    23. (fname, suffix) = os.path.splitext(filename)
    24. if not os.path.exists(f"{images_path}/{fname}.JPG"):
    25. return 0
    26. image_ori=cv2.imread(f"{images_path}/{fname}.JPG")
    27. is_ok=True
    28. try :
    29. tree = ET.parse(f"{xmls_path}/{filename}")
    30. tree_ori=copy.deepcopy(tree)
    31. except (BaseException,Exception ) as e:
    32. print(filename,traceback.format_exc())
    33. return []
    34. # 获取宽w和高h
    35. a = tree.find('size')
    36. w, h = [int(a.find('width').text),
    37. int(a.find('height').text)]
    38. objects = []
    39. if w == 0:
    40. return []
    41. crop_area=[]
    42. label_area=[]
    43. for obj in tree.findall('object'):
    44. # 获取name
    45. name = obj.find('name').text
    46. if name==crop_name:
    47. # 读取检测框的左上、右下角点的坐标
    48. bbox = obj.find('bndbox')
    49. x1, y1, x2, y2 = [int(bbox.find('xmin').text),
    50. int(bbox.find('ymin').text),
    51. int(bbox.find('xmax').text),
    52. int(bbox.find('ymax').text)]
    53. #首次确定裁剪区域
    54. crop_area.append([x1, y1, x2, y2])
    55. elif name==label_name:
    56. # 读取检测框的左上、右下角点的坐标
    57. bbox = obj.find('bndbox')
    58. x1, y1, x2, y2 = [int(bbox.find('xmin').text),
    59. int(bbox.find('ymin').text),
    60. int(bbox.find('xmax').text),
    61. int(bbox.find('ymax').text)]
    62. #首次确定裁剪区域
    63. label_area.append([x1, y1, x2, y2])
    64. matchs=[]
    65. for i in crop_area:
    66. match={}
    67. match["area"]=i
    68. match["labels"]=[]
    69. for j in label_area:
    70. if j[0]>=i[0] and j[0]<=i[2]:
    71. if j[1]>=i[1] and j[1]<=i[3] or j[3]>=i[1] and j[3]<=i[3]:
    72. match["labels"].append(j)
    73. elif j[2]>=i[0] and j[2]<=i[2]:
    74. if j[1] >= i[1] and j[1] <= i[3] or j[3] >= i[1] and j[3] <= i[3]:
    75. match["labels"].append(j)
    76. if len(match["labels"])!=0:
    77. min_x=min([k[0] for k in match["labels"]])
    78. max_x=max([k[2] for k in match["labels"]])
    79. min_y = min([k[1] for k in match["labels"]])
    80. max_y = max([k[3] for k in match["labels"]])
    81. print(min_x,min_y,max_x,max_y)
    82. print(match["area"][0])
    83. match["area"][0]=min(match["area"][0] ,min_x)
    84. match["area"][1]=min(match["area"][1] ,min_y)
    85. match["area"][2]=max(match["area"][2] ,max_x)
    86. match["area"][3]=max(match["area"][3] ,max_y)
    87. matchs.append(match.copy())
    88. #开始根据matchs 进行裁剪图片和生成xml
    89. len_matchs=len(matchs)
    90. image_count=0
    91. for match in matchs:
    92. image_count+=1
    93. #分割图片
    94. tree_=copy.deepcopy(tree_ori)
    95. image_crop=image_ori.copy()[match["area"][1]:match["area"][3],match["area"][0]:match["area"][2],:]
    96. cv2.imwrite(f"{save_image_path}/{fname}_{image_count}.JPG",image_crop)
    97. save_xml_name=f"{save_xmls_path}/{fname}_{image_count}.xml"
    98. ww,hh=image_crop.shape[:2]
    99. label_len=len(match["labels"])
    100. if label_len==0:
    101. continue
    102. a = tree_.find('size')
    103. a.find('width').text=f"{ww}"
    104. a.find('height').text=f"{hh}"
    105. if w == 0:
    106. return []
    107. for ind ,ob in enumerate( tree_.findall('object')):
    108. # 获取name
    109. if ind
    110. ob.find('name').text=f"{label_name}"
    111. bbox = ob.find("bndbox")
    112. bbox.find("xmin").text = f"{match['labels'][ind][0]-match['area'][0]}"
    113. bbox.find("ymin").text = f"{match['labels'][ind][1]-match['area'][1]}"
    114. bbox.find("xmax").text = f"{match['labels'][ind][2]-match['area'][0]}"
    115. bbox.find("ymax").text = f"{match['labels'][ind][3]-match['area'][1]}"
    116. else:
    117. tree_.getroot().remove(ob)
    118. tree_.write(save_xml_name)
    119. xs = ""
    120. with open(save_xml_name, 'r', encoding='utf8') as r:
    121. xs = r.read()
    122. r.close()
    123. with open(save_xml_name, 'w', encoding='utf8') as w:
    124. w.write(xs.replace("", ""))
    125. w.close()
    126. for i in os.listdir(xmls_path):
    127. read_xml(i)

  • 相关阅读:
    在线Excel的计算函数引入方法有哪些?提升工作效率的技巧分享!
    GPT最佳实践:五分钟打造你自己的GPT
    DQL语言进阶3
    DevExpress 22.1.3 源代码版本-2022
    iptables安全技术和防火墙
    【无标题】
    JVM调优笔记(一)--Nacos GC引发的服务批量下线问题
    JS sort排序
    更改linux centos 7系统语言
    Linux进程等待
  • 原文地址:https://blog.csdn.net/qq_55542491/article/details/133708331