Datawhale干货

作者:游璐颖,福州大学,Datawhale成员

图像分割是计算机视觉中除了分类和检测外的另一项基本任务,它意味着要将图片根据内容分割成不同的块。相比图像分类和检测,分割是一项更精细的工作,因为需要对每个像素点分类。

如下图的街景分割,由于对每个像素点都分类,物体的轮廓是精准勾勒的,而不是像检测那样给出边界框。

图像分割可以分为以下三个子领域:语义分割、实例分割、全景分割。

由对比图可发现,语义分割是从像素层次来识别图像,为图像中的每个像素制定类别标记,目前广泛应用于医学图像和无人驾驶等;实例分割相对更具有挑战性,不仅需要正确检测图像中的目标,同时还要精确的分割每个实例;全景分割综合了两个任务,要求图像中的每个像素点都必须被分配给一个语义标签和一个实例id。

01 语义分割中的关键步骤

在进行网络训练时,时常需要对语义标签图或是实例分割图进行预处理。如对于一张彩色的标签图,通过颜色映射表得到每种颜色所代表的类别,再将其转换成相应的掩膜或Onehot编码完成训练。这里将会对于其中的关键步骤进行讲解。

首先,以语义分割任务为例,介绍标签的不同表达形式。

1.1 语义标签图

语义分割数据集中包括原图和语义标签图,两者的尺寸大小相同,均为RGB图像。

在标签图像中,白色和黑色分别代表边框和背景,而其他不同颜色代表不同的类别:

1.2 单通道掩膜

每个标签的RGB值与各自的标注类别对应,则可以很容易地查找标签中每个像素的类别索引,生成单通道掩膜Mask。

如下面这种图,标注类别包括:Person、Purse、Plants、Sidewalk、Building。将语义标签图转换为单通道掩膜后为右图所示,尺寸大小不变,但通道数由3变为1。

每个像素点位置一一对应。

1.3 Onehot编码

Onehot作为一种编码方式,可以对每一个单通道掩膜进行编码。

比如对于上述掩膜图Mask,图像尺寸为,标签类别共有5类,我们需要将这个Mask变为一个5个通道的Onehot输出,尺寸为,也就是将掩膜中值全为1的像素点抽取出生成一个图,相应位置置为1,其余为0。再将全为2的抽取出再生成一个图,相应位置置为1,其余为0,以此类推。

02 语义分割实践

接下来以Pascal VOC 2012语义分割数据集为例,介绍不同表达形式之间应该如何相互转换。

实践采用的是Pascal VOC 2012语义分割数据集,它是语义分割任务中十分重要的数据集,有 20 类目标,这些目标包括人类、机动车类以及其他类,可用于目标类别或背景的分割。

数据集开源地址:

https://gas.graviti.cn/dataset/yluy/VOC2012Segmentation

2.1 数据集读取

本次使用格物钛数据平台服务来完成数据集的在线读取,平台支持多种数据集类型,且提供了很多公开数据集便于使用。在使用之前先进行一些必要的准备工作:

  • Fork数据集:如果需要使用公开数据集,则需要将其先fork到自己的账户。

  • 获取AccessKey:获取使用SDK与格物钛数据平台交互所需的密钥,链接为https://gas.graviti.cn/tensorbay/developer

  • 理解Segment:数据集的进一步划分,如VOC数据集分成了“train”和“test”两个部分。

import os
from tensorbay import GAS
from tensorbay.dataset import Data, Dataset
from tensorbay.label import InstanceMask, SemanticMask
from PIL import Image
import numpy as np
import torchvision
import matplotlib.pyplot as pltACCESS_KEY = "<YOUR_ACCESSKEY>"
gas = GAS(ACCESS_KEY)def read_voc_images(is_train=True, index=0):"""read voc image using tensorbay"""dataset = Dataset("VOC2012Segmentation", gas)if is_train:segment = dataset["train"]else:segment = dataset["test"]data = segment[index]feature = Image.open(data.open()).convert("RGB")label = Image.open(data.label.semantic_mask.open()).convert("RGB")visualize(feature, label)return feature, label  # PIL Imagedef visualize(feature, label):"""visualize feature and label"""fig = plt.figure()ax = fig.add_subplot(121)  # 第一个子图ax.imshow(feature)ax2 = fig.add_subplot(122)  # 第二个子图ax2.imshow(label)plt.show()train_feature, train_label = read_voc_images(is_train=True, index=10)
train_label = np.array(train_label) # (375, 500, 3)

2.2 颜色映射表

在得到彩色语义标签图后,则可以构建一个颜色表映射,列出标签中每个RGB颜色的值及其标注的类别。

def colormap_voc():"""create a colormap"""colormap = [[0, 0, 0], [128, 0, 0], [0, 128, 0], [128, 128, 0],[0, 0, 128], [128, 0, 128], [0, 128, 128], [128, 128, 128],[64, 0, 0], [192, 0, 0], [64, 128, 0], [192, 128, 0],[64, 0, 128], [192, 0, 128], [64, 128, 128], [192, 128, 128],[0, 64, 0], [128, 64, 0], [0, 192, 0], [128, 192, 0],[0, 64, 128]]classes = ['background', 'aeroplane', 'bicycle', 'bird', 'boat','bottle', 'bus', 'car', 'cat', 'chair', 'cow','diningtable', 'dog', 'horse', 'motorbike', 'person','potted plant', 'sheep', 'sofa', 'train', 'tv/monitor']return colormap, classes

2.3 Label与Onehot转换

根据映射表,实现语义标签图与Onehot编码的相互转换:

def label_to_onehot(label, colormap):"""Converts a segmentation label (H, W, C) to (H, W, K) where the last dim is a onehot encoding vector, C is usually 1 or 3, and K is the number of class."""semantic_map = []for colour in colormap:equality = np.equal(label, colour)class_map = np.all(equality, axis=-1)semantic_map.append(class_map)semantic_map = np.stack(semantic_map, axis=-1).astype(np.float32)return semantic_mapdef onehot_to_label(semantic_map, colormap):"""Converts a mask (H, W, K) to (H, W, C)"""x = np.argmax(semantic_map, axis=-1)colour_codes = np.array(colormap)label = np.uint8(colour_codes[x.astype(np.uint8)])return labelcolormap, classes = colormap_voc()
semantic_map = mask_to_onehot(train_label, colormap)
print(semantic_map.shape)  # [H, W, K] = [375, 500, 21] 包括背景共21个类别label = onehot_to_label(semantic_map, colormap)
print(label.shape) # [H, W, K] = [375, 500, 3]

2.4 Onehot与Mask转换

同样,借助映射表,实现单通道掩膜Mask与Onehot编码的相互转换:

def onehot2mask(semantic_map):"""Converts a mask (K, H, W) to (H,W)"""_mask = np.argmax(semantic_map, axis=0).astype(np.uint8)return _maskdef mask2onehot(mask, num_classes):"""Converts a segmentation mask (H,W) to (K,H,W) where the last dim is a onehot encoding vector"""semantic_map = [mask == i for i in range(num_classes)]return np.array(semantic_map).astype(np.uint8)mask = onehot2mask(semantic_map.transpose(2,0,1))
print(np.unique(mask)) # [ 0  1 15] 索引相对应的是背景、飞机、人
print(mask.shape) # (375, 500)semantic_map = mask2onehot(mask, len(colormap))
print(semantic_map.shape) # (21, 375, 500)

游璐颖

福州大学,datawhale成员

个人博客:https://sonatau.github.io

点击阅读原文直接获取数据集

动手实践系列:CV语义分割!相关推荐

  1. eBPF动手实践系列一:解构内核源码eBPF样例编译过程

    作者:闻茂泉 他山之石 了解和掌握纯c语言的ebpf编译和使用,有助于我们加深对于eBPF技术原理的进一步掌握,也有助于开发符合自己业务需求的高性能的ebpf程序.目前常见和主流的纯c语言的ebpf编 ...

  2. CV语义分割实践指南!

    ↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过 Datawhale干货 作者:徐和鼎,浙江大学,Datawhale优秀学习者 遥感技术已成为获取 ...

  3. 【深度学习】CV语义分割实践指南!

    作者:徐和鼎,浙江大学,Datawhale优秀学习者 遥感技术已成为获取地表覆盖信息最为行之有效的手段,已经成功应用于地表覆盖检测.植被面积检测和建筑物检测任务.本文以天池学习赛地表建筑物识别为例,对 ...

  4. 【CV语义分割】全卷积神经网络FCN(更新ing)

    学习总结 (1)paper<Fully Convolutional Networks for Semantic Segmentation> (2)论文翻译可以参考:https://www. ...

  5. 天池大赛 + CV语义分割 + 78万奖金:全国数字生态创新大赛来了!

    ↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过 Datawhale赛事 主办单位:丽水市人民政府,阿里巴巴集团 首届全国绿色生态创新大赛是由丽水 ...

  6. 天池赛题解析:零基础入门语义分割-地表建筑物识别-CV语义分割实战(附部分代码)

    赛题内容 赛题背景 赛题以计算机视觉为背景,要求选手使用给定的航拍图像训练模型并完成地表建筑物识别任务.为更好的引导大家入门,我们为本赛题定制了学习方案和学习任务,具体包括语义分割的模型和具体的应用案 ...

  7. CV语义分割,类别加权损失函数

    作者: 头孢就酒的快乐神仙 转载地址:https://bbs.huaweicloud.com/forum/thread-146576-1-1.html 在复现High-resolution NetWo ...

  8. 【原创 深度学习与TensorFlow 动手实践系列 - 2】第二课:传统神经网络

    第二课 传统神经网络 <深度学习>整体结构: 线性回归 -> 神经网络 -> 卷积神经网络(CNN)-> 循环神经网络(RNN)- LSTM 目标分类(人脸识别,物品识别 ...

  9. CV之IS:利用pixellib库基于deeplabv3_xception模型对《庆余年》片段实现语义分割/图像分割简单代码全实现

    CV之IS:利用pixellib库基于deeplabv3_xception模型对<庆余年>片段实现语义分割/图像分割简单代码全实现 目录 利用pixellib库基于deeplabv3_xc ...

最新文章

  1. macos降级_macOS Big Sur如何降级
  2. C#_数据库基本交互
  3. Fuxi ServiceModeJob 多租户(Quota Group) 功能介绍
  4. Paper:《Graph Neural Networks: A Review of Methods and Applications》翻译与解读
  5. seconds_behind_master监控复制推延的不足及pt-heartbeat改进方法
  6. 一次基于Vue.Js的用户体验优化 (vue drag)
  7. 基于javascript的asp数据库操作类,含分页、字符串截取、用户登陆验证[原创]
  8. 中医移动医疗_中医之极简移动医疗
  9. 小程序使用sass_如何使用Sass Maps生成所有实用程序类
  10. ES6_proxy_note
  11. torchtext处理文本数据——使用自己的word2vec模型作为词向量建立词表(学习二)
  12. 封装DataList分页
  13. Get Network Utilization
  14. React应用优化:避免不必要的render
  15. Java | 内部类的实例化
  16. Recycler 病毒(jwgkvsq.vmx)手动查杀
  17. 极乐净土—官方中文版 单曲循环洗脑三天了φ(ω*)
  18. mac抹掉磁盘重装系统未能与服务器取得联系_苹果笔记本怎么重装系统
  19. 【UE4 C++】角色拾取、替换武器(下)
  20. R语言中的cor和cov

热门文章

  1. SQLserver 常用函数适用方法(转载)
  2. Mui.ajax请求服务器正确返回json数据格式
  3. 赢在中国(08-02-27)
  4. 【青少年编程】黄羽恒:Python
  5. 【青少年编程】【Scratch】10 画笔模块
  6. 【ACM】二叉搜索树(Binary Search Tree /BS Tree) 小结
  7. 【数据结构】顺序循环队列及其实现(C语言)
  8. 【C++】用指针做函数参数
  9. 对标Oculus Quest2,爱奇艺奇遇VR打的什么牌?
  10. 1 元秒杀 1000+ 册爆款电子书,错过再等一年!