使用coco数据集进行语义分割(1):数据预处理,制作ground truth

如何coco数据集进行目标检测的介绍已经有很多了,但是关于语义分割几乎没有。本文旨在说明如何处理 stuff_train2017.json    stuff_val2017.json    panoptic_train2017.json    panoptic_val2017.json,将上面那些json中的dict转化为图片的label mask,也就是制作图片像素的标签的ground truth。

首先下载图片和annotation文件(也就是json文件)

2017 Train Images和2017 Val Images解压得到这两个文件夹,里面放着的是所有图片。

annotation下载下来有4个json文件

以及两个压缩包

这两个压缩包里面是panoptic segmentation的mask,用于制作ground truth。

首先说明一下那四个json文件的含义,stuff是语义分割,panoptic是全景分割。二者的区别在与

语义分割只区别种类,全景分割还区分个体。上图中,中间的语义分割将所有的人类视作同一个种类看待,而右边的全景分割还将每一个个体区分出来。

做语义分割,可以使用stuff_train2017.json生成ground truth。但是即便是只做语义分割,不做全景分割,在只看语义分割的情况下,stuff的划分精度不如panoptic,因此建立即使是做语义分割也用panoptic_train2017.json。本文中将两种json都进行说明。

stuff_train2017.json

下面这段代码是处理stuff_train2017.json生成ground truth

from pycocotools.coco import COCO
import os
from PIL import Image
import numpy as np
from matplotlib import pyplot as pltdef convert_coco2mask_show(image_id):print(image_id)img = coco.imgs[image_id]image = np.array(Image.open(os.path.join(img_dir, img['file_name'])))plt.imshow(image, interpolation='nearest')# cat_ids = coco.getCatIds()cat_ids = list(range(183))anns_ids = coco.getAnnIds(imgIds=img['id'], catIds=cat_ids, iscrowd=None)anns = coco.loadAnns(anns_ids)mask = np.zeros((image.shape[0], image.shape[1]))for i in range(len(anns)):tmp = coco.annToMask(anns[i]) * anns[i]["category_id"]mask += tmpprint(np.max(mask), np.min(mask))# 绘制二维数组对应的颜色图plt.figure(figsize=(8, 6))plt.imshow(mask, cmap='viridis', vmin=0, vmax=182)plt.colorbar(ticks=np.linspace(0, 182, 6), label='Colors')  # 添加颜色条# plt.savefig(save_dir + str(image_id) + ".jpg")plt.show()if __name__ == '__main__':Dataset_dir = "/home/xxxx/Downloads/coco2017/"coco = COCO("/home/xxxx/Downloads/coco2017/annotations/stuff_train2017.json")# createIndex# coco = COCO("/home/robotics/Downloads/coco2017/annotations/annotations/panoptic_val2017.json")img_dir = os.path.join(Dataset_dir, 'train2017')save_dir = os.path.join(Dataset_dir, "Mask/stuff mask/train")if not os.path.isdir(save_dir):os.makedirs(save_dir)image_id = 9convert_coco2mask_show(image_id)# for keyi, valuei in coco.imgs.items():#     image_id = valuei["id"]#     convert_coco2mask_show(image_id)

解释一下上面的代码。

coco = COCO("/home/xxxx/Downloads/coco2017/annotations/stuff_train2017.json")

从coco的官方库中导入工具,读取json。会得到这样的字典结构

在 coco.imgs ,找到 "id" 对应的value,这个就是每个图片唯一的编号,根据这个编号,到 coco.anns 中去索引 segmentation

注意 coco.imgs 的 id 对应的是 anns 中的 image_id,这个也是 train2017 文件夹中图片的文件名。

# cat_ids = coco.getCatIds()
cat_ids = list(range(183))

网上的绝大多数教程都写的是上面我注释的那行代码,那行代码会得到91个类,那个只能用于图像检测,但对于图像分割任务,包括的种类是182个和一个未归类的0类一共183个类。

tmp = coco.annToMask(anns[i]) * anns[i]["category_id"]

上面那行代码就是提取每一个类所对应的id,将所有的类都加进一个二维数组,就制作完成了ground truth。

panoptic_train2017.json

上面完成了通过stuff的json文件自作ground truth,那么用panoptic的json文件制作ground truth,是不是只要把

coco = COCO("/home/xxxx/Downloads/coco2017/annotations/stuff_train2017.json")

换为

coco = COCO("/home/xxxx/Downloads/coco2017/annotations/annotations/panoptic_val2017.json")

就行了呢?

答案是不行!会报错

Traceback (most recent call last):File "/home/xxxx/.local/lib/python3.8/site-packages/IPython/core/interactiveshell.py", line 3508, in run_codeexec(code_obj, self.user_global_ns, self.user_ns)File "<ipython-input-4-66f5c6e7dbe4>", line 1, in <module>coco = COCO("/home/xxxx/Downloads/coco2017/annotations/panoptic_val2017.json")File "/home/robotics/.local/lib/python3.8/site-packages/pycocotools/coco.py", line 86, in __init__self.createIndex()File "/home/xxxx/.local/lib/python3.8/site-packages/pycocotools/coco.py", line 96, in createIndexanns[ann['id']] = ann
KeyError: 'id'

用官方的库读官方的json还报错,真是巨坑!关键还没有官方的文档教你怎么用,只能一点点摸索,非常浪费时间精力。

制作panoptic的ground truth,用到了Meta公司的detectron2这个库

# Copyright (c) Facebook, Inc. and its affiliates.
import copy
import json
import osfrom detectron2.data import MetadataCatalog
from detectron2.utils.file_io import PathManagerdef load_coco_panoptic_json(json_file, image_dir, gt_dir, meta):"""Args:image_dir (str): path to the raw dataset. e.g., "~/coco/train2017".gt_dir (str): path to the raw annotations. e.g., "~/coco/panoptic_train2017".json_file (str): path to the json file. e.g., "~/coco/annotations/panoptic_train2017.json".Returns:list[dict]: a list of dicts in Detectron2 standard format. (See`Using Custom Datasets </tutorials/datasets.html>`_ )"""def _convert_category_id(segment_info, meta):if segment_info["category_id"] in meta["thing_dataset_id_to_contiguous_id"]:segment_info["category_id"] = meta["thing_dataset_id_to_contiguous_id"][segment_info["category_id"]]segment_info["isthing"] = Trueelse:segment_info["category_id"] = meta["stuff_dataset_id_to_contiguous_id"][segment_info["category_id"]]segment_info["isthing"] = Falsereturn segment_infowith PathManager.open(json_file) as f:json_info = json.load(f)ret = []for ann in json_info["annotations"]:image_id = int(ann["image_id"])# TODO: currently we assume image and label has the same filename but# different extension, and images have extension ".jpg" for COCO. Need# to make image extension a user-provided argument if we extend this# function to support other COCO-like datasets.image_file = os.path.join(image_dir, os.path.splitext(ann["file_name"])[0] + ".jpg")label_file = os.path.join(gt_dir, ann["file_name"])segments_info = [_convert_category_id(x, meta) for x in ann["segments_info"]]ret.append({"file_name": image_file,"image_id": image_id,"pan_seg_file_name": label_file,"segments_info": segments_info,})assert len(ret), f"No images found in {image_dir}!"assert PathManager.isfile(ret[0]["file_name"]), ret[0]["file_name"]assert PathManager.isfile(ret[0]["pan_seg_file_name"]), ret[0]["pan_seg_file_name"]return retif __name__ == "__main__":from detectron2.utils.logger import setup_loggerfrom detectron2.utils.visualizer import Visualizerimport detectron2.data.datasets  # noqa # add pre-defined metadatafrom PIL import Imageimport matplotlib.pyplot as pltimport numpy as nplogger = setup_logger(name=__name__)meta = MetadataCatalog.get("coco_2017_train_panoptic")dicts = load_coco_panoptic_json("/home/xxxx/Downloads/coco2017/annotations/panoptic_train2017.json","/home/xxxx/Downloads/coco2017/train2017","/home/xxxx/Downloads/coco2017/Mask/panoptic mask/panoptic_train2017", meta.as_dict())logger.info("Done loading {} samples.".format(len(dicts)))dirname = "coco-data-vis"os.makedirs(dirname, exist_ok=True)new_dic = {}num_imgs_to_vis = 100for i, d in enumerate(dicts):img = np.array(Image.open(d["file_name"]))visualizer = Visualizer(img, metadata=meta)pan_seg, segments_info = visualizer.draw_dataset_dict(d)seg_cat = {0: 0}for segi in segments_info:seg_cat[segi["id"]] = segi["category_id"]mapped_seg = np.vectorize(seg_cat.get)(pan_seg)# 保存数组为txt文件save_name = "/home/xxxx/Downloads/coco2017/Mask/panoptic label/train/" + str(d["image_id"]) + ".txt"np.savetxt(save_name, mapped_seg, fmt='%i')new_dic[d["image_id"]] = {"image_name": d["file_name"], "label_name": save_name}# # 将numpy数组转换为PIL Image对象# img1 = Image.fromarray(np.uint8(mapped_seg))# # 缩放图片# img_resized = img1.resize((224, 224))# # 将PIL Image对象转换回numpy数组# mapped_seg_resized = np.array(img_resized)# # 创建一个新的图形# plt.figure(figsize=(6, 8))# # 使用imshow函数来显示数组,并使用cmap参数来指定颜色映射# plt.imshow(mapped_seg_resized, cmap='viridis')# # 显示图形# plt.show()# fpath = os.path.join(dirname, os.path.basename(d["file_name"]))# # vis.save(fpath)if i + 1 >= num_imgs_to_vis:# 将字典转换为json字符串json_data = json.dumps(new_dic)# 将json字符串写入文件with open('/home/xxxx/Downloads/coco2017/data_for_train.json', 'w') as f:f.write(json_data)break
dicts = load_coco_panoptic_json("/home/xxxx/Downloads/coco2017/annotations/panoptic_train2017.json","/home/xxxx/Downloads/coco2017/train2017","/home/xxxx/Downloads/coco2017/Mask/panoptic mask/panoptic_train2017", meta.as_dict())

load_coco_panoptic_json的第三个参数,就是下载panoptic的annotations时,里面包含的两个压缩包。

上面这段代码,还需要修改一下detectron2库内部的文件

pan_seg, segments_info = visualizer.draw_dataset_dict(d)

进入 draw_dataset_dict这个函数内部,将两个中间结果拿出来

603行和604行是我自己加的代码。

这两个中间结果拿出来后,pan_seg是图片每个像素所属的种类,但是这个种类不是coco分类的那183个类

pan_seg中的数,要映射到segments_info中的 category_id,这个才是coco数据集所规定的183个类 。下图节选了183个中的前10个展示

 

mapped_seg = np.vectorize(seg_cat.get)(pan_seg)

上面这行代码就是完成pan_seg中的数,映射到segments_info中的 category_id。不要用两层的for循环,太低效了,numpy中有函数可以完成数组的映射。

这样就得到了语义分割的ground truth,也就是每个像素所属的种类。

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

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

相关文章

Docker下安装MySQL

如果在Docker下直接拉取MySQL并运行镜像&#xff0c;由于没有指定字符编码集&#xff0c;可能会存在插入中文出现乱码的情况&#xff0c;并且当容器删除后&#xff0c;容器里面存在的数据会丢失&#xff0c;所以在运行容器时应该使用数据卷进行挂载&#xff0c;按照如下步骤操作…

大模型中幂律缩放法则和涌现能力

幂律缩放法则是一种用于描述两个变量之间关系的数学模型。 根据幂律缩放法则&#xff0c;当一个变量的值变化时&#xff0c;另一个变量的值以指数方式变化。具体而言&#xff0c;幂律缩放法则可以表示为Y a * X^b&#xff0c;其中Y表示一个变量的值&#xff0c;X表示另一个变…

网页中的json文档,怎么保存到本地

火狐浏览器操作方法 方法一 右键——>另存页面为 方法二 点击右边的三条横线——>另存页面为 谷歌浏览器操作方法 方法一 右键——>另存为 方法二

阵列信号处理---均匀线阵和均匀加权线阵

均匀线阵 均匀线性阵列(ULA&#xff1a;Uniform Linear Array)&#xff1a;有N个阵元位于z轴上且具有均匀间距d。 一般都把阵列的中心放在坐标系的原点。如下图 阵元的位置为 p z n ( n − N − 1 2 ) d &#xff0c; n 0 , 1 , … , N − 1 p_{z_n}\big(n-\frac{N-1}{2}\b…

LLM 开发模式 RAG,MRKL,Re-Act,Plan-Execute 模式对比

本心、输入输出、结果 文章目录 LLM 开发模式 RAG&#xff0c;MRKL&#xff0c;Re-Act&#xff0c;Plan-Execute 模式对比前言RAG、MRKL、Re-Act和Plan-Execute模式的一些对比花有重开日&#xff0c;人无再少年实践是检验真理的唯一标准 LLM 开发模式 RAG&#xff0c;MRKL&…

Wireshark抓包分析RTMP协议时,出现Unknown问题

进行rtmp推流时&#xff0c;使用wireshark抓包&#xff0c;发现部分包显示Unknown 解决方法&#xff1a; 编辑 -> 首选项 -> Protocols -> RTMPT&#xff0c;这里Maximum packet size默认是32768 将该值调大&#xff0c;比如调成1048576&#xff0c;即可解决该问题。…

pytorch 中的dim 的作用范围

1. 二维矩阵时 不同的运算&#xff0c; dim 的作用域都是一样的思想&#xff1b; 当数据是二维矩阵时&#xff0c; 可以按照下面的思想理解&#xff1a; 对于矩阵&#xff1a; dim0 按列操作&#xff08;沿列向下&#xff09;。 dim1 按行操作&#xff08;跨行&#xff09;。 …

Windows修改MAC地址的方法(以windows11为例)

我们在日常的工作中&#xff0c;如果mac地址被限制&#xff0c;就需要修改mac地址&#xff0c;本文总结一下修改windows的mac地址的方法。 方法一&#xff1a;网络适配器中配置 网络适配器中配置的方式适用于能够在网络适配器中找到物理地址(NetworkAddress)的情况。 1、打开…

腾讯云轻量服务器通过Docker搭建外网可访问连接的redis5.x集群

原创/朱季谦 最近买了一台4核16的腾讯云轻量应用服务器,花了我快四百的大洋&#xff0c;打算搭建一堆docker组件集群&#xff0c;最先开始是通过docker搭建redis集群&#xff0c;计划使用三个端口&#xff0c;分别是7001,7002,7003。 腾讯云服务器有防火墙限制&#xff0c;故…

使用trigger-forward跨流水线传递参数

参考文档&#xff1a;https://docs.gitlab.com/ee/ci/yaml/#triggerforward 今天给大家介绍一个gitlab CI/CD的关键字 - forward&#xff0c;该关键字是一个比较偏的功能&#xff0c;但同时也是一个很实用的功能&#xff0c;我们通过在gitlab的ci文件中使用forward关键字&#…

火星探索:技术挑战与前沿进展

火星探索:技术挑战与前沿进展 一、引言 火星,这颗红色的星球,长久以来一直吸引着人类的目光。随着科技的飞速发展,火星探索已经从纯粹的科幻梦想逐渐转变为现实的研究课题。然而,火星探索仍然面临着诸多技术挑战。本文将深入探讨火星探索的关键技术、现有技术瓶颈以及前沿…

从零构建属于自己的GPT系列1:数据预处理(文本数据预处理、文本数据tokenizer、逐行代码解读)

&#x1f6a9;&#x1f6a9;&#x1f6a9;Hugging Face 实战系列 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在PyCharm中进行 本篇文章配套的代码资源已经上传 从零构建属于自己的GPT系列1&#xff1a;文本数据预处理 从零构建属于自己的GPT系列2&#xff1a;语…

记一次若依二开的简单流程

记一次若依二开的简单流程 前言: 搞Java后端的应该都知道若依框架&#xff0c;是一个十分强大且功能齐全的开源的快速开发平台&#xff0c;且毫无保留给个人及企业免费使用。很多中小型公司会直接在该系统上进行二次开发使用。本文记录一次使用若依二开零编码的简单实现&#…

Python安装步骤介绍

本文将介绍Python安装的详细步骤如下&#xff1a; 下载 python安装 python配置环境变量&#xff08;安装时勾选配置环境变量的则无需此步骤&#xff09; 一、python下载 官网&#xff1a;Download Python | Python.org 根据电脑位数下载所需的版本 二、Python安装 1.打开安…

C++实现ATM取款机

C实现ATM取款机 代码&#xff1a;https://mbd.pub/o/bread/ZZeZk5Zp 1.任务描述 要求&#xff1a;设计一个程序&#xff0c;当输入给定的卡号和密码&#xff08;初始卡号和密码为123456) 时&#xff0c;系统 能登录 ATM 取款机系统&#xff0c;用户可以按照以下规则进行: 查询…

dynamic-datasource多数据源事务

Spring 事务管理分为编程式和声明式两种 编程式事务指的是通过编码方式实现事务&#xff1b;声明式事务基于 AOP&#xff0c;将具体的逻辑与事务处理解耦(编程式事务在这边不做过多陈述)。 声明式事务有两种方式&#xff0c;一种是在配置文件&#xff08;XML&#xff09;中做相…

JavaWeb 添加页面和用户图像展示

add.jsp&#xff08;需要登录之后才可以访问 &#xff09; -> 不是和login.jsp同级了那就 在images目录下加上默认图像 js目录下加入common.js javaWeb项目中&#xff0c;页面的路径 img的src form的action link的href script的src a的href推荐使用绝对路径 这个绝对路径…

网络和Linux网络_7(传输层)UDP和TCP协议(端口号+确认应答+超时重传+三次握手四次挥手)

目录 1. 重看端口号 1.1 端口号的概念 1.2 端口号的划分 2. 重看UDP协议 2.1 UDP协议格式 2.2 UDP的特点 3. 重看TCP协议 3.1 TCP协议格式 3.2 TCP的解包分用 3.3 TCP的可靠性及机制 3.3.1 确认应答ACK机制 3.3.2 超时重传机制 3.3.3 连接管理机制&#xff08;三次…

kgma转换flac格式、酷狗下载转换车载模式能听。

帮朋友下载几首歌到U盘里、发现kgma格式不能识别出来&#xff0c;这是酷狗加密过的格式&#xff0c;汽车不识别&#xff0c;需要转换成mp3或者flac格式&#xff0c;网上的一些辣鸡软件各种收费、限制、广告&#xff0c;后来发现一个宝藏网站&#xff0c;可以在线免费转换成flac…

【专题】【数列极限】

【整体思路】 【常用不等式】