yolo2coco

将YOLO格式 的数据集转换为COCO格式

  1. 按照如上文件格式创建对应的文件夹
  2. 在COCO文件加下新建一个 classes.txt 文件如图:
  3. 运行代码:
    """
    YOLO 格式的数据集转化为 COCO 格式的数据集
    --root_dir 输入根路径
    --save_path 保存文件的名字(没有random_split时使用)
    --random_split 有则会随机划分数据集,然后再分别保存为3个文件。
    --split_by_file 按照 ./train.txt ./val.txt ./test.txt 来对数据集进行划分。
    """
    
    import os
    import cv2
    import json
    from tqdm import tqdm
    from sklearn.model_selection import train_test_split
    import argparse
    
    parser = argparse.ArgumentParser()
    parser.add_argument('--root_dir', default='C:/Users/ad/Desktop/night-coco', type=str,
                        help="root path of images and labels, include ./images and ./labels and classes.txt")
    parser.add_argument('--save_path', type=str, default=r'./train.json',
                        help="if not split the dataset, give a path to a json file")
    parser.add_argument('--random_split', action='store_true', help="random split the dataset, default ratio is 8:1:1")
    parser.add_argument('--split_by_file', action='store_true',
                        help="define how to split the dataset, include ./train.txt ./val.txt ./test.txt ")
    
    arg = parser.parse_args()
    
    
    def train_test_val_split_random(img_paths, ratio_train=0.8, ratio_test=0.1, ratio_val=0.1):
        # 这里可以修改数据集划分的比例。
        assert int(ratio_train + ratio_test + ratio_val) == 1
        train_img, middle_img = train_test_split(img_paths, test_size=1 - ratio_train, random_state=233)
        ratio = ratio_val / (1 - ratio_train)
        val_img, test_img = train_test_split(middle_img, test_size=ratio, random_state=233)
        print("NUMS of train:val:test = {}:{}:{}".format(len(train_img), len(val_img), len(test_img)))
        return train_img, val_img, test_img
    
    
    def train_test_val_split_by_files(img_paths, root_dir):
        # 根据文件 train.txt, val.txt, test.txt(里面写的都是对应集合的图片名字) 来定义训练集、验证集和测试集
        phases = ['train', 'val', 'test']
        img_split = []
        for p in phases:
            define_path = os.path.join(root_dir, f'{p}.txt')
            print(f'Read {p} dataset definition from {define_path}')
            assert os.path.exists(define_path)
            with open(define_path, 'r') as f:
                img_paths = f.readlines()
                # img_paths = [os.path.split(img_path.strip())[1] for img_path in img_paths]  # NOTE 取消这句备注可以读取绝对地址。
                img_split.append(img_paths)
        return img_split[0], img_split[1], img_split[2]
    
    
    def yolo2coco(arg):
        root_path = arg.root_dir
        print("Loading data from ", root_path)
    
        assert os.path.exists(root_path)
        originLabelsDir = os.path.join(root_path, 'labels')
        originImagesDir = os.path.join(root_path, 'images')
        with open(os.path.join(root_path, 'classes.txt')) as f:
            classes = f.read().strip().split()
        # images dir name
        indexes = os.listdir(originImagesDir)
    
        if arg.random_split or arg.split_by_file:
            # 用于保存所有数据的图片信息和标注信息
            train_dataset = {'categories': [], 'annotations': [], 'images': []}
            val_dataset = {'categories': [], 'annotations': [], 'images': []}
            test_dataset = {'categories': [], 'annotations': [], 'images': []}
    
            # 建立类别标签和数字id的对应关系, 类别id从0开始。
            for i, cls in enumerate(classes, 0):
                train_dataset['categories'].append({'id': i, 'name': cls, 'supercategory': 'mark'})
                val_dataset['categories'].append({'id': i, 'name': cls, 'supercategory': 'mark'})
                test_dataset['categories'].append({'id': i, 'name': cls, 'supercategory': 'mark'})
    
            if arg.random_split:
                print("spliting mode: random split")
                train_img, val_img, test_img = train_test_val_split_random(indexes, 0.8, 0.1, 0.1)
            elif arg.split_by_file:
                print("spliting mode: split by files")
                train_img, val_img, test_img = train_test_val_split_by_files(indexes, root_path)
        else:
            dataset = {'categories': [], 'annotations': [], 'images': []}
            for i, cls in enumerate(classes, 0):
                dataset['categories'].append({'id': i, 'name': cls, 'supercategory': 'mark'})
    
        # 标注的id
        ann_id_cnt = 0
        for k, index in enumerate(tqdm(indexes)):
            # 支持 png jpg 格式的图片。
            txtFile = index.replace('images', 'txt').replace('.jpg', '.txt').replace('.png', '.txt')
            # 读取图像的宽和高
            im = cv2.imread(os.path.join(root_path, 'images/') + index)
            height, width, _ = im.shape
            if arg.random_split or arg.split_by_file:
                # 切换dataset的引用对象,从而划分数据集
                if index in train_img:
                    dataset = train_dataset
                elif index in val_img:
                    dataset = val_dataset
                elif index in test_img:
                    dataset = test_dataset
            # 添加图像的信息
            dataset['images'].append({'file_name': index,
                                      'id': k,
                                      'width': width,
                                      'height': height})
            if not os.path.exists(os.path.join(originLabelsDir, txtFile)):
                # 如没标签,跳过,只保留图片信息。
                continue
            with open(os.path.join(originLabelsDir, txtFile), 'r') as fr:
                labelList = fr.readlines()
                for label in labelList:
                    label = label.strip().split()
                    x = float(label[1])
                    y = float(label[2])
                    w = float(label[3])
                    h = float(label[4])
    
                    # convert x,y,w,h to x1,y1,x2,y2
                    H, W, _ = im.shape
                    x1 = (x - w / 2) * W
                    y1 = (y - h / 2) * H
                    x2 = (x + w / 2) * W
                    y2 = (y + h / 2) * H
                    # 标签序号从0开始计算, coco2017数据集标号混乱,不管它了。
                    cls_id = int(label[0])
                    width = max(0, x2 - x1)
                    height = max(0, y2 - y1)
                    dataset['annotations'].append({
                        'area': width * height,
                        'bbox': [x1, y1, width, height],
                        'category_id': cls_id,
                        'id': ann_id_cnt,
                        'image_id': k,
                        'iscrowd': 0,
                        # mask, 矩形是从左上角点按顺时针的四个顶点
                        'segmentation': [[x1, y1, x2, y1, x2, y2, x1, y2]]
                    })
                    ann_id_cnt += 1
    
        # 保存结果
        folder = os.path.join(root_path, 'annotations')
        if not os.path.exists(folder):
            os.makedirs(folder)
        if arg.random_split or arg.split_by_file:
            for phase in ['train', 'val', 'test']:
                json_name = os.path.join(root_path, 'annotations/{}.json'.format(phase))
                with open(json_name, 'w') as f:
                    if phase == 'train':
                        json.dump(train_dataset, f)
                    elif phase == 'val':
                        json.dump(val_dataset, f)
                    elif phase == 'test':
                        json.dump(test_dataset, f)
                print('Save annotation to {}'.format(json_name))
        else:
            json_name = os.path.join(root_path, 'annotations/{}'.format(arg.save_path))
            with open(json_name, 'w') as f:
                json.dump(dataset, f)
                print('Save annotation to {}'.format(json_name))
    
    
    if __name__ == "__main__":
        yolo2coco(arg)
    
    
  4. 参数说明:

    --root_path # 输入根目录$ROOT_PATH的位置。
    --save_path # 如果不进行数据集划分,可利用此参数指定输出文件的名字,默认保存为train.json
    --random_split # 随机划分参数,若指定--random_split参数,则输出在annotations文件夹下包含
                   # train.json val.json test.json (默认随机划分成8:1:1)
    --split_by_file # 自定义数据集划分,若指定--split_by_file参数,则输出在annotations文件夹
    #  train.json val.json test.json。需要在$ROOT_PATH文件下有 ./train.txt ./val.txt #
    # ./test.txt ,可以这3个文件来定义训练集、验证集、测试集。注意, 这里里面填写的应是图片文件名字,
    # 而不是图片的绝对地址。
    #(在line 43也自行可以修改一下读取方式,为了方便起见,不推荐把图片放在不同位置)

  • 22
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: /yolo-coco/coco.names 是一个包含80个类别标签的文本文件,用于训练和测试物体检测算法。这些类别标签包括常见对象和动物,例如汽车、人、狗、猫等等。这些标签的存在使得算法能够自动识别和定位图像中的物体,为图像分类和物体检测提供了基础。/coco.names文件经过多个数据集的筛选和组合,代表了公认的物体类别,并广泛应用于目标检测和图像识别领域。/dev/yolo-coco/目录是,在YOLO V3目标检测算法中,训练数据与配置文件的扩展存储程序。它包含COCA(Common Object in Context)数据集中的200,000张图像及其相应的注释。这些图像广泛涵盖日常场景中的各种物体,并为算法提供了足够的训练样本。此外,该目录还包含其他用于训练模型的文件,包括权重文件、配置文件以及可执行程序等。因此,/yolo-coco/coco.names 是目标检测算法的必要文件之一,它提供了对常见物体类别的定义,使算法能够准确识别和定位各种对象。 ### 回答2: '/yolo-coco/coco.names'是一个文件路径,表示存放COCO数据集标签名称的文本文件。COCO(Common Objects in Context)数据集是一个用于目标检测、分割、图像生成、姿态估计等任务的广泛使用的图像数据集,其中包含80种常见对象的标注,如人、车、动物、家具等。每个对象都有一个唯一的整数ID和对应的名称。 /coco.names文件中列出了COCO数据集中所有80个对象的名称,每行一个。这些名称格式为英文小写单词,以空格或下划线分隔。这些名称包括:person、bicycle、car、dog、cat、chair、table等。使用这些对象名称,可以方便地构建自己的目标检测或图像分割模型,进行深度学习训练和预测。 总之,在深度学习中,标签名称文件非常重要,因为它在数据集处理、特征提取、模型训练和测试中都扮演着至关重要的角色。通过查看/yolo-coco/coco.names文件,可以了解COCO数据集中包含哪些对象,从而更好地理解数据集和模型的特点。 ### 回答3: /yolo-coco/coco.names是一个文本文件,包含了COCO数据集的80个类别的名称。这些类别包括了人、动物、车辆、家具、食品等日常生活中常见的物体。该文件通常是在使用YOLO算法进行目标检测时需要调用的,因为YOLO算法需要知道要检测的目标类别并进行相应的分类和定位。通过读取/yolo-coco/coco.names文件,算法就能够获得目标类别的名称,从而准确地识别和标记出物体位置。该文件的格式很简单,每个类别名称占据一行,没有其他注释或说明。不过,由于COCO数据集是一个非常流行的目标检测数据集,在使用YOLO算法时我们需要提前下载和准备好这个文件。除此之外,我们还需要了解每个类别的名称,以便我们在进行目标检测时能够快速识别它们。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值