1 Star 2 Fork 1

fakerlove / image-segmentation

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
README.md 23.84 KB
一键复制 编辑 原始数据 按行查看 历史
joker 提交于 2022-05-16 14:22 . 5.16

1. 图像分割简介

视频链接

训练赛

图像分割技巧之网络模型——来自39场Kaggle比赛 - 知乎 (zhihu.com)

分割图像的最新模型和排行榜

Semantic Segmentation | Papers With Code

1.1 简介

1.1.1 前景和背景

图像分割分为前景和背景

物体things:可数前景目标(行人等) --就是我们感兴趣的东西

事物stuff:不可数背景(天空,草地,路面)

1.1.2 图像分割方向

图像分割是图像处理和计算机视觉的领域的一个重要课题,其应用主要包括场景理解,医学图像分割,机器人感知,视频监控,增强现实和图像压缩等。这篇文章主要主要回顾了基于深度学习模型的图像分割方法。

多数的图像分割算法均是基于灰度值的不连续和相似的性质。在前者中,算法以灰度突变为基础分割一幅图像,如图像边缘分割。假设图像不同区域的边界彼此完全不同,且与背景不同,从而允许基于灰度的局部不连续性来进行边界检测]。后者是根据一组预定义的准则将一幅图像分割为相似区域,如阈值处理、区域生长、区域分裂和区域聚合都是基于这种方法形成的。下面将对每类算法进行详细说明。

图像分割主要包括三种:

image-20220303093512075

1) 语义分割

简单来说就是对图像中的像素点进行分类。

就是把图像中每个像素赋予一个类别标签(比如汽车、建筑、地面、天空等),比如下图就把图像分为了草地(浅绿)、人(红色)、树木(深绿)、天空(蓝色)等标签,用不同的颜色来表示。

预测结果为掩膜

2) 实例分割

不需要对每个像素进行标记,它只需要找到感兴趣物体的边缘轮廓就行,比如下图中的人就是感兴趣的物体。

该图的分割方法采用了一种称为Mask R-CNN的方法。我们可以看到每个人都是不同的颜色的轮廓,因此我们可以区分出单个个体。

image-20220303093733478

3) 全景分割

。它是语义分割和实例分割的结合。如下图所示,每个像素都被分为一类,如果一种类别里有多个实例,会用不同的颜色进行区分,我们可以知道哪个像素属于哪个类中的哪个实例。比如下图中黄色和红色都属于人这一个类别里,但是分别属于不同的实例(人),因此我们可以通过mask的颜色很容易分辨出不同的实例。 img

1.2 语义分割经典数据集

1.2.1 VOC数据集

pascal 数据集(VOC项目)

一共有20类别

image-20220303093941358

名称 链接网址
百度网盘 链接 提取码:kaeb
备用地址下载: 备用地址
官网 http://host.robots.ox.ac.uk/pascal/Voc/voc2012/index.html#devkit

VOC 2012

VOC 2007

讲解

PASCAL VOC挑战赛(The PASCAL Visual Object Classes )是一个世界级的计算机视觉挑战赛,PASCAL全称:Pattern Analysis, Statical Modeling and Computational Learning,是一个由欧盟资助的网络组织。PASCAL VOC挑战赛主要包括以下几类:图像分类(Object Classification),目标检测(Object Detection),目标分割(Object Segmentation),动作识别(Action Classification)等。

我们找到每个2012年的数据集

image-20220305162210763

image-20220305162734288

1.2.2 Cityscape

  • 数据集主要用于自动驾驶场景的
  • 一共30个类别
  • 5000张精细标注的图像(2975张训练图,500张验证图和1525张测试图)、20000张粗略标注的图像
  • 提供了语义分割与实力分割

image-20220303094148666

官网网址 Cityscapes Dataset – Semantic Understanding of Urban Street Scenes (cityscapes-dataset.com)

1.2.3 COCO数据集

  • 尽量不要只是包括一个大的目标或者一个空的场景场景需要广而且足够复杂 要求分割的标注结果非常精确
  • 一共91类,以人类4岁小孩能够辨识为基准,其中82类有超过5000个instance。

image-20220303094405429

官网网址 官网网址
百度云 链接: https://pan.baidu.com/s/1CTYQFpXy8aGDGEY9yyz-jg 提取码: 4v1i

数据集包括train数据,val验证数据集,test验证数据集。物体检测和keypoints身体关键点的检测。

数据集的大小和版本 大小:25 GB(压缩) 记录数量: 330K图像、80个对象类别、每幅图像有5个标签、25万个关键点。 COCO数据集分两部分发布,前部分于2014年发布,后部分于2015年,2014年版本:82,783 training, 40,504 validation, and 40,775 testing images,有270k的segmented people和886k的segmented object;2015年版本:165,482 train, 81,208 val, and 81,434 test images。 (1)、2014年版本的数据,一共有20G左右的图片和500M左右的标签文件。标签文件标记了每个segmentation的像素精确位置+bounding box的精确坐标,其精度均为小数点后两位。

数据内容如上 问:为什么那么多4G的文件? 答:因为train数据集大概18G,test数据集大概6.5G,上传的每个文件必须少于4G,博主没钱充会员,只能使用分卷压缩的方法压缩文件。

COCO数据集的下载 官网地址:http://cocodataset.org/#download

1、2014年数据集的下载 train2014:http://images.cocodataset.org/zips/train2014.zip val2014:http://images.cocodataset.org/zips/val2014.zip

http://msvocds.blob.core.windows.net/coco2014/train2014.zip

2、2017的数据集的下载 http://images.cocodataset.org/zips/train2017.zip http://images.cocodataset.org/annotations/annotations_trainval2017.zip

http://images.cocodataset.org/zips/val2017.zip http://images.cocodataset.org/annotations/stuff_annotations_trainval2017.zip

http://images.cocodataset.org/zips/test2017.zip http://images.cocodataset.org/annotations/image_info_test2017.zip

train2017 train2017:http://images.cocodataset.org/zips/train2017.zip train2017 annotations:http://images.cocodataset.org/annotations/annotations_trainval2017.zip

val2017 val2017:http://images.cocodataset.org/zips/val2017.zip val2017 annotations:http://images.cocodataset.org/annotations/stuff_annotations_trainval2017.zip

test2017 test2017:http://images.cocodataset.org/zips/test2017.zip test2017 info:http://images.cocodataset.org/annotations/image_info_test2017.zip

COCO数据集的使用方法

1.2.4 SUNRGBD

常用语3d语义分割

另外一个3d语义分割数据集SUN3D Database (princeton.edu)

官网网址http://rgbd.cs.princeton.edu/

室内场景 ,类别 37 ,训练2666,验证2619,测试5050 ,总数10335

1.2.5 NYUDv

1.2.6 CamVid 数据集(新手入门)

官网网址 Object Recognition in Video Dataset (cam.ac.uk)
github上有整理好的360*480分辨率的图像数据SegNet GitHub - lih627/CamVid: CamVid original data set, and the generated 11 category labels and training grayscale images.
百度云链接 链接:https://pan.baidu.com/s/11K4Wz-ljg60Wb5cDlFEEzQ
提取码:3dig
--解压可能失败,直接使用即可

CamVid分类信息

64 128 64	Animal
192 0 128	Archway
0 128 192	Bicyclist
0 128 64	Bridge
128 0 0		Building
64 0 128	Car
64 0 192	CartLuggagePram
192 128 64	Child
192 192 128	Column_Pole
64 64 128	Fence
128 0 192	LaneMkgsDriv
192 0 64	LaneMkgsNonDriv
128 128 64	Misc_Text
192 0 192	MotorcycleScooter
128 64 64	OtherMoving
64 192 128	ParkingBlock
64 64 0		Pedestrian
128 64 128	Road
128 128 192	RoadShoulder
0 0 192		Sidewalk
192 128 128	SignSymbol
128 128 128	Sky
64 128 192	SUVPickupTruck
0 0 64		TrafficCone
0 64 64		TrafficLight
192 64 128	Train
128 128 0	Tree
192 128 192	Truck_Bus
64 0 64		Tunnel
192 192 0	VegetationMisc
0 0 0		Void
64 192 0	Wall

1.2.7 CIFAR-10 dataset

CIFAR-10 and CIFAR-100 datasets (toronto.edu)

image-20220304105546961

def unpickle(file):
    import pickle
    with open(file, 'rb') as fo:
        dict = pickle.load(fo, encoding='bytes')
    return dict

展示代码

import numpy as np
from matplotlib import pyplot as plt
import os

def unpickle(file):
    import pickle
    with open(file, 'rb') as fo:
        dict = pickle.load(fo, encoding='bytes')
    return dict
    
def loadDataset(dataset_folder): #训练集
    dataset = np.zeros((10000*5, 3*32*32), dtype = np.int32) #训练集 先用0填充,每个元素都是4byte integer
    labels = np.zeros((10000*5), dtype =np.int32)
    for i in range(5):
        d = unpickle(os.path.join(dataset_folder,"data_batch_%d"%(i+1)))
        #每个文件含1万张图片的数据
        for j in range(len(d[b'labels'])):  #每张图片,shape: (3072,)
            dataset[ 10000*i+j] = d[b'data'][j]
            labels[ 10000*i+j] = d[b'labels'][j]
    reshaped = np.reshape(dataset,(10000*5, 3, 32, 32))
    #交换轴
    swapaxesed = np.swapaxes(reshaped,1,2)# 按图片,行,颜色通道 ,列 排列
    swapaxesed = np.swapaxes(swapaxesed,2,3) # 按图片,行,列,颜色通道 排列
    
    return swapaxesed, labels
    
def loadValidset(path): #验证集
    valid_dataset = np.zeros((10000, 3*32*32), dtype = np.int32) #训练集 先用0填充,每个元素都是4byte integer
    valid_labels = np.zeros((10000), dtype =np.int32)
    d = unpickle(path)
    #测试含1万张图片的数据
    for j in range(len(d[b'labels'])):  #每张图片,shape: (3072,)
        valid_dataset[j] = d[b'data'][j]
        valid_labels[j] = d[b'labels'][j]
    reshaped = np.reshape(valid_dataset,(10000, 3, 32, 32))
    #交换轴
    swapaxesed = np.swapaxes(reshaped,1,2)# 按图片,行,颜色通道 ,列 排列
    swapaxesed = np.swapaxes(swapaxesed,2,3) # 按图片,行,列,颜色通道 排列
    return swapaxesed, valid_labels
    
    
dataset_folder = r"E:\Python36\my tensorflow\DataSet\CIFAR-10\cifar-10-batches-py"
train_dataset, train_labels = loadDataset(dataset_folder)
valid_dataset, valid_labels = loadValidset(os.path.join(dataset_folder,"test_batch"))
#图片识别时才需要
label_names =unpickle(os.path.join(dataset_folder, "batches.meta"))
names = label_names[b'label_names']#分类结果字节字符串


if __name__ == "__main__":
    #测试数据集是否加载成功
    print(min(train_labels)) #标签编码从0开始
    for index in range(100,200):
        a = valid_dataset[index]
        print(a.shape)
        print(a)
        plt.imshow(a)
        print(valid_labels[index])
        plt.title(names[int(valid_labels[index])],fontsize =8)
        plt.xticks([]); plt.yticks([])
        plt.show()

其中的html文件是数据集的官网网页。其它文件均是由cPickle库产生的序列化后的对象。各个data_batch_x 和test_batch 都是包含以下元素的字典:

  • data

类型为uint8s 大小为10000x3072 的numpy 数组。数组的每一行代表一张32X32X3的彩色图片(32X32X3 =3072), 3072个元素中的前1024个元素代表红色通道的亮度值,中间的1024个元素代表绿色通道的亮度值,后面的1024个元素代表蓝色通道的亮度值。

  • label

10000个元素的列表。列表的每个元素范围为0~9的整数,代表10个分类。

batches.meta 包含一个字典对象:

  • label_names

它给出了0~9每个数字对应的分类名。例如label_names[0] == "airplane",label_names[1] == "automobile"等等。

下面的代码可以将CIFAR-10 数据集解析到Numpy数组

1.2.8 ADE20K

有别人做好的项目

chenjun2hao/segmentation.pytorch: Pytorch implementation for Semantic Segmentation/Scene Parsing on MIT ADE20K dataset (github.com)

这是一个PyTorch实现的在MIT ADE20K场景解析数据集上的语义分割模型

This is a PyTorch implementation of semantic segmentation models on MIT ADE20K scene parsing dataset (http://sceneparsing.csail.mit.edu/).

ADE20K is the largest open source dataset for semantic segmentation and scene parsing, released by MIT Computer Vision team. Follow the link below to find the repository for our dataset and implementations on Caffe and Torch7: https://github.com/CSAILVision/sceneparsing

ADE20K是MIT计算机视觉团队发布的最大的语义分割和场景解析开源数据集。按照下面的链接找到我们在Caffe和Torch7上的数据集和实现的存储库

训练集:20210张图片 验证集:200张 共150个类别(但是语义标注的时候,像素点不能全面覆盖,存在偶尔有点漏掉的现象,于是标注的时候会多一个 “0” 类别,不计入loss的计算,但是网络的输出只有150个类别) 语义信息的标注是在一张灰度图像上的,只是各个点的取值范围是(0-150, 0表示背景类,不计入loss计算) 类别文件就不全贴出来了。

background	背景
wall	墙
building	建筑
sky	天空
floor	地板
tree	树
ceiling	天花板
road	路
bed 	床
windowpane	窗玻璃
grass	草地
cabinet	柜子
sidewalk	人行道
person	人
earth	地
door	门
table	桌子
...

1.3 评估指标

1.3.1 语义分割评估指标

  • Pixel Accuracy:逐像素分类精度

  • Mean Pixel Accuracy : 每个类内被正确分类像素数的比例

  • Iou:前景目标交并比$Iou=\frac{A\cap B}{A\cup B}$

    image-20220303095337589

  • mIou:每个类的IoU平均值

  • FWIoU:根据每个类出现的评率给mIou计算权重

mIOU

语义分割说到底还是一个分类任务,既然是分类任务,预测的结果往往就是四种情况:

  • true positive(TP)
  • false positive(FP)
  • true negative(TN)
  • false negative(FN)

mIOU的定义:计算真实值和预测值两个集合的交集和并集之比。这个比例可以变形为TP(交集)比上TP、FP、FN之和(并集)。即:mIOU=TP/(FP+FN+TP)。

img

1.3.2 语义分割常用优化目标

交叉熵损失

交叉熵损失,$z_k$表示网络输出,$f(z_k)$表示概率 $$ f(z_k)=\frac{e^{z_k}}{\sum_j^{e^{z_j}}},l(y,z)=-\sum_{k=0}^Cy_clog(f(z_k)) $$

分割损失即所有像素分类损失的累加

交叉熵损失特点 $$ \frac{\partial l(y,z)}{\partial z_k}=\begin{cases}f(z_y)-1 \\ f(z_k)\end{cases} $$ 可用于多类别,正负样本梯度稳定

dice损失

一般用来两分类

P,G分别表示预测和真值,定义Dice相似度$S=2\frac{|P\cap G|}{|P|+|G|}$

$S_1=\frac{2\sum_N p_ig_i}{\sum_Np_i^2+\sum_Ng_i^2}$

$S_2=\frac{2\sum_Np_ig_i}{\sum_N p_+\sum_N g_i}$

dice损失$D(p,g)=1-S$

缺点

  • 专注正样本,适合小目标
  • 损失可能不稳定

1.4 上采样模块

分割网络的两个模块

卷积模块:提取特征

反卷积模块:上采样恢复到原图尺度

通常

卷积网络-编码器

反卷积网络--解码器

1.5 图像分割研究现状

1.FCN 2.Normalized cuts and image segmentation(图论方法) 3.Mean shift (像素聚类,不能用于实时算法) 4.UNet 5.SLIC(比较符合人们的预期) 6.Graph-Based Image Segmentation(贪心聚类) 7.Contour Detection and Hierarchical Image Segmentation(检测边缘,进行分割) 8.DeepLab谷歌 9.SegNet 剑桥大学 10.Mask R-CNN 何凯明 个人补充 RefineNet PSPNet 基于全卷积的GAN语义分割模型

1.5.1 FCN

img

FCN 全卷积神经网络,图像分割的开山之作。

论文地址:https://arxiv.org/abs/1411.4038

1.5.2 Encoder-Decoder(SegNet,UNet)

SegNet和FCN网络的思路基本一致。编码器部分使用VGG16的前13层卷积,不同点在于Decoder部分Upsampling的方式。FCN通过将特征图deconv得到的结果与编码器对应大小的特征图相加得到上采样结果;而SegNet用Encoder部分maxpool的索引进行Decoder部分的上采样(原文描述:the decoder upsamples the lower resolution input feature maps. Specifically, the decoder uses pooling indices computed in the max-pooling step of the corresponding encoder to perform non-linear upsampling.)。

在这里插入图片描述

论文地址 https://arxiv.org/abs/1505.04597

目前使用最多的网络模型,大多数的网络模型都是在此基础上改动。比较典型的又Segnet,u_net。

UNet

U-Net网络最初是针对生物医学图像设计的,但由于其初四的性能,现如今UNet及其变体已经广泛应用到CV各个子领域。UNet网络由U通道和短接通道(skip-connection)组成,U通道类似于SegNet的编解码结构,其中编码部分(contracting path)进行特征提取和捕获上下文信息,解码部分(expanding path)用解码特征图来预测像素标签。短接通道提高了模型精度并解决了梯度消失问题,特别要注意的是短接通道特征图与上采用特征图是拼接而不是相加(不同于FCN)。

FC-DenseNet

FC-DenseNet (百层提拉米苏网络)(paper title: The One Hundred Layers Tiramisu: Fully Convolutional DenseNets for Semantic Segmentation)该网络结构是由用密集连接块(Dense Block)和UNet架构组建的。该网络最简单的版本是由向下过渡的两个下采样路径和向上过渡的两个上采样路径组成。且同样包含两个水平跳跃连接,将来自下采样路径的特征图与上采样路径中的相应特征图拼接在一起。上采样路径和下采样路径中的连接模式不完全同:下采样路径中,每个密集块外有一条跳跃拼接通路,从而导致特征图数量的线性增长,而在上采样路径中没有此操作。(多说一句,这个网络的简称可以是Dense Unet,但是有一篇论文叫Fully Dense UNet for 2D Sparse Photoacoustic Tomography Artifact Removal, 是一个光声成像去伪影的论文,我看到过好多博客引用这篇论文里面的插图来谈语义分割,根本就不是一码事好么 =_=||,自己能分清即可。)

1.5.3 DeepLab

Dilated Convolutional Models and DeepLab Family

DeepLab系列网络,是第一次空洞卷积用在了卷积网络中,并且得到了一个较高的准确率。其中目前表现最好的是deeplabv3,网络结构上图所示。 论文链接 https://arxiv.org/abs/1706.05587

1.5.4 Mask R-CNN

1.5.5 分类网络

VGG net

AlexNet

GooleNet

1.6 计算机视觉会议期刊

CVPR: IEEE Conference on Computer Vision and Pattern Recognition IEEE国际计算机视觉与模式识别会议 PAMlI: IEEE Transactions on Pattern Analysis and Machine Intelligence IEEE模式分析与机器智能汇刊

2. 入门

关键难题

  • 如何恢复高分辨率。得到高精度的分割结果

    image-20220303211354036

  • 下采样后特征分辨率低

  • CNN 拥有的一定程度的空间不变性

2.1 FCN

[链接][/fcn]

2.2 Unet

UNet论文网址

U-Net是原作者参加ISBI Challenge提出的一种分割网络,能够适应很小的训练集(大约30张图)。U-Net与FCN都是很小的分割网络,既没有使用空洞卷积,也没有后接CRF,结构简单

img

整个U-Net网络结构如图9,类似于一个大大的U字母:首先进行Conv+Pooling下采样;然后Deconv反卷积进行上采样,crop之前的低层feature map,进行融合;然后再次上采样。重复这个过程,直到获得输出388x388x2的feature map,最后经过softmax获得output segment map。总体来说与FCN思路非常类似。

为何要提起U-Net?是因为U-Net采用了与FCN完全不同的特征融合方式:拼接!

img

与FCN逐点相加不同,U-Net采用将特征在channel维度拼接在一起,形成更“厚”的特征。所以:

语义分割网络在特征融合时也有2种办法:

  1. FCN式的逐点相加,对应caffe的EltwiseLayer层,对应tensorflow的tf.add()
  2. U-Net式的channel维度拼接融合,对应caffe的ConcatLayer层,对应tensorflow的tf.concat()

记得划重点哦。

相比其他大型网络,FCN/U-Net还是蛮简单的,就不多废话了。

总结一下,CNN图像语义分割也就基本上是这个套路:

  1. 下采样+上采样:Convlution + Deconvlution/Resize
  2. 多尺度特征融合:特征逐点相加/特征channel维度拼接
  3. 获得像素级别的segement map:对每一个像素点进行判断类别

看,即使是更复杂的DeepLab v3+依然也是这个基本套路(至于DeepLab以后再说)。

2.3 Deeplab

img

弱监督语义分割

什么是弱监督语义分割

高昂的标注成本

image-20220303211700122

常见语义分割b标级别

类别标注(imahe-level)

image-20220303211750946

点的标注(point),笔触标注(Strokes)

image-20220303211833278

弱监督语义分割关键技术

Python
1
https://gitee.com/fakerlove/image-segmentation.git
git@gitee.com:fakerlove/image-segmentation.git
fakerlove
image-segmentation
image-segmentation
master

搜索帮助