Mean shift聚类

1.原理简介:

   与K-Means算法不一样的是,Mean Shift算法可以自动决定类别的数目。与K-Means算法一样的是,两者都用集合内数据点的均值进行中心点的移动。

  Mean shift算法本质是一个迭代的过程,那么这个算法的最终效果是什么呢?或者说这个算法能做什么事情?它能够在一组数据的密度分布中寻找到局部极值,它比较稳定,而且是无参密度估计(它不需要事先知道样本数据的概率密度分布函数,完全依靠对样本点的计算),而且它在采样充分的情况下,一定会收敛,即可以对服从任意分布的数据进行密度估计。

  均值漂移聚类目的是发现一个平滑密度的样本点。它是一种基于质心的算法,其工作原理是将质心的候选点更新为给定区域内的点的平均值。然后在后处理阶段对这些候选点进行过滤,以消除近似重复点,形成最终的一组质心。给定一个候选质心xi和迭代次数t,按照以下的等式进行更新:xit+1=m(xit)

  其中N(xi)是在xi周围给定距离内的样本的邻域,m是针对指向点密度最大增长区域的每个质心计算的平均位移向量。使用以下公式进行计算,能有效地更新一个质心为其邻域内样本的平均值:m(xi)=∑xj∈N(xi)K(xj−xi)xj∑xj∈N(xi)K(xj−xi)

       

 

    以二维来说明,上图中的很多的红点就是我们的样本特征点,meanshift就是在这些点中的任意一个点为圆心,然后以半径R画一个圆,然后落在这个圆中的所有点和圆心都会对应的一个向量,把所有这些向量相加(注意是向量相加),最终我们只得到一个向量,就是下图中用黄色箭头表示的向量,这个向量就是meanshift向量。

  Mean Shift算法的流程可被理解为:

  1. 计算每个样本的平均位移
  2. 对每个样本点进行平移
  3. 重复(1)(2),直到样本收敛
  4. 收敛到相同点的样本可被认为是同一簇类的成员
  5. ## Mean Shift算法的优缺点
  6. 不需要设置簇的个数也可以处理任意形状的簇类,同时算法需要的参数较少,且结果较为稳定不需要像K-means的样本初始化。但同时Mean Shift对于较大的特征空间需要的计算量非常大,而且如果参数设置的不好则会较大的影响结果,如果bandwidth设置的太小收敛太慢,而如果bandwidth参数设置的过大,一部分簇则会丢失。

2.Mean shift应用

  Mean shift的这种思想可以应用于目标跟踪、图像平滑、边缘检测、聚类等,是一种适应性很好的算法,缺点是速度非常慢。

1.简单聚类

  在常用的聚类算法中,有一种DBSCAN是基于密度的聚类,密度是概率密度的狭义表示,因此mean shift用于聚类就有些类似于密度聚类,从单个样本点出发,找到其对应的概率密度局部极大点,并将其赋予对应的极大点,从而完成聚类的过程(通常还要对得到的极大点进行一定的后处理,比如将较近的极大点进行合并等)。其权重可以简单的选取高斯核函数。  

2.图像分割

  图像分割的本质也是聚类,不过相对与简单聚类,图像分割又有其特殊性。mean shift通过对像素空间进行聚类,达到图像分割的目的。

  图像平滑的目的是减高频保低频,去细节保边缘,因此,图像分割(当用概率密度极大点的颜色特征作为分割区域的颜色特征时)可以看作是图像平滑过度的结果。而迭代的次数和选取的核函数(主要为带宽)控制了图像平滑的程度。因此,对于一般的图像平滑任务,由于需要保证足够多的细节信息,因此通常迭代一次即可。至于选取的核函数,就见仁见智了。

3.图像平滑

  图像平滑和图像分割有异曲同工之妙,同样是对每一个像素点寻找其对应的概率密度极大点,主要区别在于:
  a.迭代过程不用深入,通常迭代一次即可;
  b.找到概率密度极大点后,直接用其颜色特征覆盖自身的颜色特征。

4.轮廓提取

  轮廓提取与图像分割也是类似的,或者具体地说,轮廓提取可以基于图像分割进行。首先使用mean shift 算法对图像进行分割,然后取不同区域的边缘即可得到简单的轮廓。

5.目标跟踪

  基于图像的目标跟踪,处理框架一般是:a. 目标区域建模,b. 候选区域表示,c. 相似性度量。

  运动跟踪说到底就是在一开始告诉程序一个跟踪目标,即我想跟踪什么,然后程序就在接下来的视频帧中去寻找这个目标了。给定跟踪目标很简单,直接在图像中给一个ROI(感兴趣区域)给程序就可以了,那么程序接下来要做的就是在下一帧图像中去找这个ROI,但这个ROI是移动了的,已经不在之前的那个位置了,那么这个时候程序要怎么来找到这个ROI呢?那么在计算机视觉中我们是这么来解决的:首先对跟踪目标进行描述,这个描述是将跟踪目标区域转换为颜色HSV空间,然后得到H的这个通道的分布直方图,有了这个描述之后,我们就是要在下一个视频帧中找到和这个描述的一样的区域,但是我们知道要找到完全一样的区域很难,所以我们就用了一个相似函数来衡量我们找到的区域和我们的目标区域的相似度,通过这个相似函数,相似函数值越大说明我们找打的区域和目标区域越相似,所以我们的目标就是要找这个对应最大相似值的区域,那么怎么来找呢?这个时候meanshift就排上用场了,它可以通过不断地迭代得到有最大相似值的区域(具体里面的是怎么算的,可以参考博文地底下的参考博客),meanshift的作用可以让我们的搜索窗口不断向两个模型相比颜色变化最大的方向不断移动,直到最后两次移动距离小于阈值,即找到当前帧的位置,并以此作为下一帧的起始搜索窗口中心,如此重复,这个过程每两帧之间都会产生一个meanshift向量,整个过程的meanshift向量连起来就是目标的运动路径。

3.代码实例

 1 # 导入相关模块和导入数据集
 2 import numpy as np
 3 from sklearn.cluster import MeanShift, estimate_bandwidth
 4 from sklearn.datasets import make_blobs
 5 # 生成样本数据
 6 centers = [[1, 1], [-1, -1], [1, -1]]
 7 X, _ = make_blobs(n_samples=10000, centers=centers, cluster_std=0.6)
 8 es_bandwidth = estimate_bandwidth(X,quantile=0.2, n_samples= 500)
 9 '''
10 estimate_bandwidth()用于生成mean-shift窗口的尺寸,
11 其参数的意义为:从X中随机选取500个样本,
12 计算每一对样本的距离,然后选取这些距离的0.2分位数作为返回值
13 '''
14 MS = MeanShift(bandwidth=es_bandwidth)
15 MS.fit(X)
16 labels = MS.labels_
17 cluster_centers = MS.cluster_centers_
18 uni_labels = np.unique(labels)
19 n_clusters_ = len(uni_labels)
20 import matplotlib.pyplot as plt
21 from itertools import cycle
22 # 对算法聚类结果进行可视化
23 colors = cycle('bgrcmykbgrcmykbgrcmykbgrcmyk')
24 for k, col in zip(range(n_clusters_), colors):
25     my_members = labels == k
26     cluster_center = cluster_centers[k]
27     plt.plot(X[my_members, 0], X[my_members, 1], col + '.')
28     plt.plot(cluster_center[0], cluster_center[1], 'o', markerfacecolor=col,
29              markeredgecolor='k', markersize=14)
30 plt.show()

 

参考链接:  meanshift算法通俗讲解_first_adam的博客-CSDN博客_meanshift算法通俗讲解

      均值偏移( mean shift )? - 知乎 (zhihu.com)

posted @ 2022-03-25 11:55  hungry_J  阅读(106)  评论(0)    收藏  举报