【算法实现】Meanshift 求2d散点的密度最大处,点最密集处

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/github_36923418/article/details/84640908

【Python Meanshif】

参考来源http://www.chioka.in/meanshift-algorithm-for-the-rest-of-us-python/

这个参考链接是提供代码的,针对于用mean shift对2D点集 进行聚类,并返回聚类中心,那位大佬还对理论进行了较为详细的介绍,还有一些用相应API进行分割,聚类的说明,可以看看。

算法简介

1、meanshift 目前有几个比较常用的接口提供: Scikit-Learn,Opencv

2、meanshift 在追踪领域,聚类等都有着比较多的应用

3、本次主要介绍meanshift的算法逻辑,以及以及简单的实现方法:

      1)输入一堆2D点集记为X

      2)设置初始点坐标,建议选择,X的均值点记为x_mean,同时设置一个距离阈值,选择高斯函数作为权重核函数

      3)输入其实点位置iter_position,根据距离阈值求出所有近邻点N(X),然后根据如下公式求出这些点的带权中心

                                

      4)用求得的m(x)来更新iter_position,然后重复3) ,根据迭代次数限制,或者判断 m(x)与iter_position 距离变动大小来决定推出迭代,从而我们就得到了2d散点集合种,密度最大的位置,也就是点最密集的位置

实例说明:

       下图中黑色点表示 图中 黑色点为所有数据点,蓝色点为最开始初始化的位置,黄色点为5次迭代之后找到的密度最大位置。

                                                                            

实现:

#以下函数 主要来自于参考链接内容中的 大佬写的函数,输入数据是numpy array的2d点,shape like(30,2)
def mean_shift(data,iter_position):
    
    look_distance = 500  # 设置近邻点搜索阈值
    kernel_bandwidth = 25  # 设置权重函数(高斯)的一个阈值

    def euclid_distance(x, xi):  #求 两点之间的欧式距离
        return np.sqrt(np.sum((x - xi)**2))

    def neighbourhood_points(X, x_centroid, distance = 5): #求N(X)近邻点集合
        eligible_X = []
        for x in X:
            distance_between = euclid_distance(x, x_centroid)
            if distance_between <= distance:
                eligible_X.append(x)
        return eligible_X

    def gaussian_kernel(distance, bandwidth): #权重函数,对应到公式中的k(x-xi)
        val = (1/(bandwidth*math.sqrt(2*math.pi))) * np.exp(-0.5*((distance / bandwidth))**2)
        return val
    
    X = np.copy(data)
    n_iterations = 5  #迭代次数
    for it in range(n_iterations):
        neighbours = neighbourhood_points(X, iter_position, look_distance)
        #print(neighbours)
        numerator = 0.
        denominator = 0.
        for neighbour in neighbours:
            distance = euclid_distance(neighbour, iter_position)
            weight = gaussian_kernel(distance, kernel_bandwidth)
            numerator += (weight * neighbour)
            denominator += weight
        new_x = numerator / denominator
        iter_position=new_x
        
    return iter_position

 

展开阅读全文

说点MFC最基础的编程概念

02-10

最近学习MFC。至今天终有一点稍微宏观上的概念。rnrn以对话框的创建举例。rnrn比如我想创建一个对话框。思路是什么呢?rnrn第一步:我们在资源里面插入一个对话框 。rnrn插入之后应该正式资源。在程序并没有形成什么实质意义的代码。rnrn第二步: 由于在MFC中进行操作通常都是操作一个和资源对应的类完成的。rn所以我们创建一个类 。将鼠标移到到新建的对话框上面右击选择《添加类》rn这样在程序就有了一个类 这个类可以完全准确的描述我们插入的对话框。rn但是如果这个时候我们编译运行程序 是不会看到插入的对话框的。因为那只是一个rn类而不是一个对象。只有对象才能被人看到。rnrn第三步:如果想要看到那个对话框 我们需要将它实例化 rn比如:CTestDlg dlg; CTestDlg是我们根据对话框资源创建的类 dlg是这个类的实例rn实例中有一大堆成员函数 利用这些成员函数我么可以做很多事情 比如利用DoModal();该函数用于激活模态对话框。rn有必要说明的是CTestDlg dlg; dlg.DoModal();放置的位置。很多初学者对于函数该放置在什么位置rn该如何调用非常的茫然(当然我现在也比较茫然)。首先必须说明的这两行代码必然是放置在某一个函数体(假设为F1)内部,当这个F1被运行的时候 这两行代码也就会运行。rn至于这个F1怎么来就不是本帖的主题了。 不细说,举个例子 ,这个F1可以是某个的按钮的鼠标左键rn响应函数。rnrnrnrn罗罗嗦嗦说了这么多 只是把心中的想法梳理一下。对于不对我不是很清楚,放在这里算是抛砖引玉。rn请各位大神斧正。rn谢谢rnIDE是VS2010rn源代码如下:链接:http://yun.baidu.com/xcloud/csdn/pan/share/link?shareid=236613875&uk=2604484023 密码:imv4rnrnrn 论坛

没有更多推荐了,返回首页