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 sysif "/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 pycococreatortoolsROOT_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.0def image_trans():img_subfolders = os.listdir(IMAGE_DIR)image_count = 0for sub in img_subfolders:# sub_path = sub + '/' + subimage_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_scalenew_h = new_w / 2top = 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 += 1def data_loader():imgs = os.listdir(IMAGE_SAVE_DIR)masks_generator(imgs, ANNOTATION_SAVE_DIR)def masks_generator(imges, ann_path):global idxpic_count = 0for 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:continueelse:class_id = id // 1000if 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:continueinstance_mask = np.zeros((h, w, 3), dtype=np.uint8)mask = annotation == idinstance_mask[mask] = 255mask_name = image_name + '_' + instance_class + '_' + str(idx) + '.png'cv2.imwrite(os.path.join(ann_folder, mask_name), instance_mask)idx += 1pic_count += 1print(pic_count)def json_generate():car = 0pedestrian = 0truck = 0bus = 0rider = 0caravan = 0motorcycle = 0bicycle = 0files = os.listdir(IMAGE_SAVE_DIR)coco_output = {"info": INFO,"licenses": LICENSES,"categories": CATEGORIES,"images": [],"annotations": []}image_id = 1segmentation_id = 1# go through each imagefor 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")continueelse: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 += 1elif class_id == 2:pedestrian += 1elif class_id == 3:truck += 1elif class_id == 4:bus += 1elif class_id == 5:rider += 1elif class_id == 6:caravan += 1elif class_id == 7:motorcycle += 1elif class_id == 8:bicycle += 1else: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 + 1image_id = image_id + 1print(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 osdef 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']] = ifor 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_dictpath = '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 npdef convert_txt_to_labelme_json(txt_path, image_path, output_dir, image_fmt='.jpg'):# txt 转labelme jsontxts = 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_fmtlabelme_json['imagePath'] = image_nameimage_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'] = hlabelme_json['imageWidth'] = wwith 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):breakelse: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.mzph.cn/diannao/34353.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开启调试模式

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 run()方法虽然适用于启动本地的开发服务器,但是每次修改代码后都要手动重启它。这样并不够方便,如果启用了调试支持&#xff…

AIGC-商业设计大师班,商业设计全流程(22节课)

课程内容: 02.AIGC大师计划(百天磨炼,只为让你一次成为大师).mp4 03.这5个细心的翻译工具我想全部告诉你(感受不到的工具才是好工具),mp4 04.扎实的基础是成功的关键(汇聚精华指导新功能演示方法).mp4 05.AI绘画大师级十二体咒语书写(大师级起步).mp…

SaaS企业营销:海外小众独立站Homage如何实现客群破圈?

深度垂直的市场标签对小众出海品牌来说,既是挑战也是机遇。由于品牌若想取得长远发展,无法仅凭单一狭窄的市场空间来支撑其持续壮大。因此,在追求可持续发展的道路上,小众品牌面临着需要突破既有市场圈层的挑战。 在这一过程中&am…

基于Java考研助手网站设计和实现(源码+LW+调试文档+讲解等)

💗博主介绍:✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者,博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 🌟文末获取源码数据库🌟 感兴趣的可以先收藏起来,…

Calibre - 翻译电子书(Ebook Translator)

本文参考教程 :https://bookfere.com/post/1057.html 使用 Ebook Translator 插件,详见: 官网:https://translator.bookfere.comgithub :https://github.com/bookfere/Ebook-Translator-Calibre-Plugin 一、基本翻译 …

张量在人工智能中的解释?

张量在人工智能中的解释? 张量是一种多维数组,它可以看作是向量和矩阵的推广。在人工智能领域,张量被用作数据的基本表示形式,尤其在深度学习中扮演着核心角色。张量的多维性允许它们表示复杂的数据结构和关系,而其可…

期末成绩怎么快速发给家长

Hey各位老师们,今天来聊一个超级实用的话题:如何快速高效的向家长们传达学生的期末成绩。你可能会想,这不是很简单吗?直接班级群发个消息不就得了?但别忘了,保护学生隐私和自尊心也是很重要的哦&#xff01…

GB28181视频汇聚平台EasyCVR接入Ehome设备视频播放出现异常是什么原因?

多协议接入视频汇聚平台EasyCVR视频监控系统采用了开放式的架构,系统可兼容多协议接入,包括市场标准协议:国标GB/T 28181协议、GA/T 1400协议、JT808、RTMP、RTSP/Onvif协议;以及主流厂家私有协议及SDK,如:…

视频融合共享平台LntonCVS视频监控平台在农场果园等场景的使用方案

我国大江南北遍布着各类果园。传统的安全防范方式主要是建立围墙,但这种方式难以彻底阻挡不法分子的入侵和破坏。因此,需要一套先进、科学、实用且稳定的安全防范报警系统,以及时发现并处理潜在问题。 需求分析 由于果园地处偏远且缺乏有效防…

redis以后台的方式启动

文章目录 1、查看redis安装的目录2、Redis以后台的方式启动3、通过客户端连接redis4、连接后,测试与redis的连通性 1、查看redis安装的目录 [rootlocalhost ~]# cd /usr/local/redis/ [rootlocalhost redis]# ll 总用量 112 drwxr-xr-x. 2 root root 150 12月 6…

【从零开始认识AI】梯度下降法

目录 1. 原理介绍 2. 代码实现 1. 原理介绍 梯度下降法(Gradient Descent)是一种用于优化函数的迭代算法,广泛应用于机器学习和深度学习中,用来最小化一个目标函数。该目标函数通常代表模型误差或损失。 基本思想是从一个初始…

软件测试计划审核表、试运行审核、试运行申请表、开工申请表

1、系统测试计划审核表 2、系统试运行审核表 3、系统试运行申请表 4、开工申请表 5、开工令 6、项目经理授权书 软件全套资料获取:本文末个人名片直接获取或者进主页。 系统测试计划审核表 系统试运行审核表 系统试运行申请表 开工申请表 开工令 项目经理授权书

青否数字人实时直播带货手机版发布!

青否数字人6大核心 AIGC 技术,让新手小白也能轻松搞定数字人在全平台的稳定直播,并有效规避违规风险,赋能商家开播即赚钱! AI主播 只需要录制主播1分钟的绿幕视频,1秒钟就能克隆出一个数字人主播形象。S级真人深度学习…

快速鲁棒的 ICP (Fast and Robust Iterative Closest Point)

迭代最近点(Iterative Closet Point,ICP)算法及其变体是两个点集之间刚性配准的基本技术,在机器人技术和三维重建等领域有着广泛的应用。ICP的主要缺点是:收敛速度慢,以及对异常值、缺失数据和部分重叠的敏…

el-form-item的label设置两端对齐

<style scoped> ::v-deep .el-form-item__label {display: inline;text-align-last: justify; } </style>效果如图所示

数据分析必备:一步步教你如何用matplotlib做数据可视化(11)

1、Matplotlib 三维绘图 尽管Matplotlib最初设计时只考虑了二维绘图&#xff0c;但是在后来的版本中&#xff0c;Matplotlib的二维显示器上构建了一些三维绘图实用程序&#xff0c;以提供一组三维数据可视化工具。通过导入Matplotlib包中包含的mplot3d工具包&#xff0c;可以启…

双 μC 的 PWM 频率和分辨率

该方法是过滤 PWM 信号的 HF 分量&#xff0c;只留下与占空比成正比的 LF 或 DC 分量。然而&#xff0c;低通滤波器并不能完全滤除PWM频率&#xff0c;因此LF/DC信号一般会有一些纹波。 有两种方法可以降低 PWM DAC 的纹波。可以降低低通滤波器的截止频率&#xff0c;或者提高…

数据结构-顺序表的插入排序

顺序表的排序可以看作数组排序的拓展。基本逻辑和数组排序的逻辑大同小异。 由于顺序表中可以存放不同种的数据类型&#xff0c;进而和结构体排序又有相似之处。其中要注意的是&#xff08;->&#xff09;和&#xff08;.&#xff09;的区别。 -> 符号是针对指针进行的操…

「动态规划」如何求最长摆动子序列的长度?

376. 摆动序列https://leetcode.cn/problems/wiggle-subsequence/description/ 如果连续数字之间的差严格地在正数和负数之间交替&#xff0c;则数字序列称为摆动序列。第一个差&#xff08;如果存在的话&#xff09;可能是正数或负数。仅有一个元素或者含两个不等元素的序列也…