ultralytics实例分割mask读取

36 篇文章 10 订阅
8 篇文章 4 订阅

在前面学习YOLOv8的实例分割过程中,需要使用实例分割的数据集,其标签的标注格式如下:

实例分割勾勒轮廓

其中,第一个数字代表的是类别编号,后面的数据代表的是标注的坐标(转换到0-1之间)每两个为一个坐标,即 (x,y)

23 0.683625 0.829413 0.684172 0.767559 0.677578 0.71892 0.667703 0.67439 0.667703 0.656244 0.663312 0.624906 0.652891 0.600188 0.652328 0.583685 0.669344 0.551526 0.670453 0.525141 0.666063 0.497113 0.650687 0.451761 0.649594 0.448474 0.647391 0.427864 0.647938 0.423732 0.646844 0.399812 0.644656 0.394883 0.643547 0.388286 0.641906 0.351174 0.634219 0.28439 0.625437 0.25223 0.613375 0.255516 0.604031 0.237394 0.602938 0.234085 0.602391 0.217606 0.604031 0.2077 0.602938 0.198638 0.604594 0.190376 0.613922 0.159883 0.617203 0.140915 0.618859 0.140915 0.62325 0.154108 0.622703 0.160704 0.624344 0.165657 0.632031 0.161526 0.637516 0.145047 0.638609 0.14338 0.64575 0.147512 0.640266 0.172254 0.640266 0.181315 0.647391 0.192042 0.653984 0.189554 0.662766 0.182136 0.663312 0.188732 0.654531 0.203568 0.646844 0.218427 0.675391 0.300047 0.691844 0.370141 0.708313 0.404765 0.727531 0.421268 0.753875 0.465775 0.776922 0.502887 0.812047 0.530915 0.837297 0.591103 0.847172 0.630681 0.849359 0.640587 0.878453 0.669437 0.922359 0.690047 0.936625 0.697465 0.938281 0.753545 0.920719 0.748592 0.915219 0.737042 0.910828 0.714789 0.90425 0.696643 0.866375 0.668615 0.849906 0.655423 0.849359 0.732113 0.850469 0.763427 0.861984 0.805493 0.859797 0.816221 0.832906 0.815376 0.818625 0.816221 0.800516 0.818685 0.791734 0.821972 0.76375 0.716432 0.746734 0.694178 0.745094 0.691714 0.734656 0.798075 0.732469 0.833521 0.688562 0.836831 0.687453 0.838474 0.684172 0.838474
23 0.155094 0.952394 0.208703 0.924366 0.226187 0.894601 0.247172 0.868333 0.270469 0.912113 0.283297 0.917371 0.284453 0.917371 0.289125 0.896362 0.268141 0.845587 0.229687 0.836831 0.208703 0.859577 0.194719 0.877089 0.16675 0.887606 0.129453 0.898099 0.113141 0.917371 0.0944844 0.93662 0.0828281 0.962887 0.101484 0.966385 0.152766 0.954131

如何讲坐标画出轮廓呢,使用OpenCV中的cv.polylines方法

import cv2 as cv
import numpy as np
img=cv.imread("coco8-seg/images/train/000000000025.jpg")
w,h,c=img.shape
shape=np.array((w,h))
with open("coco8-seg/labels/train/000000000025.txt") as f:
    datas=f.read()
    datas=datas.split("\n")
    for data in datas:
        xys=data.split(" ")
        xys.pop(0)
        xys_new=[]
        i=0
        while(i<len(xys)-1):
            xys_new.append(float(xys[i])*h)
            xys_new.append(float(xys[i+1])*w)
            i=i+2
        xys_new=np.array(xys_new,np.int_)
        xys_new = xys_new.reshape((-1,1,2))
        cv.polylines(img,[xys_new],True,(0,0,0),thickness=5)
    cv.imshow("img",img)
    cv.waitKey(0)
    cv.destroyAllWindows()

画出的图像如下:

在这里插入图片描述

以上是我们自己勾勒出的实例分割轮廓,那么,在ultralytics中,对于这些轮廓是如何处理的呢?

我们发现,在训练器加载过程中,首先会根据我们指定的数据集路径来读取相应的标注文件,可以看到,在这个labels属性中,数据集中图像的名称,目标类别,标注框以及分割的标签都成功的读取了。

在这里插入图片描述

事实上,分割所标注的坐标映射到图像上是这样的:

在这里插入图片描述

我们根据先前实例分割输入的标注分析,其输入的为mask模式,即如下图所示,mask为(4,160,160)

在这里插入图片描述

轮廓提取生成mask(错误方法)

开始时,博主想要直接读取标注文件然后画图,但却由于没有搞清填充图像的方法,所以像将坐标转换为线条,再通过腐蚀、阈值轮廓提取等方式来生成轮廓坐标,最后再进行填充,代码与效果图如下:

import cv2 as cv
import numpy as np
img=cv.imread("coco8-seg/images/train/000000000025.jpg")
w,h,c=img.shape
shape=np.array((w,h))
gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
with open("coco8-seg/labels/train/000000000025.txt") as f:
    datas=f.read()
    datas=datas.split("\n")
    for data in datas:
        xys=data.split(" ")
        xys.pop(0)
        xys_new=[]
        i=0
        while(i<len(xys)-1):
            xys_new.append(float(xys[i])*h)
            xys_new.append(float(xys[i+1])*w)
            i=i+2
        xys_new=np.array(xys_new,np.int_)
        xys_new = xys_new.reshape((-1,1,2))
        cv.polylines(gray,[xys_new],True,(0,0,0),thickness=5)
        blur = cv.blur(gray,(7,7))
        ret, thresh = cv.threshold(gray, 0, 255, 0)
        thresh = cv.blur(thresh,(2,2))
        contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
        canvs=np.zeros_like(img)
        #cv.drawContours(canvs, contours, 0, (0, 255, 0), thickness=cv.FILLED)
        cv.drawContours(canvs, contours, 1, (0, 255, 0), thickness=cv.FILLED)
        cv.drawContours(canvs, contours, 2, (0, 255, 0), thickness=cv.FILLED)
        cv.drawContours(canvs, contours, 3, (0, 255, 0), thickness=cv.FILLED)
    cv.imshow("img1",gray)
    cv.imshow("img",canvs)
    cv.waitKey(0)
    cv.destroyAllWindows()

在这里插入图片描述
这里涉及到OpenCV中的轮廓寻找与绘制问题,contours为找到的轮廓坐标
在这里插入图片描述

但这种方法很明显是不行的,这个标注本不需要进行轮廓提取就可以直接使用,后来,通过观察轮廓坐标contours格式,我们也可以直接读取数据来进行mask转换。

直接利用坐标填充mask

通过分析,可以采用如下方式来利用坐标生成对应的mask,同时还可以将对应的类别给作为颜色区分

import cv2 as cv
import numpy as np
img=cv.imread("coco8-seg/images/train/000000000009.jpg")
w,h,c=img.shape
shape=np.array((w,h))
gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
points=[]
cls=[]
with open("coco8-seg/labels/train/000000000009.txt") as f:
    datas=f.read()
    datas=datas.split("\n")
    canvs=np.zeros_like(img)
    for data in datas:
        xys=data.split(" ")
        cl=xys.pop(0)
        cls.append(cl)
        xys_new=[]
        i=0
        while(i<len(xys)-1):
            xys_new.append(float(xys[i])*h)
            xys_new.append(float(xys[i+1])*w)
            i=i+2
        xys_new=np.array(xys_new,np.int_)
        xys_new = xys_new.reshape((-1,1,2))
        points.append(xys_new)
        cv.polylines(gray,[xys_new],True,(0,0,0),thickness=5)
    points.pop(-1)#删除最后一个list,这个是空的,我们可以通过遍历的方式为不同类别设计不同颜色mask
    cls.pop(-1)
    for i,cl in enumerate(cls):
        cv.drawContours(canvs, [points[i]], -1, (int(cl)*3,int(cl)*3, int(cl)*3), thickness=cv.FILLED)

    cv.imshow("img1",gray)
    cv.imshow("img",canvs)
    cv.waitKey(0)
    cv.destroyAllWindows()

在这个过程中,即需将原本的轮廓坐标转换为mask的形式,但这部分代码我并没有在ultralytics中找到。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彭祥.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值