如何从 COCO 数据集创建蒙版图像?

How to create mask images from COCO dataset?

所以我一直在使用这个代码,。我正在尝试从 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)

但我得到的是这样的东西

但我想要的是这样的

我怎样才能得到每个图像的原始蒙版?

不熟悉 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 

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

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

plt.imshow(mask)

我来晚了,但如果这可以帮助别人。 我不知道您的代码是否适用于您的应用程序,但是,如果您希望蒙版的每个像素都具有注释类别 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。
请注意,这里的披萨在其多边形的边缘与 table 重叠。如果我们添加掩码,重叠将被赋予一个 id,该 id 对应于 classes 的比萨饼和 table 的总和。但是,使用 max,只保留 class 之一。在这种情况下,由于 class table 的 ID 大于 class 比萨饼的 ID,重叠会影响 class table 即使比萨饼上面是直观的。不过,我不确定这是否可以轻松解决。

答案中没有完整的代码,所以我 post 在下面。

请先安装pycocotools

pip install pycocotools

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

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)

只需添加答案的变体,如果您想获得所有注释的二进制掩码,可以将其创建为:

#Construct the binary mask
mask = coco.annToMask(anns[0])>0
for i in range(len(anns)):
     mask += coco.annToMask(anns[i])>0

plt.imshow(mask,cmap='gray')