图像分割(segmentation)指的是将数字图像划分成多个图像子区域的过程。
在实际场景中具有诸多重要应用
在广义的图像分割中,传统方法和深度方法对于分割有不同的定义。
传统方法:对于图像进行区域划分,核心问题在于:区域间差异性、区域内相似性。本质上属于一个聚类问题
深度方法:对于图像进行像素级分类,核心问题在于:逐像素分类,本质上是一个分类问题
实际上,在深度方法中,对于语义分割又有更加细分的问题定义
语义分割:将前景与后景区分开来
实例分割:将不同的物体分类分割
所以图像分割也可以深入的细分为语义分割和实例分割
在传统方法时代,主要是基于初等图像特征对图像的像素进行划分,本质上,是对一簇像素进行合并的过程。
主要的思路包括:
阈值法根据不同的像素值等级,划分出不同的方法。代表性方法为直方图法
边缘法根据梯度进行区域划分。
区域法以像素为起点,不断合并周围像素成为更大的区域。代表性方法: 区域生长,分水岭算法
轮廓法设定一个初始轮廓,定义函数值对其进行优化逼近物体的真实轮廓。
图论法将区域视为一个整体,不断进行切割。直到切割不动了(满足阈值)。
区域法
区域生长算法
from skimage import data, segmentation, color
from skimage import graph
from matplotlib import pyplot as plt
img = data.coffee()
plt.imshow(img)
labels1 = segmentation.slic(img, compactness=30, n_segments=400,
start_label=1)
out1 = color.label2rgb(labels1, img, kind='avg', bg_label=0)
g = graph.rag_mean_color(img, labels1, mode='similarity')
labels2 = graph.cut_normalized(labels1, g)
out2 = color.label2rgb(labels2, img, kind='avg', bg_label=0)
fig, ax = plt.subplots(nrows=2, sharex=True, sharey=True, figsize=(6, 8))
ax[0].imshow(out1)
ax[1].imshow(out2)
for a in ax:
a.axis('off')
plt.tight_layout()
在像素图中,每个点和其他点的连线便是一个节点,将图去切分边,来做图像分割。如果不懂图论,可先学习数据结构图整章。
原图:
分割
原理
对于一张图像 I ∈ R M × N I \in \mathcal{R}^{M \times N} I∈RM×N,对任意两个像素点,都可以衡量其距离 d i j = w ( i , j ) d_{i j}=w(i, j) dij=w(i,j)
把图像定义成一个图结构,其中,每个节点都是一个像素,像素和像素之间的连线为边。
那么将图像进行分割的问题,就变成了如何将图进行拆分
然而,这种方式会使得较为边缘的区域被单独分割出来。(数据分布不均衡)
分割:让A图和B图尽可能的不相似,
缺点:把类比较散的同一类可能分割为多类
进行了改进,目前normalized cut算法改进了优化函数,提出了一种归一化距离的方式。
定义总体的距离损失为
数据集
coco数据集:20万张标注数据,150万个对象实例,171个类别
官网地址:coco
每个图都可当一个数据集。
human parsing dataset: 25403张图像,包含背景共59个类别
传送门:官网
可将人的图像解析出来。
如今可作为 智慧工地项目的数据基础,交通监控(KITT数据集也常用)
cityscapes: 30类,5000张细致标注数据,20000张精细标注数据
官网:https://www.cityscapes-dataset.com/
Cityscapes数据集的特点
像素级标注;
提供算法评估接口。
评价指标