目录
lxml windows安装
读取示例
可视化
生成示例
上面是代码,下面有调用示例
api调用代码,其实只有几行:
这个生成代码也很简洁:
python生成voc xml文件_jacke121的专栏-CSDN博客
lxml windows安装
pip install lxml可能失败,
一种可行方法,在这里下载对应版本whl,然后安装,亲测OK。
lxml · PyPI
读取示例
import os
import cv2
import numpy as np
import xml.etree.ElementTree as ET
CLASSES = ('m',)
_class_to_ind=dict(list(zip(CLASSES, list(range(len(CLASSES))))))
def get_label(label_path,shape, flip&#61;False):h, w, c &#61; shapeannotations &#61; np.zeros((0, 5),dtype&#61;np.float32)if os.path.exists(label_path):tree &#61; ET.parse(label_path)objs &#61; tree.findall(&#39;object&#39;)for ix, obj in enumerate(objs):if obj.find(&#39;name&#39;).text.lower().strip() not in _class_to_ind:# logging.info("label not select: {}".format(obj.find(&#39;name&#39;).text.lower().strip()))continuebbox &#61; obj.find(&#39;bndbox&#39;)x1 &#61; max(float(bbox.find(&#39;xmin&#39;).text), 1) # - 1y1 &#61; max(float(bbox.find(&#39;ymin&#39;).text), 1) # - 1x2 &#61; min(float(bbox.find(&#39;xmax&#39;).text), 10000) # - 1y2 &#61; min(float(bbox.find(&#39;ymax&#39;).text), 10000) # - 1if obj.find("difficult") is not None and obj.find("difficult").text &#61;&#61; &#39;1&#39;:if (x2-x1) * (y2-y1)<10*10:continue
可视化
import os
import cv2
import reimport xml.etree.ElementTree as ETCLASSES &#61; (&#39;car&#39;,)
_class_to_ind&#61;dict(list(zip(CLASSES, list(range(len(CLASSES))))))if __name__ &#61;&#61; &#39;__main__&#39;:image_dir &#61; r&#39;G:\img&#39;xml_dir &#61; r&#39;G:\xml&#39;image_list &#61; os.listdir(image_dir)cnt &#61; 0for i in image_list:image_path &#61; os.path.join(image_dir ,i)xml_path &#61; os.path.join(xml_dir ,os.path.splitext(i)[0 ] &#43;&#39;.xml&#39;)tree &#61; ET.parse(xml_path)objs &#61; tree.findall(&#39;object&#39;)image &#61; cv2.imread(image_path)for ix, obj in enumerate(objs):if obj.find(&#39;name&#39;).text.lower().strip() not in _class_to_ind:# logging.info("label not select: {}".format(obj.find(&#39;name&#39;).text.lower().strip()))continuebbox &#61; obj.find(&#39;bndbox&#39;)x1 &#61; max(float(bbox.find(&#39;xmin&#39;).text), 1) # - 1y1 &#61; max(float(bbox.find(&#39;ymin&#39;).text), 1) # - 1x2 &#61; min(float(bbox.find(&#39;xmax&#39;).text), 10000) # - 1y2 &#61; min(float(bbox.find(&#39;ymax&#39;).text), 10000) # - 1cv2.rectangle(image, (int(x1), int(y1)), (int(x2), int(y2)), (255, 0, 0), thickness&#61;2)# cv2.putText(image, info[0], (info[1], info[2]), cv2.FONT_HERSHEY_PLAIN, 0.5, (0, 0, 255), 1)cv2.imshow("image",image)cv2.waitKey()
生成示例
上面是代码&#xff0c;下面有调用示例
api调用代码&#xff0c;其实只有几行&#xff1a;
anno &#61; GEN_Annotations(pic_path)anno.set_size(new_width, new_height, 3)for (x, y, w, h,name) in bbox_list:anno.add_pic_attr(name, x, y, w, h)save_xml_path&#61;xml_path.replace(base_path,save_pic_path)os.makedirs(os.path.dirname(save_xml_path), exist_ok&#61;True)anno.savefile(save_xml_path)
# -*- coding: utf-8 -*-import osfrom lxml import etreeclass GEN_Annotations:def __init__(self, filename):self.root &#61; etree.Element("annotation")child1 &#61; etree.SubElement(self.root, "folder")child1.text &#61; "VOC2007"child2 &#61; etree.SubElement(self.root, "filename")child2.text &#61; filenamechild3 &#61; etree.SubElement(self.root, "source")# child2.set("database", "The VOC2007 Database")child4 &#61; etree.SubElement(child3, "annotation")child4.text &#61; "PASCAL VOC2007"child5 &#61; etree.SubElement(child3, "database")child6 &#61; etree.SubElement(child3, "image")child6.text &#61; "flickr"child7 &#61; etree.SubElement(child3, "flickrid")child7.text &#61; "35435"# root.append( etree.Element("child1") )# root.append( etree.Element("child1", interesting&#61;"totally"))# child2 &#61; etree.SubElement(root, "child2")# child3 &#61; etree.SubElement(root, "child3")# root.insert(0, etree.Element("child0"))def set_size(self,witdh,height,channel):size &#61; etree.SubElement(self.root, "size")widthn &#61; etree.SubElement(size, "width")widthn.text &#61; str(witdh)heightn &#61; etree.SubElement(size, "height")heightn.text &#61; str(height)channeln &#61; etree.SubElement(size, "channel")channeln.text &#61; str(channel)def savefile(self,filename):tree &#61; etree.ElementTree(self.root)tree.write(filename, pretty_print&#61;True, xml_declaration&#61;False, encoding&#61;&#39;utf-8&#39;)def add_pic_attr(self,label,x,y,w,h,diffi_&#61;0):object &#61; etree.SubElement(self.root, "object")namen &#61; etree.SubElement(object, "name")namen.text &#61; labeldiffi &#61; etree.SubElement(object, "difficult")diffi.text &#61; str(diffi_)truncated_ &#61; etree.SubElement(object, "truncated")truncated_.text &#61; str(0)bndbox &#61; etree.SubElement(object, "bndbox")xminn &#61; etree.SubElement(bndbox, "xmin")xminn.text &#61; str(x)yminn &#61; etree.SubElement(bndbox, "ymin")yminn.text &#61; str(y)xmaxn &#61; etree.SubElement(bndbox, "xmax")xmaxn.text &#61; str(x&#43;w)ymaxn &#61; etree.SubElement(bndbox, "ymax")ymaxn.text &#61; str(y&#43;h)
调用&#xff1a;
import cv2
import xml.etree.ElementTree as ETdef change_size(pic_path, xml_path,base_path,save_pic_path):img &#61; cv2.imread(pic_path)if img is None:print(&#39;img is null&#39;, pic_path)returnif img.shape[1] <1 or img.shape[0] <1:print(&#39;img is null&#39;, pic_path)returnheight,width&#61;img.shape[:2]new_width &#61; widthnew_height &#61; heightif height>700 and width>1200:new_width &#61; int(width * 0.8)new_height &#61; int(height * 0.8)img&#61;cv2.resize(img,(new_width,new_height))if new_height!&#61;576 or new_width!&#61;1024:print(new_height,new_width,pic_path)pic_path &#61; pic_path.replace(base_path, save_pic_path)os.makedirs(os.path.dirname(pic_path), exist_ok&#61;True)cv2.imwrite(pic_path, img)if os.path.exists(xml_path):tree &#61; ET.parse(xml_path)# file_objs &#61; tree.findall(&#39;filename&#39;)objs &#61; tree.findall(&#39;object&#39;)objs_diffi &#61; tree.findall(&#39;object/difficult&#39;)if len(objs_diffi)&#61;&#61;0:print(xml_path, objs_diffi, len(objs_diffi))bbox_list &#61; []for ix, obj in enumerate(objs):name &#61; obj.find(&#39;name&#39;).textbbox &#61; obj.find(&#39;bndbox&#39;)x1 &#61; int(int(bbox.find(&#39;xmin&#39;).text)*0.8)y1 &#61; int(int(bbox.find(&#39;ymin&#39;).text)*0.8)x2 &#61; int(int(bbox.find(&#39;xmax&#39;).text)*0.8)y2 &#61; int(int(bbox.find(&#39;ymax&#39;).text)*0.8)bbox_list.append((x1,y1,(x2-x1),(y2-y1),name))anno &#61; GEN_Annotations(pic_path)anno.set_size(new_width, new_height, 3)for (x, y, w, h,name) in bbox_list:anno.add_pic_attr(name, x, y, w, h)save_xml_path&#61;xml_path.replace(base_path,save_pic_path)os.makedirs(os.path.dirname(save_xml_path), exist_ok&#61;True)anno.savefile(save_xml_path)if __name__ &#61;&#61; &#39;__main__&#39;:# save file pathsource_base_path &#61; r&#39;D:\Team-CV\dataset\chumao_train/&#39;save_base_path &#61; r&#39;D:\Team-CV\dataset\chumao_train_1024/&#39;os.makedirs(save_base_path, exist_ok&#61;True)# file pathg &#61; os.walk(source_base_path)pic_files &#61; [&#39;%s\\%s&#39; % (i[0], j) for i in g if i[0].endswith(&#39;JPEGImages&#39;) for j in i[-1] if j.endswith(&#39;jpg&#39;)]for i,pic_file in enumerate(pic_files):if &#39;JPEGImages&#39; in pic_file:xml_file &#61; pic_file.replace(&#39;JPEGImages&#39;,&#39;Annotations&#39;).replace(&#39;.jpg&#39;,&#39;.xml&#39;)change_size(pic_file, xml_file,source_base_path,save_base_path)print(i,pic_file)