计算机视觉和图像处理
图像分割
一、目标分割
- 图像分类旨在判断该图像所属类别
- 目标检测是在图像分类的基础上,进一步判断图像中的目标具体在图像的什么位置,通常是以外包矩阵的形式表示。
- 图像分割是目标检测更进阶的任务,目标检测只需要框出每个目标的包围盒,语义分割需要进一步判断图像中哪些像素属于哪个目标。但是,语义分割不区分属于相同类别的不同实例。
1.1 图像分割的定义
在计算机视觉领域,图像分割指的是将数字图像细分为多个图像子区域(像素的集合)的过程,并且同一个子区域内的特征具有一定相似性,不同子区域的特征呈现较为明显的差异。
1.2 任务类型
1.2.1 任务描述
我们的目标是输入一个RGB彩色图片或者一个灰度图,然后输出一个包含各个像素类别标签的分割图。
预测目标可以采用one-hot编码,即为每一个可能的类创建一个输出通道。通过取每个像素点在各个通道的argmax可以得到最终的预测分割图。
1.2.2 任务类型
目前的图像分割任务主要有两类: 语义分割和实例分割
- 语义分割就是把图像中每个像素赋予一个类别标签
- 实例分割,相对于语义分割来讲,不仅要区分不同类别的像素,还需要需要对同一类别的不同个体进行区分。如下图所示,不仅需要进行类别的划分,还要将各个个体划分出来:羊1,羊2,羊3,羊4,羊5等。
二、语义分割
2.1 FCN网络
FCN用于图像语义分割,自从该网络提出后,就成为语义分割的基本框架,后续算法基本都是在该网络框架中改进而来。
简而言之,FCN和CNN的区别就是:CNN卷积层之后连接的是全连接层;FCN卷积层之后仍然连卷积层,输出的是与输入大小相同的特征图。
2.1.1网络结构
FCN是一个端到端,像素对像素的全卷积网络,用于进行图像的语义分割。整体的网络结构分为两个部分:全卷积部分和上采样部分。
- 全卷积部分
全卷积部分使用经典的CNN网络(以AlexNet网络为例),并把最后的全连接层换成1x1卷积,用于特征提取。 - 上采用部分
上采样部分将最终得到的特征图上采样得到原图像大小的语义分割结果。
在这里采用的上卷积方法是反卷积,也叫转置卷积,反卷积是一种特殊的正向卷积,通俗的讲,就是输入补0+卷积。先按照一定的比例通过补0来扩大输入图像的尺寸,再进行正向卷积即可。
2.2 Unet网络
Unet网络是建立再FCNN网络基础上的。
整个网络由编码部分(左)和解码部分(右)组成,类似于一个大大的u字母,具体介绍如下:
1.编码部分是典型的卷积网络架构
编码部分的主要功能是提取输入图像的特征。通过一系列的卷积层和池化层(通常是最大池化层),编码部分逐渐减少特征图的尺寸,同时增加特征图的深度(即特征图的数量)。
- 架构中含有一种重复结构,每次重复中有2个3x3卷积层、非线性ReLU层和一个2x2 max pooling层(stride为2)。
- 每一次下采样后我们都把特征通道的数量加倍。
下采样(编码部分):减少数据点的数量或降低数据的分辨率,用于减少数据量、简化模型训练等
- 解码部分也使用了类似的模式:
解码部分的主要功能是恢复特征图的空间分辨率,最终生成与输入图像相同尺寸的分割结果。解码部分通过一系列的上采样操作(如转置卷积或上采样层)和卷积操作来逐步恢复特征图的尺寸。
- 每一步都首先使用反卷积,每次使用反卷积都将特征通道数量减半,特征图大小加倍。
- 反卷积过后,将反卷积的结果与编码部分中对应步骤的特征图拼接起来。
- 编码部分中的特征图尺寸稍大,将其修建过后进行拼接。
- 对拼接后的map再进行2次3x3的卷积。
- 最后一层的卷积核大小为1x1,将64通道的特征图转化为特定类比数量的结果。
上采样(解码部分):增加数据点的数量或提高数据的分辨率,用于恢复细节、改善图像质量等。
三、UNet案例
Oxford-IIIT Pet Dataset宠物图像分割数据集,包含37种宠物类别,其中有12种猫的类别和25种狗的类别,每个类别大约有200张图片,所有图像都具有品种,头部ROI和像素级分割的标注,如下图所示:
import os
from IPython.display import Image,display
from tensorflow.keras.preprocessing.image import load_img
import PIL
from PIL import ImageOps
3.1 数据集获取
3.1.1 设置相关信息
# 图像位置
input_dir = 'segdata/images/'
# 图像路径
input_img_path = sorted([os.path.join(input_dir,fname) for fname in os.listdir(input_dir) if fname.endswith('jpg')])
input_img_path
# 标注信息
target_dir = 'segdata/annotations/trimaps/'
# 目标值
target_img_path = sorted([os.path.join(target_dir,fname) for fname in os.listdir(target_dir) if fname.endswith('png') and not fname.startswith('.')])
target_img_path
# 图像大小及类别信息
img_size = (160,160)
batch_size = 32
num_classes = 4
3.1.2 图像展示
display(Image(input_img_path[10]))
img = PIL.ImageOps.autocontrast(load_img(target_img_path[10]))
d