如何从 COCO 数据集创建掩码图像?

Posted

技术标签:

【中文标题】如何从 COCO 数据集创建掩码图像?【英文标题】:How to create mask images from COCO dataset? 【发布时间】:2018-11-21 04:05:41 【问题描述】:

所以我一直在使用这个代码,。我正在尝试从 COCO 数据集生成图像的原始掩码。

dataDir='G:'
dataType='train2014'
annFile='/annotations/instances_.json'.format(dataDir,dataType)


coco=COCO(annFile)
annFile = '/annotations/person_keypoints_.json'.format(dataDir,dataType)
coco_kps=COCO(annFile)


catIds = coco.getCatIds(catNms=['person'])
imgIds = coco.getImgIds(catIds=catIds );
imgIds = coco.getImgIds(imgIds = imgIds[0])
img = coco.loadImgs(imgIds[np.random.randint(0,len(imgIds))])[0]
I = io.imread('G:/train2014/'+img['file_name'])

plt.imshow(I); plt.axis('off')
annIds = coco.getAnnIds(imgIds=img['id'], catIds=catIds, iscrowd=None)
anns = coco.loadAnns(annIds)
coco.showAnns(anns)

但我得到的是这样的东西

但我想要的是这样的

如何获取每个图像的原始蒙版?

【问题讨论】:

【参考方案1】:

不熟悉 COCO,但我看到有一个 annToMask 函数应该为每个注释生成一个二进制掩码。

所以在未经测试的伪代码中,假设不重叠的掩码,你应该有类似的东西:

annIds = coco.getAnnIds(imgIds=img['id'], catIds=catIds, iscrowd=None)

mask = np.zeros_like(img)
for i, ann in enumerate(annIds):
    mask += coco.annToMask(ann) * i 

【讨论】:

【参考方案2】:

按照 Filippo 先生的直觉,我能够编写正确的代码,看起来像这样。

mask = coco.annToMask(anns[0])
for i in range(len(anns)):
    mask += coco.annToMask(anns[i])

plt.imshow(mask)

【讨论】:

酷,很高兴它有帮助!请注意,这样您将生成二进制掩码。在这种情况下,使用二进制 OR 会比简单的加法更安全。将掩码乘以索引i 背后的想法是,这样每个标签都有不同的值,您可以使用图像中的颜色图(我猜是nipy_spectral)在您的 imshow 中将它们分开情节 这并不重要,但有什么理由让您每天切换一次已接受的答案? 不!我继续接受它,但它又被关闭了。 !!可能是由于我的手机浏览器中的错误...每当我打开此页面时,它都会切换!甚至我的回答也是! 哈哈 :-) 对不起!尝试重置缓存或类似的东西 假设 mask 是一个 numpy 数组,你不是加了两次 ann[0] 吗? ***.com/questions/15579260/…【参考方案3】:

我迟到了,但如果这可以帮助某人。 我不知道您的代码是否适用于您的应用程序,但是,如果您希望掩码的每个像素都具有注释类别 id 的值,那么您不能只添加掩码,因为有些会重叠。我为此使用了一个 numpy 最大值:

cat_ids = coco.getCatIds()
anns_ids = coco.getAnnIds(imgIds=img['id'], catIds=cat_ids, iscrowd=None)
anns = coco.loadAnns(anns_ids)
anns_img = np.zeros((img['height'],img['width']))
for ann in anns:
    anns_img = np.maximum(anns_img,coco.annToMask(ann)*ann['category_id'])

编辑: 这是我在 2017 数据集的图像 47112 上的代码示例: 灰色阴影的值是数据集描述中描述的类别的id。 请注意,这里的比萨饼在其多边形的边缘与桌子重叠。如果我们添加掩码,重叠部分将被赋予一个对应于比萨饼和餐桌类总和的 id。但是,使用 max,只保留一个类。在这种情况下,由于类表的 id 大于比萨类的 id,因此即使比萨在上面可见,重叠也会影响到类表。不过,我不确定这是否可以轻松解决。

【讨论】:

您是说您的代码将提供像原始问题的最后一张图片一样的输出? 有灰色阴影是的。我刚刚编辑了我的帖子以添加一个示例。 你说的问题不是很严重吗?例如,在一个人站在火车旁边的图像中,如果火车的 id 更高,它会覆盖这个人。因此,您的图像将只有一个类别(火车),这是不正确的基本事实。【参考方案4】:

完整的代码不在答案中,所以我把它贴在下面。

请先安装pycocotools

pip install pycocotools

导入所需的模块。我假设您使用的是 jupyter 笔记本。

from pycocotools.coco import COCO
import os
from PIL import Image
import numpy as np
from matplotlib import pyplot as plt
%matplotlib inline

加载 coco 数据集的注释。在这里,指定 74 图像。

coco = COCO('../datasets/coco/annotations/instances_train2017.json')
img_dir = '../datasets/coco/train2017'
image_id = 74

img = coco.imgs[image_id]
# loading annotations into memory...
# Done (t=12.70s)
# creating index...
# index created!

加载的img信息如下。

img
# 'license': 2,
#  'file_name': '000000000074.jpg',
#  'coco_url': # 'http://images.cocodataset.org/train2017/000000000074.jpg',
#  'height': 426,
#  'width': 640,
#  'date_captured': '2013-11-15 03:08:44',
#  'flickr_url': # 'http://farm5.staticflickr.com/4087/5078192399_aaefdb5074_z.jpg# ',
#  'id': 74

如下显示图像。

image = np.array(Image.open(os.path.join(img_dir, img['file_name'])))
plt.imshow(image, interpolation='nearest')
plt.show()

如果要查看叠加结果:

plt.imshow(image)
cat_ids = coco.getCatIds()
anns_ids = coco.getAnnIds(imgIds=img['id'], catIds=cat_ids, iscrowd=None)
anns = coco.loadAnns(anns_ids)
coco.showAnns(anns)

如 Farshid Rayhan 所说,如果您只想看面具,请执行以下操作:

mask = coco.annToMask(anns[0])
for i in range(len(anns)):
    mask += coco.annToMask(anns[i])

plt.imshow(mask)

【讨论】:

以上是关于如何从 COCO 数据集创建掩码图像?的主要内容,如果未能解决你的问题,请参考以下文章

如何注册要与detectron2 一起使用的数据集?我们有 COCO JSON 格式的图像及其注释

从COCO数据集和VOC数据集提取特定的类别

如何下载Coco Dataset的特定部分?

《南溪的目标检测学习笔记》——COCO数据集的学习笔记

yolov5训练coco数据集

COCO数据集介绍