labelimg的xml文件转labelme的json文件
文章目录
- 前言
- 一、原始数据
- 二、文件转换
- 1.xml文件
- 2.转换代码
- 三、转换后的结果
- 总结
前言
labelimg和labelme是计算机视觉领域里非常常用的两款标注软件,然后,有时候我们会遇到需要转换标注文件的情况(其实是用惯了某款软件),为防止自己的脚本找不到,所以本篇文章用来记录将labelimg的xml标注文件转换成labelme的json文件。
一、原始数据
原始数据摆放如下:
其中,annotations里放的就是我们xml标注文件,jpegimages存放的即是我们的图片文件,标注结果可视化为:
二、文件转换
1.xml文件
正常情况下,xml标注文件里的内容如下:
所以,我们只需要读取文件后,通过xml.etree.ElementTree来解析内容即可。
2.转换代码
转换代码如下:
import xml.etree.ElementTree as ET
import json,glob,base64,os
from pathlib import Path
import shutil
#解析XML文件
def get_xml_data(xml_path):
tree = ET.parse(xml_path)
filename=tree.find("filename").text
objects=tree.findall("object")
objects_list=[] #储存目标的信息,格式为{class_name:boxes}
for object in objects:
object_dict={}
class_name=object.find("name").text
bndbox=object.find("bndbox")
xmin=bndbox.find("xmin").text
ymin=bndbox.find("ymin").text
xmax=bndbox.find("xmax").text
ymax=bndbox.find("ymax").text
boxes=[xmin,ymin,xmax,ymax]
object_dict[class_name]=boxes
objects_list.append(object_dict)
imgsize=tree.find("size")
w=imgsize.find("width").text
h=imgsize.find("height").text
objects_list.append({"imageWidth":w})
objects_list.append({"imageHeight":h})
return {filename:objects_list}
#base64读取图片
def img_base64(imgpath):
with open(imgpath,"rb") as f:
base64_str=base64.b64encode(f.read())
string=bytes.decode(base64_str)
return string
#生成labelme的json文件
def create_json(xml_data,img_dir,save_dir):
json_data={}
json_data["version"]="5.5.0"
json_data["flags"]={}
json_data["shapes"]=[]
for filename,box_data in xml_data.items():
imgpath=os.path.join(img_dir,filename)
if not os.path.exists(imgpath):
print(f"{imgpath} not exists")
break
json_data["imagePath"]=filename
for objects in box_data:
if "imageWidth" in objects:
json_data["imageWidth"]=int(objects["imageWidth"])
continue
if "imageHeight" in objects:
json_data["imageHeight"]=int(objects["imageHeight"])
continue
object_dict={"group_id":None}
object_dict["description"]=""
object_dict["shape_type"]="rectangle"
object_dict["flags"]={}
for class_name,box in objects.items():
object_dict["label"]=class_name
object_dict["points"]=[[int(box[0]),int(box[1])],[int(box[2]),int(box[3])]]
json_data["shapes"].append(object_dict)
imgpath=os.path.join(img_dir,filename)
json_data["imageData"]=img_base64(imgpath)
json_name=Path(filename).stem+".json"
print(json_name)
save_json_path=os.path.join(save_dir,json_name)
json.dump(json_data,open(save_json_path,"w"),indent=4)
save_img_path=os.path.join(save_dir,filename)
shutil.copy(imgpath,save_img_path)
if __name__ == '__main__':
xml_dir=r"xxx/Annotations"
img_dir=r"xxx/JPEGImages"
save_dir=os.path.join(xml_dir,"../json")
os.makedirs(save_dir,exist_ok=True)
xml_list=glob.glob(xml_dir+os.sep+"*.xml")
for xml_path in xml_list:
print(xml_path)
xml_data=get_xml_data(xml_path)
print(xml_data)
create_json(xml_data,img_dir,save_dir)
代码执行完成后会在我们jpegimages的统计目录下生成json文件夹,里面储存了图片及对应的json文件,如下:
三、转换后的结果
转换后的结果如下:
总结
以上,就是本篇文章的所有内容,如有问题,欢迎评论区交流。