labelme等标注的单个数据转voc标准数据集格式

单个数据转voc标准数据集格式

解决独立标注的数据,一键转为标准VOC格式

file_save = "yolo_format"

# 判断是否存在保存文件,如果存在则删除文件
if os.path.exists(file_save):
    shutil.rmtree(file_save)
# 新建文件
os.makedirs(file_save)

# 原始数据集标注文件路径
file_annotation = "Annotations"
file_images = "JPEGImages"
# 原始数据集标签
classes = []
traintxt = []
valtxt = []
train = {
    
    'images':[],'type':"instances",'annotations':[],'categories':[]}
val = {
    
    'images':[],'type':"instances",'annotations':[],'categories':[]}
# 遍历所有标签文件
for i in os.listdir(file_annotation):
    if "xml" not in i:
        continue
    # 获取该文件最后一个/除后缀名以外的内容
    temp_cat = {
    
    "supercategory":"none","id":0,"name":"080002"}
    temp_ann = {
    
    "area":1164024,"iscrowd":0,"category_id":12,"ignore":0,"image_id":0,"id":0, "bbox":[]}
    temp_img = {
    
    "file_name":"DZB_F_1.jpg","height":1386,"width":3031,"id":0}

    p = Path(i)
    name = p.stem
    stat = random.random()

    # 解析xml文件
    tree = ET.parse(os.path.join(file_annotation, i))
    root = tree.getroot()  # 获取根节点

    # 遍历子节点size
    for size in root.iter('size'):
        width = int(size.find('width').text)     # 获取图片的宽度
        height = int(size.find('height').text)   # 获取图片的高度
    temp_img["file_name"] = i.replace(".xml",".jpg")
    temp_img["height"] = height
    temp_img["width"] = width
    if stat>0.1:
        temp_img["id"] = len(train["images"])
        train["images"].append(copy.deepcopy(temp_img))
        traintxt.append(temp_img["file_name"].replace(".jpg",""))
    else:
        temp_img["id"] = len(val["images"])
        val["images"].append(copy.deepcopy(temp_img))
        valtxt.append(temp_img["file_name"].replace(".jpg",""))
        

    # 遍历子节点object
    for obj in root.iter('object'):
        cls = obj.find('name').text  # 获取标签名
        # 获取当前类别的id
        if cls not in classes:
            classes.append(cls)
            # 添加类型
            temp_cat["id"] = classes.index(cls)
            temp_cat["name"] = cls
            # 同时添加
            train["categories"].append(copy.deepcopy(temp_cat))
            val["categories"].append(copy.deepcopy(temp_cat))    
            
        cls_id = classes.index(cls)
        # 获取VOC格式标签的坐标信息
        xmlbox = obj.find('bndbox')
        xmin = int(xmlbox.find('xmin').text)
        ymin = int(xmlbox.find('ymin').text)
        xmax = int(xmlbox.find('xmax').text)
        ymax = int(xmlbox.find('ymax').text)
        #写入json
        if stat>0.1:
            #temp_ann = {"area":1164024,"iscrowd":0,"category_id":12,"ignore":0,"image_id":0,"id":0, "bbox":[]}
            temp_ann["area"] = (ymax - ymin) * (xmax - xmin)
            temp_ann["category_id"] = cls_id
            temp_ann["image_id"] = temp_img["id"]
            temp_ann["id"] = len(train["annotations"])
            temp_ann["bbox"] = [xmin, ymin, xmax, ymax]
            train["annotations"].append(copy.deepcopy(temp_ann))
        else:
            #temp_ann = {"area":1164024,"iscrowd":0,"category_id":12,"ignore":0,"image_id":0,"id":0, "bbox":[]}
            temp_ann["area"] = (ymax - ymin) * (xmax - xmin)
            temp_ann["category_id"] = cls_id
            temp_ann["image_id"] = temp_img["id"]
            temp_ann["id"] = len(val["annotations"])
            temp_ann["bbox"] = [xmin, ymin, xmax, ymax]
            val["annotations"].append(copy.deepcopy(temp_ann))

# 新建和标签文件同名的txt文件
with open("label.txt", "w") as file:
    classes = "\n".join(classes)
    file.write(classes)
with open("train.txt", "w") as file:
    classes = "\n".join(traintxt)
    file.write(classes)
with open("val.txt", "w") as file:
    classes = "\n".join(valtxt)
    file.write(classes)
#保存json
import json
with open("train.json", "w") as file:
    file.write(json.dumps(train))
with open("val.json", "w") as file:
    file.write(json.dumps(val))

猜你喜欢

转载自blog.csdn.net/weixin_44242403/article/details/145864706
今日推荐