当前位置: 首页 > article >正文

二值mask转polygon/RLE (coco segment格式)

coco数据集annotation的segmentation并不是二值mask,而是polygon格式,
看一个annotation.

{
	"segmentation": [[510.66,423.01,511.72,420.03,510.45......]], #两两组成(x,y)坐标,polygon格式
	"area": 702.1057499999998, #面积
	"iscrowd": 0,  #是不是一群物体,为0是seg是polygon格式,否则是RLE格式
	"image_id": 289343,  #对应的image id
	"bbox": [473.07,395.93,38.65,28.67], #(x,y,w,h)
	"category_id": 18,  #分类label
	"id": 1768  #当前annotation的id,每一个图像有不止一个对象,所以要对每一个对象编号(每个对象的ID是唯一的)
},

segmentation其实是一个二值mask的轮廓点,
如果想把二值mask转成这种格式,需要提取轮廓。

网上找来一张二值mask的图片

请添加图片描述

提取它的轮廓

mask_img = cv2.imread("mask.png",cv2.IMREAD_GRAYSCALE)
contours, _ = cv2.findContours(mask_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
polygons = []
for object in contours:
    coords = []

    for point in object:
        coords.append(int(point[0][0]))
        coords.append(int(point[0][1]))

    polygons.append(coords)
    print(polygons)
    #[[131, 48, 130, 49, 129, 50, 128, 51, ...]]

这个polygon能不能用呢?是不是和coco的annotation格式一样?
下面来验证一下。
引入python自带的coco库,要用到里面的annToMask函数,把polygon转为mask,
然后imshow出来看看是不是和原图一样。

先看一下annToMask函数,它需要先把polygon格式转为RLE格式。

    def annToMask(self, ann):
        """
        Convert annotation which can be polygons, uncompressed RLE, or RLE to binary mask.
        :return: binary mask (numpy 2D array)
        """
        rle = self.annToRLE(ann)
        m = maskUtils.decode(rle)
        return m
        
    def annToRLE(self, ann):
        """
        Convert annotation which can be polygons, uncompressed RLE to RLE.
        :return: binary mask (numpy 2D array)
        """
        t = self.imgs[ann['image_id']]
        h, w = t['height'], t['width']
        segm = ann['segmentation']
        if type(segm) == list:
            # polygon -- a single object might consist of multiple parts
            # we merge all parts into one mask rle code
            rles = maskUtils.frPyObjects(segm, h, w)
            rle = maskUtils.merge(rles)
        elif type(segm['counts']) == list:
            # uncompressed RLE
            rle = maskUtils.frPyObjects(segm, h, w)
        else:
            # rle
            rle = ann['segmentation']
        return rle

转成RLE的过程中需要用到annotation里的image_id, segmentation.
而现在我们只有一个segmentation, 并没有image_id,
而image_id只是用来得到图片的w, h,
所以引入coco的instance_val2017.json文件,随便找一个image_id用一下。

from pycocotools.coco import COCO
coco_api = COCO('coco/annotations/instances_val2017.json')
ann = dict()
ann['image_id'] = 37777
ann['segmentation'] = polygons
mask = coco_api.annToMask(ann)
mask = np.clip(mask*255,0,255)

说明找到的轮廓是可以用的(随便找的image_id导致h,w和原图不一致,不过不影响mask).
(在曲线的连续性上仔细看会有一些误差)。

请添加图片描述


http://www.kler.cn/a/5295.html

相关文章:

  • 在 Vue 3 集成 e签宝电子合同签署功能
  • 推动多语言语音科技迈向新高度:INTERSPEECH 2025 ML-SUPERB 2.0 挑战赛
  • arcgisPro加载CGCS2000天地图后,如何转成米单位
  • 平面坐标转大地坐标(arcgisPro中进行)
  • 数据库模型全解析:从文档存储到搜索引擎
  • 黄仁勋演讲总结(2种显卡,1个开源大模型,1个数据采集平台)
  • RSA解密-第十届Java研究生组E题
  • Leetcode: 236.二叉树的最近公共祖先
  • 医用超声检查设备
  • 无线耳机哪个品牌好?四大国内蓝牙耳机品牌排行
  • 软件工程导论(四)总体设计(临时)
  • 49天精通Java,第21天,Java内部类,看看文心一言、ChatGPT怎么说
  • MongoDB的优缺点以及springboot中的使用
  • TypeScript学习笔记一
  • 超级进化吧switch case in java
  • OSPF(开放式最短路径优先协议2)
  • 写毕业论文经验贴
  • 设计模式-设计原则
  • Markdown pandoc-crossref自定义图表前缀(解决figureTitle和tableTitle被XeLaTex忽略的问题 )
  • 期货黄金交易平台重要吗?有哪些显著的期货黄金交易平台优势?
  • 【Redis】十大数据类型(下篇)
  • 24、基于原型的切比雪夫低通滤波器设计理论(插入损耗法)
  • 谈谈C语言的面向对象
  • ChatGPT5.0会如何?
  • 2023年广东省网络安全竞赛——Windows 操作系统渗透解析(超级详细)
  • Spring Cloud Sentinel实战(三)- Sentinel流控规则