图像语义分割和目标检测(上)

语义分割是对图像在像素级别上进行分类的方法,在一张图像中,属于同一类的像素点都要被预测为相同的类,因此语义分割是从像素级别来理解图像。但是需要正确区分语义分割和实例分割,虽然他们在名称上很相似,但是他们属于不同的计算机视觉任务。例如,一张照片中有多个人,针对语义分割任务,只需将所有人的像素都归为一类即可,但是针对实例分割任务,则需要将不同人的像素归为不同的类。简单来说,实例分割会比语义分割所做的工作更近一步。

随着深度学习在计算机视觉领域的发展,提出了多种基于深度学习方法的图像语义分割网络,如FCN、U-Net、SegNet、DeepLab等。下面对FCN、U-Net、SegNet等网络结构进行一些简单的介绍。

1.FCN

FCN语义分割网络是在图像语义分割文章Fully Convolutional Networks for Semantic Segmentation中提出的全卷积网络,该文章是基于深度网络进行图像语义分割的开山之作,而且是全卷积的网络,可以输入任意图像尺寸。FCN的主要思想是:

(1)对于一般的CNN图像分类网络,如VGG和ResNet,在网络的最后是通过连接层,并经过softmax后进行分类。但这只能表示整个图片的类别,不能表示每个像素点的类别,所以这种全连接方法不适用于图像分割。因此FCN提出把网络最后几个全连接层换成卷积操作,已获得和输入图像尺寸相同的特征映射,然后通过softmax获得每个像素点的分类信息,既可以实现基于像素点分类的图像分割。

(2)端到端像素级语义分割任务,需要输出分类结果尺寸和输入图像尺寸一致,而基于卷积+池化的网络结构,或缩小图片尺寸。因此FCN引入反卷积(deconvolution,和转置卷积的功能一致,也可成为转置卷积)操作,对缩小后的特征映射进行上采样,从而满足像素级的图像分割要求。

(3)为了更有效地利用特征映射信息,FCN提出一种跨层连接结构,将低层和高层的目标位置信息的特征映射进行融合,即将低层目标位置信息强但语义信息弱的特征映射与高层目标位置信息弱但语义信息强的特征映射进行融合,一次来提升网络对图像进行语义分割的性能。

2.U-Net

U-Net是原作者参加ISBI Challenge提出的一种分割网络,能够适应较小的训练集(大约30张图片)。其设计思想是基于FCN网络,在整个网络中仅有卷积层,没有全连接层。因为训练数据较少,故采用大量弹性形变的方式增强数据,以让模型更好地学习形变不变性,这种增强方式对于医学图像来说很重要,并在不同的特征融合方式上,相较于FCN式的逐点相加,U-Net则采用在通道维度上进行拼接融合。

3.SegNet

SegNet的网络结构借鉴了自编码网络的思想,网络具有编码器网络和相应的解码器网络,最后通过softmax分类器对每个像素点进行分类。

网络在编码器处,执行卷积核最大值池化等操作,并且会在进行2*2最大值池化时,存储相应的最大值池化索引。在解码器部分,执行上采样和卷积,并且在上采样期间,会调用相应编码器层的最大值池化索引来帮助上采样操作,最后,每个像素通过softmax分类器进行预测类别。

下面来介绍常用的目标检测网络。

目标检测是很多计算机视觉应用的基础,如实例分割、人体关键点提取、人脸识别等,目标检测任务可以认为是目标分类和定位两个任务的结合。目标检测主要关注特定的物体目标,要求同时获得这一目标的类别信息和位置信息。基于深度学习的目标检测方法主要有两类,一类是两阶段检测模型,如R-CNN、Fast R-CNN、Faster R-CNN等模型,他们将检测问题划分为两个阶段,首先产生候选区域,然后对候选区域分类并对目标位置进行精修;另一类是但阶段检测模型,如YOLO系列、SSD、Retina-Net等模型,他们不需要产生候选区域阶段,直接产生物体的类别概率和位置坐标值,经过单次检测即可直接得到最终的检测结果,因此他们的检测速度更快。

1.R-CNN

R-CNN是将CNN方法引入目标检测领域的开山之作,大大提高了目标检测效果,并且改变了目标检测领域的主要研究思路。

R-CNN的工作流程主要有4个步骤。

(1)候选区域生成:每张图像会采用Selective Search方法,生成1000~2000个候选区域。

(2)特征提取:针对每个生成的候选区域,归一化为同一尺寸,使用深度卷积网络(CNN)提取候选区域的特征。

(3)类别判断:将CNN特征送入每一类SVM分类器,判别候选区域是否属于该类。

(4)位置精修:使用回归器精细修正候选框位置。

2.Faster R-CNN

Faster R-CNN是两阶段方法的奠基性工作,提出的RPN(Region Proposal Networks)网络取代Selective Search算法使得检测任务可以由神经网络端到端地完成。其具体操作方法是将RPN放在最后一个卷积层之后,RPN直接训练得到候选区域。RPN网络的特点在于通过滑动窗口的方式实现候选框的提取,在特征映射上滑动窗口,每个滑动窗口位置生成9个不同尺度、不同宽高的候选窗口,提取对应9个候选窗口的特征,用于目标分类和边框回归。目标分类只需要区分候选框内特征为前景或者北京,与Fast R-CNN类似,边框回归确定更精确的目标位置。

3.YOLO

YOLO(You Only Look)是经典的但阶段目标检测算法,将目标区域预测和目标类别预测整合于单个神经网络模型中,实在在准确率较高的情况下快速检测与识别目标。YOLO的主要优点是检测速度快、全局处理使得北京错误相对较少、泛化性能好,但是YOLO由于其设计思想的局限,所以会在小目标检测时有些困难。

YOLO的工作流程如下:首先将图像划分为S*S个网格,然后再每个网格上通过深度卷积网络给出其物体所属的类别判断(图像使用不同的颜色表示),并在每个网格上生成B个边框(box),每个边框预测5个回归值,其中前4个值表示边框位置,第五个至表示这个边框含有物体的概率和位置的准确程度。最后经过NMS(Non-Maximum Suppression,非极大抑制)过滤得到最后的预测框。

这怒地图像的语义分割网络,下面将介绍Pytorch中已经与训练好网络的使用方式,然后使用VOC2012数据集训练一个FCN语义分割网络。

在pytorch提供的已与训练好的图像语义分割网络中,有连个你与训练好的网络,分别是FCN ResNet101系列和DeepLabV3 ResNet101系列。针对语义分割的分割器,需要输入图像使用了相同的预处理方式,即先将每张图像的像素值预处理到0~1之间,然后对图像进行标准化处理,使用的均值为[0.485,0.456,0.406],标准差为[0.229,0.224,0.225]

在Pascal VOC(Pattern analysis statistical modelling and computational learning,Visual Object Class)数据集中存在20个类别和1个背景类,与训练好的模型在COCO train2017的子集上进行了与训练。这20个类别分别分为4个大类,分别为人、动物(鸟、猫、牛、马、羊)、交通工具(飞机、自行车、船、大巴、轿车、摩托车、火车)、室内物品(瓶子、椅子、餐桌、盆栽、沙发、显示器)等。已经预训练好的可供使用的网络模型如下所示:

网络类描述segmentation.fcn_resnet50()具有ResNet-50结构的全卷积网络模型sogmentation.fcn_resnet101()具有ResNet-101结构的全卷积网络模型segmentation.deeplabv3_resnet50()具有ResNet-50结构的DeepLabV3模型segmentation.deeplabv3_resnet101()具有ResNet-101结构的DeepLabV3模型

下面以segmentation.fcn_resnet101()为例,介绍如何使用这些已经与训练好的网络结构进行图像的语义分割任务。首先导入需要使用的库和模块。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import PIL
import torch
from torchvision import transforms
import torchvision

下面从torchvision库的models模块下导入与训练好的segmentation.fcn_resnet101()网络,并且设置参数pretrained=True,程序如下所示:

图像语义分割和目标检测(上)

下面从文件中读取一张照片,并对其进行预测,程序如下:

image=PIL.Image.open("data/chap10/照片1.jpg")
image_transf=transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485,0.456,0.406],
                         std=[0.229,0.224,0.225])
])
image_tensor=image_transf(image).unsqueeze(0)
output=model(image_tensor)["out"]
outputarg=torch.argmax(output.squeeze(),dim=0).numpy()
print(outputarg)

输出结果如下:

图像语义分割和目标检测(上)

上述程序对一整副图像的预测结果,只需要使用网络输出的”out”对应的预测矩阵即可,该输出是一个三维矩阵,该三维矩阵可以使用torch.argmax()将其转化为二维矩阵,并且二维矩阵中的每个取值均代表图像中对应位置像素点的预测类别。

为了更直观地查看网络的图像分割结果,可以将像素值的每个预测类别分别编码为不同的颜色,然后将图像可视化,用于直观地观察图像的结果。

定义一个编码颜色的函数decode_segmaps(),程序如下所示:

def decode_segmaps(image,label_colors,nc=21):
    r=np.zeros_like(image).astype(np.unit8)
    g=np.zeros_like(image).astype(np.unit8)
    b=np.zeros_like(image).astype(np.unit8)
    for cla in range(0,nc):
        idx=image==cla
        r[idx]=label_colors[cla,0]
        g[idx]=label_colors[cla,1]
        b[idx]=label_colors[cla,2]
    rgbimage=np.stack([r,g,b],axis=2)
    return rgbimage

该函数通过label_colors来指定所有的颜色编码。然后对图像image中的不同像素点取值并定义一种颜色,nc参数指定数据的类别。下面对图像分割的结果进行可视化,程序如下所示:

label_colors=np.array([(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)])
outputrgb=decode_segmaps(outputarg,label_colors)
plt.figure(figsize=(20,8))
plt.subplot(1,2,1)
plt.imshow(image)
plt.axis("off")
plt.subplot(1,2,2)
plt.imshow(outputarg)
plt.axis("off")
plt.subplots_adjust(wspace=0.05)
plt.show()

程序输出结果如下:

图像语义分割和目标检测(上)

下面展示一张图像中有不同目标实例的图像分割结果,程序如下所示:

image=PIL.Image.open("data/chap10/2012_004308.jpg")
image_tensor=image_transf(image).unsqueeze(0)
output=model(image_tensor)["out"]
outputarg=torch.argmax(output.squeeze(),dim=0).numpy()
outputrgb=decode_segmaps(outputarg,label_colors)
plt.figure(figsize=(20,8))
plt.subplot(1,2,1)
plt.imshow(image)
plt.axis("off")
plt.subplot(1,2,2)
plt.imshow(outputrgb)
plt.axis("off")
plt.subplots_adjust(wspace=0.05)
plt.show()

输出结果如下:

图像语义分割和目标检测(上)

Original: https://blog.csdn.net/mez_Blog/article/details/119949079
Author: mez_Blog
Title: 图像语义分割和目标检测(上)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/682601/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球