cityscapes数据集转换为COCO数据集格式【速来,我吃过的苦,兄弟们就别再吃了】

利用CityScapes数据集,将其转换为COCO格式的实例分割数据集

– – – 进而再训练出新的YOLOv8-seg模型

写个前言:
人嘛,总想着偷点懒,有现成的数据集,就得拿来用,是吧?确实是这样。
接下来的步骤大概有这么几个,as follow.
S1:下载好cityscapes数据集【小的是带json的,大的是原图】
S2:将cityscapes转换为YOLO格式的JSON文件
S3:将此JSON文件转换为多个TXT文件【每个TXT对应自己的IMAGE
S4:(根据需要,看看是不是自己要再加类别啥的)将这些个TXT文件转换成labelme对应的JSON文件
S5:(续S4)直接打开labelme,OK,至此和我的上一篇文章形成套环:

上一篇文章链接

S1:下载好cityscapes数据集【小的是带json的,大的是原图】
在这里插入图片描述
在这里插入图片描述
解压后,简单测试一个城市的,就比如Aachen:
分别把这俩数据集解压出来的Aachen城市的数据拿出来【我是分别单独给创建个dev测试目录存的】
在这里插入图片描述

S2:将cityscapes转换为YOLO格式的JSON文件transcityscapes2coco_dev.py】【随便放位置】

import sys

if "/opt/ros/kinetic/lib/python2.7/dist-packages" in sys.path:
    sys.path.remove("/opt/ros/kinetic/lib/python2.7/dist-packages")

import cv2
import json
import os
from PIL import Image
import numpy as np
from pycococreatortools import pycococreatortools

ROOT_DIR = 'C:/Users/ycc/Desktop/cityscapes2coco-master/cityscape'
IMAGE_DIR = os.path.join(ROOT_DIR, "leftImg8bit/train_dev")
ANNOTATION_DIR = os.path.join(ROOT_DIR, "gtFine/train_dev")
ANNOTATION_SAVE_DIR = os.path.join(ROOT_DIR, "annotations")  # annotations是新创建的
INSTANCE_DIR = os.path.join(ROOT_DIR, "gtFine/train_dev")
IMAGE_SAVE_DIR = os.path.join(ROOT_DIR, "val_images")  # train_images是新创建的

INFO = {
    "description": "Cityscapes_Instance Dataset",
    "url": "https://github.com/waspinator/pycococreator",
    "version": "0.1.0",
    "year": "2020",
    "contributor": "Kevin_Jia",
    "date_created": "2020-1-23 19:19:19.123456"
}

LICENSES = [
    {
        "id": 1,
        "name": "Attribution-NonCommercial-ShareAlike License",
        "url": "http://creativecommons.org/licenses/by-nc-sa/2.0/"
    }
]

CATEGORIES = [
    {
        'id': 1,
        'name': 'car',
        'supercategory': 'cityscapes',
    },
    {
        'id': 2,
        'name': 'pedestrian',
        'supercategory': 'cityscapes',
    },
    {
        'id': 3,
        'name': 'truck',
        'supercategory': 'cityscapes',
    },
    {
        'id': 4,
        'name': 'bus',
        'supercategory': 'cityscapes',
    },
    {
        'id': 5,
        'name': 'rider',
        'supercategory': 'cityscapes',
    },
    {
        'id': 6,
        'name': 'caravan',
        'supercategory': 'cityscapes',
    },
    {
        'id': 7,
        'name': 'motorcycle',
        'supercategory': 'cityscapes',
    },
    {
        'id': 8,
        'name': 'bicycle',
        'supercategory': 'cityscapes',
    }
]

background_label = list(range(-1, 24, 1)) + [30, 31, 34]

idx = 0
pic_scale = 1.0
h_bias = 1.0


def image_trans():
    img_subfolders = os.listdir(IMAGE_DIR)
    image_count = 0
    for sub in img_subfolders:
        # sub_path = sub + '/' + sub
        image_sub_path = os.path.join(IMAGE_DIR, sub)
        for image in os.listdir(image_sub_path):
            img_path = os.path.join(image_sub_path, image)
            ann_name = image.split('_')[0] + '_' + image.split('_')[1] + '_' + image.split('_')[
                2] + '_gtFine_instanceIds.png'
            ann_sub_path = os.path.join(ANNOTATION_DIR, sub)
            ann_path = os.path.join(ann_sub_path, ann_name)
            if os.path.exists(ann_path):
                pic = cv2.imread(img_path)
                h, w = pic.shape[:2]
                new_w = w * pic_scale
                new_h = new_w / 2
                top = int((h_bias * h - new_h) / 2)
                bottom = int((h_bias * h + new_h) / 2)
                left = int((w - new_w) / 2)
                right = int((w + new_w) / 2)
                roi = pic[top:bottom, left:right]
                img_save_path = os.path.join(IMAGE_SAVE_DIR, image)
                cv2.imwrite(img_save_path, roi)
                annotation = cv2.imread(ann_path, -1)
                ann_roi = annotation[top:bottom, left:right]
                ann_save_path = os.path.join(ANNOTATION_SAVE_DIR, ann_name)
                cv2.imwrite(ann_save_path, ann_roi)
            else:
                print(image + '  do not have instance annotation')
            print(image_count)
            image_count += 1


def data_loader():
    imgs = os.listdir(IMAGE_SAVE_DIR)
    masks_generator(imgs, ANNOTATION_SAVE_DIR)


def masks_generator(imges, ann_path):
    global idx
    pic_count = 0
    for pic_name in imges:
        image_name = pic_name.split('.')[0]
        ann_folder = os.path.join(INSTANCE_DIR, image_name)
        os.mkdir(ann_folder)
        annotation_name = pic_name.split('_')[0] + '_' + pic_name.split('_')[1] + '_' + pic_name.split('_')[
            2] + '_gtFine_instanceIds.png'
        # annotation_name = image_name + '_instanceIds.png'
        print(annotation_name)
        annotation = cv2.imread(os.path.join(ann_path, annotation_name), -1)
        h, w = annotation.shape[:2]
        ids = np.unique(annotation)
        for id in ids:
            if id in background_label:
                continue
            else:
                class_id = id // 1000
                if class_id == 26:
                    instance_class = 'car'
                elif class_id == 24:
                    instance_class = 'pedestrian'
                elif class_id == 27:
                    instance_class = 'truck'
                elif class_id == 28:
                    instance_class = 'bus'
                elif class_id == 25:
                    instance_class = 'rider'
                elif class_id == 29:
                    instance_class = 'caravan'
                elif class_id == 32:
                    instance_class = 'motorcycle'
                elif class_id == 33:
                    instance_class = 'bicycle'
                else:
                    continue
            instance_mask = np.zeros((h, w, 3), dtype=np.uint8)
            mask = annotation == id
            instance_mask[mask] = 255
            mask_name = image_name + '_' + instance_class + '_' + str(idx) + '.png'
            cv2.imwrite(os.path.join(ann_folder, mask_name), instance_mask)
            idx += 1
        pic_count += 1
        print(pic_count)


def json_generate():
    car = 0
    pedestrian = 0
    truck = 0
    bus = 0
    rider = 0
    caravan = 0
    motorcycle = 0
    bicycle = 0
    files = os.listdir(IMAGE_SAVE_DIR)

    coco_output = {
        "info": INFO,
        "licenses": LICENSES,
        "categories": CATEGORIES,
        "images": [],
        "annotations": []
    }

    image_id = 1
    segmentation_id = 1

    # go through each image
    for image_filename in files:
        image_name = image_filename.split('.')[0]
        image_path = os.path.join(IMAGE_SAVE_DIR, image_filename)
        image = Image.open(image_path)
        image_info = pycococreatortools.create_image_info(
            image_id, os.path.basename(image_filename), image.size)
        coco_output["images"].append(image_info)
        print(image_filename)
        annotation_sub_path = os.path.join(INSTANCE_DIR, image_name)
        ann_files = os.listdir(annotation_sub_path)
        if len(ann_files) == 0:
            print("ao avaliable annotation")
            continue
        else:
            for annotation_filename in ann_files:
                annotation_path = os.path.join(annotation_sub_path, annotation_filename)
                for x in CATEGORIES:
                    if x['name'] in annotation_filename:
                        class_id = x['id']
                        break
                # class_id = [x['id'] for x in CATEGORIES if x['name'] in annotation_filename][0]
                if class_id == 1:
                    car += 1
                elif class_id == 2:
                    pedestrian += 1
                elif class_id == 3:
                    truck += 1
                elif class_id == 4:
                    bus += 1
                elif class_id == 5:
                    rider += 1
                elif class_id == 6:
                    caravan += 1
                elif class_id == 7:
                    motorcycle += 1
                elif class_id == 8:
                    bicycle += 1
                else:
                    print('illegal class id')
                category_info = {'id': class_id, 'is_crowd': 'crowd' in image_filename}
                binary_mask = np.asarray(Image.open(annotation_path)
                                         .convert('1')).astype(np.uint8)

                annotation_info = pycococreatortools.create_annotation_info(
                    segmentation_id, image_id, category_info, binary_mask,
                    image.size, tolerance=2)

                if annotation_info is not None:
                    coco_output["annotations"].append(annotation_info)

                    segmentation_id = segmentation_id + 1

            image_id = image_id + 1
            print(image_id)

    with open('{}/val_modified.json'.format(ROOT_DIR), 'w') as output_json_file:
        json.dump(coco_output, output_json_file)
    print(car, pedestrian, truck, bus, rider, caravan, motorcycle, bicycle)


if __name__ == "__main__":
    image_trans()
    data_loader()
    json_generate()



执行代码结束后,得到:val_modified.json【和你的数据集同目录】
Ctrl+Alt+L格式化一下JSON,好看一些。
在这里插入图片描述

S3:将此JSON文件转换为多个TXT文件【每个TXT对应自己的IMAGE**】**
【convert_coco_dev1.py】【随便放个地方】【注释掉的部分,是detect转换,不动代码的话,就是seg转换】

import json
import os


def convert_coco_to_yolo(coco_data):
    image_list = coco_data['images']
    annotations = coco_data['annotations']
    categories = coco_data['categories']

    yolo_data = []
    category_dict = {}  # 用于存储类别名和对应的序号
    for i, category in enumerate(categories):  # 构建类别名和序号的映射关系
        category_dict[category['name']] = i

    for image in image_list:
        image_id = image['id']
        file_name = image['file_name']
        width = image['width']
        height = image['height']

        image_annotations = [ann for ann in annotations if ann['image_id'] == image_id]
        yolo_annotations = []
        for ann in image_annotations:
            category_id = ann['category_id']
            category = next((cat for cat in categories if cat['id'] == category_id), None)
            if category is None:
                continue

            # bbox = ann['bbox']
            # x, y, w, h = bbox
            # x_center = x + w / 2
            # y_center = y + h / 2
            # normalized_x_center = x_center / width
            # normalized_y_center = y_center / height
            # normalized_width = w / width
            # normalized_height = h / height

            # 实例分割代码:
            segmentation = ann['segmentation']
            yolo_annotations.append({
                'category': category_dict[category['name']],  # 使用类别序号
                'seg': [site for site in segmentation]
            })

            # yolo_annotations.append({
            #     'category': category_dict[category['name']],  # 使用类别序号
            #     'x_center': normalized_x_center,
            #     'y_center': normalized_y_center,
            #     'width': normalized_width,
            #     'height': normalized_height
            # })

        if yolo_annotations:
            yolo_annotations.sort(key=lambda x: x['category'])  # 按类别序号排序
            yolo_data.append({
                'file_name': file_name,
                'width': width,
                'height': height,
                'annotations': yolo_annotations
            })

    return yolo_data, category_dict


path = 'C:/Users/ycc/Desktop/cityscapes2coco-master/cityscape'  # 修改为包含 via_export_coco.json 文件的目录路径
file_name = 'val_modified.json'  # 文件名
save_dir = 'C:/Users/ycc/Desktop/cityscapes2coco-master/cityscape/yolo/labels'  # 保存目录
file_path = os.path.join(path, file_name)  # 完整文件路径

if os.path.isfile(file_path):  # 检查文件是否存在
    with open(file_path, 'r', encoding='utf-8') as load_f:
        load_dict = json.load(load_f)
        yolo_data, category_dict = convert_coco_to_yolo(load_dict)

    os.makedirs(save_dir, exist_ok=True)  # 创建保存目录

    # 生成 class.txt 文件
    class_file_path = os.path.join(save_dir, 'classes.txt')
    with open(class_file_path, 'w', encoding='utf-8') as class_f:
        for category_name, category_index in sorted(category_dict.items(), key=lambda x: x[1]):
            class_f.write(f"{category_name}\n")

    for data in yolo_data:
        file_name = os.path.basename(data['file_name'])  # 提取文件名部分
        width = data['width']
        height = data['height']
        annotations = data['annotations']

        txt_file_path = os.path.join(save_dir, os.path.splitext(file_name)[0] + '.txt')

        with open(txt_file_path, 'w', encoding='utf-8') as save_f:
            for annotation in annotations:
                category = annotation['category']

                #实例分割代码
                segmentation = annotation['seg']
                line = f"{category}"
                tem = ""
                for s in segmentation:
                    tem = " ".join([f"{num:.6f}" for num in s])
                line = line + " " + tem + "\n"

                # x_center = annotation['x_center']
                # y_center = annotation['y_center']
                # box_width = annotation['width']
                # box_height = annotation['height']
                # line = f"{category} {x_center:.6f} {y_center:.6f} {box_width:.6f} {box_height:.6f}\n"
                save_f.write(line)

    print("转换完成,保存到:", save_dir)
else:
    print("文件不存在:", file_path)

执行完之后,得到:labels【保存目录自己改,随你】
在这里插入图片描述

S4:(根据需要,看看是不是自己要再加类别啥的)将这些个TXT文件转换成labelme对应的JSON文件【不需要改动的话,就可以直接拿去训练YOLOv8-seg模型了,训练教程参考我的上一篇文章,链接在本文开头】
【txt2json.py】

import os
import cv2
import json
import glob
import numpy as np

def convert_txt_to_labelme_json(txt_path, image_path, output_dir, image_fmt='.jpg'):
    # txt 转labelme json
    txts = glob.glob(os.path.join(txt_path, "*.txt"))
    for txt in txts:
        labelme_json = {
            'version': '4.5.7',
            'flags': {},
            'shapes': [],
            'imagePath': None,
            'imageData': None,
            'imageHeight': None,
            'imageWidth': None,
        }
        txt_name = os.path.basename(txt)
        image_name = txt_name.split(".")[0] + image_fmt
        labelme_json['imagePath'] = image_name
        image_name = os.path.join(image_path, image_name)
        if not os.path.exists(image_name):
            raise Exception('txt 文件={},找不到对应的图像={}'.format(txt, image_name))
        image = cv2.imdecode(np.fromfile(image_name, dtype=np.uint8), cv2.IMREAD_COLOR)
        h, w = image.shape[:2]
        labelme_json['imageHeight'] = h
        labelme_json['imageWidth'] = w
        with open(txt, 'r') as t:
            lines = t.readlines()
            for line in lines:
                content = line.split(' ')
                label = content[0]
                shape = {
                    'label': str(label),
                    'flags': {},
                    'points': []
                }
                for i in range(len(content)):
                    if 2 * i + 1 >= len(content):
                        break
                    else:
                        try:
                            shape['points'].append([float(content[2 * i + 1]), float(content[2 * i + 2])])
                        except Exception as e:
                            print(e)

                labelme_json['shapes'].append(shape)
            json_name = txt_name.split('.')[0] + '.json'
            json_name_path = os.path.join(output_dir, json_name)
            fd = open(json_name_path, 'w')
            json.dump(labelme_json, fd, indent=4)
            fd.close()
            print("save json={}".format(json_name_path))


if __name__=="__main__":
    in_imgs_dir = 'C:\\Users\\ycc\\Desktop\\cityscapes2coco-master\\cityscape\\leftImg8bit\\train_dev\\aachen'
    in_label_txt_dir = 'C:\\Users\\ycc\\Desktop\\cityscapes2coco-master\\cityscape\\yolo\\labels'
    out_labelme_json_dir = 'C:\\Users\\ycc\\Desktop\\cityscapes2coco-master\\cityscape\\yolo\\json'

    if not os.path.exists(out_labelme_json_dir):
        os.mkdir(out_labelme_json_dir)
    convert_txt_to_labelme_json(in_label_txt_dir,in_imgs_dir,out_labelme_json_dir,image_fmt='.png')


执行完之后得到JSON:
在这里插入图片描述
OK,至此,再将得到的JSON文件和image原图片文件放到一个文件夹下(对应的名字都一样,一份对应一个png一个json)如下:
在这里插入图片描述
然后直接labelme打开这个目录就好了,开始编辑自己的数据集吧,we go…
在这里插入图片描述
在这里插入图片描述

提一嘴,标签的名字整成数字了,不过能区分不同类别,问题是出在TXT转JSON这一步上,后边再更新,wait for me!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/740154.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何使用mapXplore将SQLMap数据转储到关系型数据库中

关于mapXplore mapXplore是一款功能强大的SQLMap数据转储与管理工具,该工具基于模块化的理念开发,可以帮助广大研究人员将SQLMap数据提取出来,并转储到类似PostgreSQL或SQLite等关系型数据库中。 功能介绍 当前版本的mapXplore支持下列功能…

贪心算法系列(二)|摆动序列最长递增子序列|买卖股票的最佳时机|买卖股票的最佳时机II

摆动序列 分析 最经典的做法还是使用两个dp表的动态规划(代码放下面)这里采用贪心算法,直接上结论整个序列中,波峰波谷起点和重点的个数就是整个最长的摆动序列长度 那么如何判断波峰/波谷呢?也很简单left nums[i] - nums[i-1]right nu…

JBPM4 JBDL Demo

JBPM4 JBDL Demo 工作流样例,工作流程定义文件

面向对象六大设计原则--依赖倒置

目录 六大原则 定义 概念 Java语言中的表现 优点 在设计模式中体现 工厂方法模式 观察者模式 状态模式 示例 手机模块设计 五个示例 一、读取数据 二、发送消息 三、支付方式 四、日志记录 五、数据持久化 使用汽车驾驶进行说明 依赖的三种写法 1.构造函数…

基于FPGA的温湿度检测

初始化部分就不过多赘述,我会给出对应的文件,我只说明这部分里面涉及到使用的代码部分 1、数据的读取和校验 数据的读取和检验代码如下 always (posedge clk_us)if (data_temp[7:0] data_temp[39:32] data_temp[31:24] data_temp[23:16] data_te…

SQLite3的使用

14_SQLite3 SQLite3是一个嵌入式数据库系统,它的数据库就是一个文件。SQLite3不需要一个单独的服务器进程或操作系统,不需要配置,这意味着不需要安装或管理,所有的维护都来自于SQLite3软件本身。 安装步骤 在Linux上安装SQLite…

AI数据分析:集中度分析和离散度分析

在deepseek中输入提示词: 你是一个Python编程专家,要完成一个Python脚本编写的任务,具体步骤如下: 读取Excel表格:"F:\AI自媒体内容\AI行业数据分析\toolify月榜\toolify2023年-2024年月排行榜汇总数据.xlsx&qu…

【PADS】软件下载安装、PADS—Altium Designer文件转换

PADS软件学习——软件下载、安装、解析 一、软件下载 PADS:链接:https://pan.baidu.com/s/1J9z-Rl9sLjfnZYwlE3ZLPQ?pwdGLNG 提取码:GLNG解析软件:http://mentor.mr-wu.cn/PADS教学视频:https://www.bilibili.com/v…

“硝烟下的量子”:以色列为何坚持让量子计算中心落地?

自2023年10月7日新一轮巴以冲突爆发以来,支持巴勒斯坦伊斯兰抵抗运动(哈马斯)的黎巴嫩真主党不时自黎巴嫩南部向以色列北部发动袭击,以军则用空袭和炮击黎南部目标进行报复,双方在以黎边境的冲突持续至今。 冲突走向扑…

Django教程(001):安装及快速上手

1.1 Django安装 pip install django安装之后 c:\python39-python.exe-Scripts-pip.exe-django-admin.exe【安装django之后,工具,创建django项目】-Lib-内置模块-site-packages-flask-django(安装django之后,【django框架源码】)如下图&…

springboot 网上商城系统-计算机毕业设计源码08789

摘 要 随着互联网趋势的到来,各行各业都在考虑利用互联网将自己推广出去,最好方式就是建立自己的互联网系统,并对其进行维护和管理。在现实运用中,应用软件的工作规则和开发步骤,采用Java技术建设网上商城系统。 本设…

HTTPS 代理的优点和缺点是什么?

HTTPS(超文本安全传输协议)作为一种基于HTTP加上SSL安全层的网络通信协议,已经成为互联网上广泛使用的IP协议之一。它在保证信息安全和隐私方面具有很多优势,但也存在一些缺点。接下来,我们就来探究一下HTTPS协议的优缺…

导致代理IP延迟高的原因

很多用户在使用代理IP进行网络访问时,可能会遇到代理IP超时的情况,也就是代理IP的延迟过高。代理IP延迟过高会影响用户的网络体验和数据获取效率。因此,了解代理IP延迟过高的原因很重要。以下是导致代理IP延迟过高的一些常见原因:…

相位和展开相位

相位 (Phase) 相位是一个周期信号在一个周期内的位置,通常以角度(度或弧度)表示。在许多应用中,相位被限制在一个周期内。例如,相位通常被限定在 −180∘到 180∘ 或 0∘ 到 360∘ 之间。 示例 −90∘ 表示信号在周…

fvcore库的一些功能和使用

目录 一、安装fvcore库 二、使用 fvcore是Facebook开源的一个轻量级的核心库,它提供了各种计算机视觉框架中常见且基本的功能。其中就包括了统计模型的参数以及FLOPs等。 项目地址:fvcore 一、安装fvcore库 pip install fvcore 二、使用 1、计算模…

【实物资料包】基于STM32智能台灯设计

【实物资料包】基于STM32智能台灯设计 需要资料的请在文章结尾获取哦~~~~(如有问题私信我即可) 1.介绍 1 添加wifi模块模块,可通过wifi模块APP或者手动按钮切换自动/手动模式 2 自动模式下,台灯可以感应是否有人落座&#xff0…

干货 | 准备换ERP系统?来看看这篇文章!

当前客户的痛点 在当今竞争激烈的市场环境中,企业面临着诸多挑战和痛点,尤其是在管理和运营方面。让我们以一家中小型制造业企业为例,探讨他们所面临的主要痛点: 分散的数据管理:企业各部门之间信息孤岛严重&#xff…

Ci2451和Ci2454:2.4GHz无线MCU的芯片对比数据资料分析

一、2.4GHz无线MCU芯片的背景介绍 1、开头我们先聊聊,关于南京中科微2.4GHz无线MCU芯片(Ci2451、Ci2454、CSM2433)是建立在现有的2.4GHz射频芯片基础上面,它的内部是集成了8位RISC内核,且集成丰富的MCU资源、更小的尺寸可以来满足…

iPhone卡在恢复模式无法退出时,有那些退出恢复模式方法?

iPhone用户有时会遇到需要将手机进入恢复模式的情况。恢复模式可以帮助解决一些软件问题,但如果iPhone卡在恢复模式,不知道如何退出就会非常麻烦。小编将介绍几种iPhone退出恢复模式的方法。 一、苹果手机的恢复模式是什么意思 iPhone的恢复模式是针对i…

React的生命周期函数详解

import React,{Component} from "react";import SonApp from ./sonAppclass App extends Component{state{hobby:爱吃很多好吃的}// 是否要更新数据,这里返回true才会更新数据shouldComponentUpdate(nextProps,nextState){console.log("app.js第一步…