记录一下labelme标注完之后生成yolo的txt格式标签

        前言:最近这两天因为数据集的问题,进行了一些简单的标注工作,使用labelme标注完成之后会生成json格式的文件(每张图对应一个json文件)。在获得json文件之后需要将其转换为txt格式。

               在标注完成之后,你可以自己划分文件夹得到两个文件夹:一个只包含图片,一个只包含json文件

以下是json转txt的具体步骤:

        (1)首先将json标签转VOC格式的xml标签

# -*- coding: utf-8 -*-
"""
Created on Sun May 31 10:19:23 2020
@author: ywx
#TODO:json转xml文件
#TODO:需要改动的地方为两个路径:①19行改为json格式所在路径;②21行整个数据集所在的路径;
#TODO:最后会在数据集路径下自动创建一个xmls路径用来存放xml的文件路径
"""
import os
from typing import List, Any
import numpy as np
import codecs
import json
from glob import glob
import cv2
import shutil
from sklearn.model_selection import train_test_split
# 1.标签路径
labelme_path = r"D:\datasets\small-object-detection-datasets\Solar_1200\json/"#这个路径是存放每个图片的json的路径
# 原始labelme标注数据路径
saved_path = r"D:\datasets\small-object-detection-datasets\Solar_1200/"#这个路径是这个数据集的路径

# 2.获取待处理文件
files = glob(labelme_path + "*.json")
files = [i.replace("\\","/").split("/")[-1].split(".json")[0] for i in files]
print(files)
# 4.读取标注信息并写入 xml
for json_file_ in files:
    json_filename = labelme_path + json_file_ + ".json"
    json_file = json.load(open(json_filename, "r", encoding="utf-8"))
    height, width, channels = cv2.imread(saved_path + "JPEGImages/" + json_file_ + ".tiff").shape
    # with codecs.open(saved_path + "labels/" + json_file_ + ".xml", "w", "utf-8") as xml:
    with codecs.open(saved_path + "xml/" + json_file_ + ".xml", "w", "utf-8") as xml:

        xml.write('<annotation>\n')
        xml.write('\t<folder>' + 'Solar' + '</folder>\n')
        xml.write('\t<filename>' + json_file_ + ".tiff" + '</filename>\n')
        xml.write('\t<source>\n')
        xml.write('\t\t<database>Unknown</database>\n')
        xml.write('\t</source>\n')
        xml.write('\t<size>\n')
        xml.write('\t\t<width>' + str(width) + '</width>\n')
        xml.write('\t\t<height>' + str(height) + '</height>\n')
        xml.write('\t\t<depth>' + str(channels) + '</depth>\n')
        xml.write('\t</size>\n')
        xml.write('\t\t<segmented>0</segmented>\n')
        for multi in json_file["shapes"]:
            points = np.array(multi["points"])
            labelName = multi["label"]
            xmin = min(points[:, 0])
            xmax = max(points[:, 0])
            ymin = min(points[:, 1])
            ymax = max(points[:, 1])
            label = multi["label"]
            if xmax <= xmin:
                pass
            elif ymax <= ymin:
                pass
            else:
                xml.write('\t<object>\n')
                xml.write('\t\t<name>' + labelName + '</name>\n')
                xml.write('\t\t<pose>Unspecified</pose>\n')
                xml.write('\t\t<truncated>1</truncated>\n')
                xml.write('\t\t<difficult>0</difficult>\n')
                xml.write('\t\t<bndbox>\n')
                xml.write('\t\t\t<xmin>' + str(int(xmin)) + '</xmin>\n')
                xml.write('\t\t\t<ymin>' + str(int(ymin)) + '</ymin>\n')
                xml.write('\t\t\t<xmax>' + str(int(xmax)) + '</xmax>\n')
                xml.write('\t\t\t<ymax>' + str(int(ymax)) + '</ymax>\n')
                xml.write('\t\t</bndbox>\n')
                xml.write('\t</object>\n')
                print(json_filename, xmin, ymin, xmax, ymax, label)
        xml.write('</annotation>')

        (2)生成一个image_id.txt文件

        这个txt文件的内容就是图片名的前缀,如下图我的图片名命名为000001~001200共1200张图,所要得到的txt文件就包含1200行

            

        (3)用xml文件生成yolo格式的txt标签文件(脚本如下,使用之前先看TODO后面的提示)

# -*- coding: utf-8 -*-
import xml.etree.ElementTree as ET
import os
from os import getcwd
'''使用这个脚本需要修改的代码为:
    ①13行classes修改成数据集对应的类别;②34行存储xml文本的路径;③36行、66行、67行存储txt文本的路径;④第68行的image_ids,要创建一个包含图片id的txt纯数字文件;
    ⑤第69行:创建一个文件夹(过程性的,不用管);⑥72行图片存储的路径(图片格式不是tiff的话要对应修改)。    
    
    
    '''
# sets = ['train', 'val', 'test']
sets = ['image_id']
classes = ['bl', 'ce', 'ch', 'cr', 'hi', 'ir',  'oi', 'pe'] # 改成自己的类别
# abs_path = os.getcwd()
# print(abs_path)


def convert(size, box):
    dw = 1. / (size[0])
    dh = 1. / (size[1])
    x = (box[0] + box[1]) / 2.0 - 1
    y = (box[2] + box[3]) / 2.0 - 1
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return x, y, w, h


def convert_annotation(image_id):
    #修改为xml文件存放的路径
    in_file = open('D:\datasets\small-object-detection-datasets\Solar_1200/xml/%s.xml' % (image_id), encoding='UTF-8')
   #修改为txt文件存放的路径
    out_file = open('D:\datasets\small-object-detection-datasets\Solar_1200/txt/%s.txt' % (image_id), 'w')
    tree = ET.parse(in_file)
    root = tree.getroot()
    size = root.find('size')
    w = int(size.find('width').text)
    h = int(size.find('height').text)
    for obj in root.iter('object'):
        difficult = obj.find('difficult').text
        # difficult = obj.find('Difficult').text
        cls = obj.find('name').text
        if cls not in classes or int(difficult) == 1:
            continue
        cls_id = classes.index(cls)
        xmlbox = obj.find('bndbox')
        b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
             float(xmlbox.find('ymax').text))
        b1, b2, b3, b4 = b
        # 标注越界修正
        if b2 > w:
            b2 = w
        if b4 > h:
            b4 = h
        b = (b1, b2, b3, b4)
        bb = convert((w, h), b)
        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')


wd = getcwd()
for image_set in sets:
    #存放在txt的标签路径
    if not os.path.exists('D:\datasets\small-object-detection-datasets\Solar_1200/txt/'):
        os.makedirs('D:\datasets\small-object-detection-datasets\Solar_1200/txt/')
    image_ids = open('D:\datasets\small-object-detection-datasets\Solar_1200/%s.txt' % (image_set)).read().strip().split()
    list_file = open('D:\datasets\small-object-detection-datasets\Solar_1200/0/%s.txt' % (image_set), 'w')
    for image_id in image_ids:
        # print(abs_path)
        list_file.write('D:\datasets\small-object-detection-datasets\Solar_1107\JPEGImages/%s.tiff\n' % (image_id))
        convert_annotation(image_id)
    list_file.close()

        这样之后就获得了yolo格式的txt文件夹,yolo格式转COCO格式要生成小目标的APs指标可以参考我这一篇小目标的检测指标APs怎么获得?------数据集Yolo格式生成json文件-CSDN博客的步骤,只需要使用图片文件夹和这篇博客生成的txt文件夹就可以了。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值