1.J-Linkage算法的简介
J-Linkage算法是一种自底向上的一种层次聚类的算法,当然还有很多评价每个聚类距离的算法,例如simple linkage, complete linkage and average linkage,这些感兴趣的小伙伴可以自己查阅相关的资料。
原文题目’Robust Multiple Structures Estimation with J-linkage’。以论文中的例子说明算法要达到的效果:
这里就以三维点的平面拟合进行举例分析
我们的目标是要拟合出三维空间点对应的三个平面,能实现该功能的算法也有不少,这里介绍下J-linkage算法是如何实现的,介绍J-linkage算法之前,需要了解Ransac算法的原理,具体内容可参考LZ的另外一篇文章http://blog.csdn.net/felaim/article/details/76422803,或者这一篇http://grunt1223.iteye.com/blog/961063。
其实思想也很简单:ransac算法是要找到样本数据中满足某种模型的最大数据集合。这里的最大是指集合的数据个数。J-linkage算法是要找到多个数据集合,以上图为例,目的是要找到3个数据集合,每个数据集合能拟合出一个平面。
首先提出一个定义:(Jaccard distance)给定两个集合A和B,the jaccard distance是
dJ(A,B)=|A⋃B|−|A⋂B||A⋃B|
jaccard distance评价了两个集合的重叠程度,范围是从0(同一个集合)到1(完全独立的集合),这里截止的值被设为1,这也就意味着算法把有重叠部分的preference set(PS) link起来。所以聚类的点有以下两个性质:
(1)对于每个聚类,至少存在一个模型包含所有在PS的点(i.e.,一个可以拟合所有数据的模型)
(2)一个模型不可能存在于PS中两个不同聚类的点集(否则他们就会被link)。
每个聚类的点定义至少一个模型,如果更多的模型拟合一个聚类的所有点,那么他们肯定很相似。最后利用最小二乘算法估计每个聚类的模型。
异常点会融合成比较小的聚类,通常情况下,会根据不同的应用,可以设置不同的阈值。如果异常点所占的百分比是已知的或者是可以估计的(正如RANSAC假设的一样),我们是可以拒绝所有最小的聚类直到把异常点全部剔除。
J-linkage算法的流程是:
输入:数据点的集合,每个点被表示成它的preference set(PS)
输出:属于相同模型的点集的聚类
(1)把每个点看成是自己的一个聚类;
(2)把PS的一个聚类定义为其点的PS的交集;
(3)在所有的聚类中,在各自PS中,选择两个Jaccard distance最小的聚类,计算其模型参数;
(4)合并这两个模型,并重新计算得到最小Jaccard距离的两模型;
(5)重复3~4过程,知道最小Jaccard距离为1为止。
算法最终得到若干个分类,有些分类属于弱分类,就是说集合内的样本个数太少,不能算是一类,本例只要取前3个分类结果即可,这3个分类结果的样本数量也是最多的3类。
2.具体算法的实现理解
程序首先输入的是三维点云的坐标(X,Y,Z),将三维数据可视化如下图所示:
% Generate an exponential Cumulative distribution function(cdf)
% needed to generate a non-uniform sampling
[nearPtsTab] = calcNearPtsTab(CastelVecchio, 'exp', sigmaExp);
% Generate Hypothesis(random sampling)
[totm, totd] = generateHypothesis(CastelVecchio, @getfn_plane, @distfn_plane, @degenfn_plane, 3, 4, 100,numberOfTrials, nearPtsTab);
% Perform J-Linkage clusterization
[T, Z, Y, totdbin] = clusterPoints(totd, inliersThreshold);
因为主要考虑的J-Linkage的算法,所以直接说最后的那一行代码吧
function [T, Z, Y, totdbin] = clusterPoints(totd, inliersThreshold)
#先按照设定的阈值把PS映射到只有{0, 1}的空间集合中
corM = find(totd < inliersThreshold);
totdbin = false(size(totd));
totdbin(corM) = true;
#计算jaccard distance
Y = pDistJaccard(totdbin');
#对每个聚类进行连接相交
Z = linkageIntersect(Y, totdbin);
#最后进行聚类
T = cluster(Z,'cutoff',1-(1/(size(totdbin,1)))+eps,'criterion','distance');
最后就得到了博客一开始放的那张效果图,先说这么多啦O(∩_∩)O哈哈~
参考文献:
[1]Toldo R, Fusiello A. Robust Multiple Structures Estimation with J-Linkage[C]// European Conference on Computer Vision. Springer-Verlag, 2008:537-547.