COCO_04 展示COCO格式数据集 目标框与分割mask

news2024/5/18 15:39:37

文章目录

  • 1 前言
  • 2 绘制GT
    • 2.1 绘制目标框与类别
    • 2.2 绘制分割mask
  • 3 Appendix
    • A. mask polygon格式转化为图片格式
  • 参考

1 前言

上篇文章介绍了如何制作COCO个数数据集的DatasetDataloader,并绘制了dataloader->batch的返回的信息,https://blog.csdn.net/qq_44776065/article/details/128698022,接下来我们直接根据标注文件来绘制标注信息,来更好的认识数据集以及其操作方法

2 绘制GT

指定标注文件以及数据集根路径之后,按照图片索引展示标注

创建COCO数据集对象

from pycocotools import mask as coco_mask
from pycocotools.coco import COCO

def get_COCO(dataset_root, anno_file):
    anno_path = os.path.join(dataset_root, anno_file)
    anno = COCO(anno_path)
    return anno
    pass
   
if __name__ == "__main__":
    dataset_root = r"D:\Learning\OCT\oct-dataset-master\dataset\dataset_stent_coco"
    anno_file = r"P13_1_IMG002_annotations.json"
    coco = get_COCO(dataset_root, anno_file)
    
    # show_bbox(coco, index=1, cat_id=2, dataset_root=dataset_root)
    show_seg(coco, index=1, cat_id=2, dataset_root=dataset_root, alpha=0.5)

    pass

2.1 绘制目标框与类别

在获取bbox信息之后,根据坐标绘制矩形框即可,一个图像的标注含有1到多个bbox,需要逐个绘制

绘制目标框使用PIL.ImageDraw,绘制目标框有两种方式ImageDraw.rectangle()ImageDraw.line

使用ImageDraw.rectangle()无法指定边界颜色来表示种类

使用ImageDraw.line()可以指定颜色来表示种类,更加灵活

Code:

  • anno:COCO标注对象
  • index:图片索引
  • cat_id:种类
  • dataset_root:数据集根路径
# 绘制图片中某类的bbox
def show_bbox(anno, index, cat_id, dataset_root):
    image_ids = anno.getImgIds()
    image_id = image_ids[index]
    
    # 加载图片
    image_filename = anno.loadImgs(image_id)[0]["file_name"]
    image_filepath = os.path.join(dataset_root, image_filename)
    img = Image.open(image_filepath).convert('RGB')

    # 加载标注
    ann_ids = anno.getAnnIds(imgIds=image_id, catIds=cat_id)
    annos = anno.loadAnns(ann_ids)

    # 获取类别
    cat = anno.loadCats(cat_id) 

    # 创建绘制对象
    draw = ImageDraw.Draw(img)

    # 绘制标签
    for ann in annos:
        x, y, w, h = ann["bbox"]
        x_min, y_min, x_max, y_max = x, y, int(x + w), int(y + h)

        # 1 绘制矩形 
        # draw.rectangle((x_min, y_min, x_max, y_max), width=1)   # 不用fill参数, 会填充区域

        # 2 绘制直线
        # 确定四个点
        left_top , left_bottom, right_top, right_bottom = (x, y), (x, y+h), (x+w, y), (x+w, y+h)
        draw.line([left_top, left_bottom, right_bottom, right_top, left_top], fill="red", width=2)
        draw.text((x_min, y_min), cat[0]["name"], fill="red")

    plt.imshow(img)    # 默认为RGB空间
    plt.show()
    ...

指定类别为1的效果:
在这里插入图片描述

2.2 绘制分割mask

与bbox一样,一个图片的标注含有多个mask,遍历每个mask进行绘制

绘制过程为:将mask前景转换为bool类型的矩阵,对图片含有目标前景的部分进行颜色赋值;本此使用的数据集均无重叠目标

透明mask的实现方法:img = img * (1 - alpha) + img_copy * alpha

根据种类cats定义颜色的RGB:color ={"1": (255, 255, 0), "2": (255, 0, 255)},可以根据自己的种类定义颜色

def show_seg(anno, index, cat_id, dataset_root, color ={"1": (255, 255, 0), "2": (255, 0, 255)}, alpha=0.5):
    image_ids = anno.getImgIds()
    image_id = image_ids[index]
    
    # 加载图片
    image_filename = anno.loadImgs(image_id)[0]["file_name"]
    image_path = os.path.join(dataset_root, image_filename)
    img = Image.open(image_path).convert('RGB')
    
    # 加载类别
    cats = anno.loadCats(cat_id)

    # 加载标注
    anno_ids = anno.getAnnIds(image_id, cat_id)
    anns = anno.loadAnns(anno_ids)
    
    # 处理mask, 保存为数组
    img_w, img_h = img.size   # 获取图片大小, w与h
    cats, masks = [], []    # 存储每个obj信息
    for ann in anns:
        cats.append(ann["category_id"])
        polygons = ann["segmentation"]
        # 转化为rle,再转化为mask, mask维度为3 [h, w, 1]
        rles = coco_mask.frPyObjects(pyobj=polygons, h=img_h, w=img_w)
        mask = coco_mask.decode(rles)
        # 降低维度, 转化为2值图像
        mask = np.squeeze(mask, axis=2)
        masks.append(mask)
        
    # 转化为numpy数组
    if masks:
        masks = np.stack(masks, axis=0)
    else:
        masks = np.zeros((0, img_h, img_w), dtype=np.uint8)   # uint8类型图像

    masks = np.where(masks > 0.5, True, False)
    
    # 不同颜色显示
    img = np.array(img)   # 一份拷贝
    img_to_draw = np.copy(img)

    # 按照obj个数绘制, 颜色数不好确定
    # colors = [(255, 255, 0), (0, 255, 255), (255, 176, 8), (123, 232, 78), (23, 234, 111), (132, 231, 232)]
    # for mask, color in zip(masks, colors):
    #     img_to_draw[mask] = color

    # 怎么与cats类别信息结合
    for mask, cat in zip(masks, cats):
        img_to_draw[mask] = color[str(cat)]

    img = img * (1 - alpha) + img_to_draw * alpha
    out = np.array(img, dtype=np.uint8)  # 需要转化为uint8进行保存

    # img_save = Image.fromarray(img)
    # img_save.save(f"./test_cat{cat_id}.png")

    plt.imshow(out)   # 展示彩色图像
    plt.show()

指定为2的效果

在这里插入图片描述


3 Appendix

A. mask polygon格式转化为图片格式

从标注中获取polygon数据,将其转化为rle格式,再将rle格式转化为mask,对前景mask进行转化:[h, w, c]->[h, w] c只有一个维度,最后合并为numpy.ndarray

cats, masks = [], []    # 存储每个obj信息
for ann in anns:
    cats.append(ann["category_id"])
    polygons = ann["segmentation"]
    # 转化为rle,再转化为mask, mask维度为3 [h, w, 1]
    rles = coco_mask.frPyObjects(pyobj=polygons, h=img_h, w=img_w)
    mask = coco_mask.decode(rles)
    # 降低维度, 转化为2值图像
    mask = np.squeeze(mask, axis=2)
    masks.append(mask)
    
# 转化为numpy数组
if masks:
    masks = np.stack(masks, axis=0)
else:
    masks = np.zeros((0, img_h, img_w), dtype=np.uint8) 

注意:对于mask处理常常将其转化为bool数组masks = np.where(masks > 0.5, True, False)


参考

COCO数据集介绍:https://blog.csdn.net/qq_37541097/article/details/113247318


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

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

相关文章

【打卡】医学搜索Query相关性判断学习赛

入坑传送门 赛事介绍 文本匹配拥有广泛的应用场景,可以用于去除重复问题和文本相似度中。在本次学习中我们将学习: 如何计算文本之间的统计距离如何训练词向量 & 无监督句子编码BERT模型搭建和训练 上述步骤都是一个NLP算法工程师必备的基础&…

【GD32F427开发板试用】02-ADC规则组连续采样

本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:Stark_GS ADC 简介及特点 器件中集成了一个 12 位 2.6 MSPS 多通道 ADC。 一共有19个多路复用通道:16个外部通道,1个…

office365删除错误发送的邮件

微软喜欢变,office365删个邮件真是不容易。 --管理员登录 Connect-IPPSSession -UserPrincipalName adminmydomain.onmicrosoft.com --创建一个 "deleteemail"的搜索项目,项目名可以任意起,这个名称后面在office365安全合规门户里…

libcurl简介及其编程应用

本文为学习笔记,整合课程内容以及下列文章: 其中,libcurl函数库常用字段解读部分: 参考博文:原文地址 作者:冬冬他哥哥 目录 libcurl简介 libcurl的使用 学会开源包使用的一般步骤 包的解读 重点是看…

Spark 核心编程

文章目录Spark 核心编程一、RDD1、分布式计算模拟(1) 搭建基础的架子(2) 客户端向服务器发送计算任务Spark 核心编程 Spark 计算框架为了能够进行高并发和高吞吐的数据处理,封装了三大数据结构,用于处理不同的应用场景。三大数据结构分别是:…

【数据结构与算法理论知识点】1.1基本概念

1.1基本概念 为什么要学习数据结构与算法? AlgorithmsData StructuresPrograms---- Niklaus Wirth ( Pascal程序设计语言之父、结构化程序设计首创者、图灵奖获得者) 计算机程序:使用计算机求解问题算法是求解问题的步骤的描述:从蛮力到策…

套接字编程(二)UDP服务端与客户端的通信模拟实现

目录 一、前言 二、UDP客户端流程信息 1、创建套接字 2、为套接字绑定地址信息(不推荐) 3、发送数据(将数据放入发送缓冲区中) 4、接收数据(从socket结构体接收缓冲区中取出数据) 5、关闭套接字 三…

机器学习基本概念及问题梳理

前言:整理西瓜书第一、二章中的基本概念 待办:第二章评估方法、性能度量及后续内容未整理 下图梳理机器学习中部分概念 模型评估与选择相关知识点: 错误率(error rate, E):如果在m个样本中有a个样本分类…

WordPress安全指南:19个步骤让您的WordPress安全防线坚如磐石

谈到WordPress安全性,您可以采取很多措施来锁定您的网站,以防止黑客和漏洞影响您的电子商务网站或博客。您最不想发生的事情是一天早上醒来发现您的网站一团糟。因此,今天我们将分享许多技巧、策略和技术,您可以使用这些技巧、策略…

WEBSHELL管理工具流量特征——基础篇

前言 前一阵子帮别人做取证题目,有很多关于WEBSHELL的流量要分析,想起来还有没好好分析过于是准备写篇文章总结一下帮助大家能够快速的辨别WEBSHELL流量,下面我们展开文章来讲。 中国菜刀 这个应该是大家最熟悉的WEBSHELL管理工具&#xf…

NeuRay学习笔记

Neural Rays for Occlusion-aware Image-based Rendering 主页:https://liuyuan-pal.github.io/NeuRay/ 论文:https://arxiv.org/abs/2107.13421 Code:https://github.com/liuyuan-pal/NeuRay 效果: desktop摘要 We present a ne…

一文读懂 UniProt 数据库(2023 最新版)

一、UniProt 数据库介绍 Uniprot (Universal Protein )是包含蛋白质序列,功能信息,研究论文索引的蛋白质数据库,整合了包括EBI( European Bioinformatics Institute),SIB&#xff0…

【面试题】前端最新面试题-浏览器 dom、bom篇

原文见:语雀(https://www.yuque.com/deepstates/interview/fsitlt) ● BOM ● window对象 ○ frames ■ iframe ■ 跨窗口通信 ■ 同源策略/跨域 ○ navigator ● DOM ○ DOM结构 ○ DOM操作 ○ DOM事件 ■ 表单事件 ● 浏览器渲染 ○ 进程、…

Vue组件化编程的组件通信

对于组件化编程,组件之间的通信技术无疑是非常重要的内容,需要将细节牢牢把握。 组件通信,就是子组件放置在父组件内之后,父组件如何向子组件传递参数以及子组件如何与外部组件进行互动。 这部分的知识很重要,需要展开…

基于Ubuntu20.04搭建OpenHarmony v3.0.6的qemu仿真环境

基于Ubuntu20.04搭建OpenHarmony v3.0.6的qemu仿真环境0. 前言1. 安装Ubuntu1.1 更换华为源1.2 安装必要工具2. 下载代码2.1 解压与目录设置3. 配置环境3.1 安装库和工具3.2 设置python版本3.3 安装编译工具hb3.4 切换dash为bash4. 编译4.1 hb构建4.2 启动qemu5. 第二种环境配置…

Java之日期与时间、JDK8新增日期类、包装类、正则表达式、Arrays类、常见算法和Lambda表达式

目录日期与时间DateSimpleDateFormatCalendar概述JDK8新增日期类概述、LocalTime /LocalDate / LocalDateTimeInstantDateTimeFormatterDuration/PeriodchronoUnit包装类正则表达式Arrays类Arrays类概述,常用功能演示Arrays类对于Comparator比较器的支持常见算法选择…

[论文翻译] GIKT: A Graph-based Interaction Model forKnowledge Tracing

摘要随着在线教育的快速发展,知识追踪(KT)已成为追踪学生知识状态并预测他们在新问题上的表现的基本问题。在线教育系统中的问题通常很多,并且总是与更少的技能相关联。然而,以往的文献未能将问题信息与高阶问题-技能相…

计网必会:电路交换和分组交换

电路交换和分组交换的概念和区别,为什么分组交换更有效? 电路交换:由于电路交换在通信之前要在通信双方之间建立一条被双方独占的物理通路(由通信双方之间的交换设备和链路逐段连接而成) 特点是源和目标点建立起名副其…

C语言中的void*是什么?

目录1.void *是什么2.void*的解引用3.void*类型的应用场景1.void *是什么 我们之前学过许多类型的指针变量,如整形指针,字符指针,甚至数组指针,函数指针等。 int a 10; int *pa &a;//整形指针pa接受一个整形变量a的地址但…

阻塞队列-BlockingQueue

一、BlockingQueue介绍BlockingQueue 继承了 Queue 接口,是队列的一种。Queue 和 BlockingQueue 都是在 Java 5 中加入的。阻塞队列(BlockingQueue)是一个在队列基础上又支持了两个附加操作的队列,常用解耦。两个附加操作:支持阻塞…