中层处理,不处理像素级别的了。
Segmentation
分割是为了找到主体,这样进行分析就更加容易了。
过分割:把一个完整的物体分成好几个
欠分割:把不同的物体分成一个了
图像分割的目标
超像素:把一个图中相似的地方都放到一起,每个区块中的语义相似,这样就不需要处理每个像素点,表达更加简洁。
Bottom-up process
利用底层像素的相似性进行连接。
Unsupervised(无监督的)
利用语义的相似性进行分割
人是Bottom-up和top-down结合,supervised 和unsupervised结合
Inspiration from psychology
指导思想是啥?
The Gestalt school:人是如何将这些东西分割到一组中去的,人感受群组的时候是整体大于部件的。
人感知首先是感知部件,然后部件组合起来能够感知到新的语义。分割的终极目标不仅仅是理解部件,还要理解整体的语义。
人为啥能感知呢?人会按照自己的理解进行分割,自上而下进行分割,一起综合进行理解,所以能够感知出更多的东西。部件大于整体。
Gestalt factors
哪些factors可以组合在一起?依据如下:
Grouping phenomena in real life
5 和 6 中间的到底是5楼还是6楼,因为这个东西无法让人类高效的群组。不能群组的东西又一些局限,可以群组的东西判断比较方便。
算法一:聚类
Segmentation as clustering
K-means聚类:
灰度:256
彩色:RGB
分别用灰度和彩色进行聚类的结果。
语义分割:只需要告诉我当前的位置是啥东西即可
实例分割:不仅要告诉是啥,还要告诉是这个类中的具体的哪个上面的pixel
通过增加更多的维度信息,加入坐标之后变成5维的信息之后,就可以把这个图进行更好的分割。
但是也有不好的问题,当时属于背景的信息就被分割成两个类了,因为这两个背景隔得太远,
优点是可以进行实例分割,缺点是可能会出现过分割。
K-Means for segmentation
pros:
- 简单
- 局部最优解
cons: - 内存需求
- 需要指定k
- 对初始结果非常敏感,就是初始条件对结果非常敏感(密度法、空间等距离划分)
⚠️不一定非得细化到每个方法都能敲出来,但是要知道都有哪些方法可以解决当前遇到的问题⚠️ - 模型假设问题(K-means 是以球型的形式是可以很好的聚类的,这是假设的前提,如果是橄榄形就不能用K-means 就可以用Gaussian进行)
算法二:mean shift
Mean shift clustering and segmentation
要找分布直方图的密度中心。
假设一个二维空间,现在想要判断这个图像的中心的位置,meanshift是统计这个区域里的所有点的重心,然后把这个蓝色框的中心移到这个重心(均值漂移),然后再在这个新的框中寻找重心,最后中心和重心重合就是要找的中心的位置。
可以使用图像上的像素然后给他一个框,利用mean shift每个像素都会到属于他的那个中心的位置就可以分隔开。(中心没有指定过,是自己飘过去的)
mean shift的结果:
Mean shift pros and cons
pros:
- 不需要假定球形的聚类
- 只有一个参数——窗框大小
能不能跨越局部的小的peak找到一个大范围的peak,可以理解为看的视野,视野小山峰就小,视野大就可以看到一个高峰,圈太小圈太大也不行 - 可以不去确定数量,不需要知道一共有多少个类
- 对噪点有鲁棒性
cons:
- 依赖于窗口大小
- 计算复杂
但是这个计算可以简化,原来是每个点都画个圆,现在是在上山的过程中往上走就不用自己在走了,就带着路过的点往上走,这样就可以不用一个个去找了(⚠️具体怎么实现???) - 对于高维特征处理的不太好
维度灾难:有一万个样本在一维空间中显得很密集,但是如果放在100万的维度里,点分布的十分分散,这样没有办法找到每个点的邻居了。(三维就是⚽️)
算法三:Images as graphs
边的权重在这里连线表示两个点的相似度。那么如何分割呢?
找一条边把整个图像切开,希望找到的那些切割边之和是最小的,相似性最小的那些边被断开了,剩下的相似的像素就留在了一起。
相似性的衡量
dist是对两个像素的相似性的衡量(距离),sigma是对相似性的衡量,上面的整个公式叫做相似性。
sigma的影响
sigma是在调整在聚类的时候多远的距离会被聚成一类。
Graph cut(图割)
什么样是一个好的分割?
标准的图割方法有什么问题呢?
会趋向于把一些单独的点单独分割出来,会割出很多细小的区域,这种方法一般不使用。
常用方法
真正用的方法是归一化的图割,w(A,B)是切完之后A和B集合之间的联系,A和B之间有连接关系的总的权重求和,原来的最小割就是使w(A,B)最小。A和B之间割出来的边V占总的边数A/B的比例。这样能够避免把A切成一个像素,B是一组或者B切成一个像素A是一组。
操作步骤(coding)
- 先定义一个w矩阵,定义一个相关度矩阵,就是一个邻接矩阵,自己和自己为0,其余的都是两个点之间的similarity。(是一个对称矩阵)
【sigma、distance、向量表示】 - D是一个对角矩阵,每一行的元素相加
- y是一个像素的向量,里面存的是例如0,1,2。。。之类的表示每个点属于哪个类别。
- 求解要使中间的表达式最小的y向量 ,求解出的结果就是要分割的那条边
第二小的特征值进行求解,因为第一小的特征值是0,要求的是第一个非0的。
可能要对计算得到的y确定一个门限来判断属于哪一类。
- 特征表示
- 距离选择
- sigma设定
- w求解
门限的确定方法:可以把求出的每一个Y代回到原来的表达式中求解出每个都求出一个值,找到最小的那个作为设定的门限进行求解。
现在已经分成两类了,继续分割可以通过:
- 迭代计算
- K-means分类,因为已经有好多的向量了
这里面其实求出了按照不同的特征值进行分类得到的结果是不同的,可以对这些分割方法进行聚类,相似的分割方法聚集到一起。
分割结果
Challenge
每个像素定义一个特征表示:
前面的特征向量使用的是RGB和XY坐标进行表示,其实纹理的向量还可以用滤波器组来表示。现在一个像素变为一个48维的向量,在第一步的时候可以表示车给纹理的分类结果。
但是纹理取点的时候会有一些问题,比如下面的鹰,????的边缘的地方都是一边深一边前,而内部都是同一个颜色,所以会把这两个东西分成两类。解决方法:去找这个东西的轮廓看是否这两个东西是一个套在另一个里面,如果是的话直接把它delete掉就好了,把二者合并成一类。
Normalized cuts:Pro and con
pro:
- 可以用各种各样的特征来进行计算
con:
- 计算好复杂,矩阵存储很大
- 每个都趋向于让这两个类别大小相同,因为那个公式A和B两个部分都不能太大