【问题标题】:Grouping of points using Triangulation使用三角剖分对点进行分组
【发布时间】:2015-06-12 12:55:50
【问题描述】:

语言:MATLAB

问题防御:

我在空间中有一组二维点。我想根据欧几里得距离对点进行分组。我的数据有一个属性,即两组总是至少被 R 个单位分开。因此对于一个给定的点,所有接近 50 个单位的点都可以被认为是它的邻居。组合具有共同邻居的点将产生组(至少是这个想法)。

建议方法:

在 matlab 中使用 delaunay 三角剖分并获取生成的三角形的边列表。删除所有大于 R 个单位的边。剩下的每一组点都是我正在寻找的组。剩余的未连接点可以忽略。

尝试: 我试图在 MATLAB 中实现上述内容,但在对剩余点进行分组时犯了一个错误。我附上我的代码。

DT      = delaunayTriangulation(double(frame(:,1:2)));
edgeList   = edges(DT);

edgeVertex1 = frame(edgeList(:,1),:); 
edgeVertex2 = frame(edgeList(:,2),:); 

dVec = edgeVertex1 - edgeVertex2;
edgeLengths = sqrt(sum(abs(dVec).^2,2));
requiredEdges = edgeLengths < NEIGH_RADIUS;

edgeLengthsFiltered = edgeLengths(requiredEdges);
edgeListFiltered = edgeList(requiredEdges,:);

% Clustering
edgeOrigins = edgeListFiltered(:,1);
edgeEndings = edgeListFiltered(:,2);
nodeList = unique(edgeOrigins);

if isempty(nodeList)
    Result = struct([]);
    super_struct(i).result = Result;
else
    groups = cell(10,1);
    groups{1} = nodeList(1);
    groupLength = 2;
    flag = 0;

    % grouping
    for j = 1:1:length(nodeList);
        neighbourList = [nodeList(j); edgeEndings(edgeOrigins==nodeList(j))];
        % add current node as part of neighbourList
        for k = 1:1:groupLength-1
           te =  ismembc(groups{k}, neighbourList);
           if sum(te) ~=0
                temp = sort([groups{k}; neighbourList]);
                groups{k} = temp([true;diff(temp(:))>0]);
                flag = 1;
                break;
            end
        end

        if ~flag
            groups{groupLength} = neighbourList;
            groupLength = groupLength + 1;
        end

        flag = 0;
    end

    largeGroups = cell(1,1);
    largeGroups_c = 1;
    for j = 1:1:groupLength -1;
        if ~ isempty(groups{j})

        for k = j+1:1:groupLength - 1
            te = ismembc(groups{j}, groups{k});
            if sum(te) ~= 0
                temp = sort([groups{j}; groups{k}]);
                groups{j} = temp([true;diff(temp(:))>0]);
                groups{k} =[];
            end    
        end

        % ignore small groups
        if length(groups{j}) > MIN_PTS_IN_GROUP
            largeGroups{largeGroups_c} = groups{j};
            largeGroups_c = largeGroups_c+1;
        end

        end
    end

在上面的代码中,frame 是具有点列表的变量。常量NEIGH_RADIUS 代表问题中的R。另一个常量MIN_PTS_IN_GROUP 是用户定义的,用于选择将其视为感兴趣集群所需的最小点数。

当我运行上述代码时,仍然存在单组点仍表示为多组的情况。

红线与上面代码所标识的单个组相邻。显然存在错误的交叉组。

问题 1 有人可以提出更好(和正确)的分组方式吗?

问题 2 任何其他比三角测量更快地获得组的替代方法也会很棒!

提前谢谢你

【问题讨论】:

  • 你提前知道有多少组吗?
  • 没有。组数未知。
  • 构建长度小于R的边图,通过this answer获取连通分量。
  • @knedlsepp 你的建议奏效了。谢谢你。获得连接的组件是我真正想要的。我也对解决问题的替代方法感兴趣(即不使用三角测量)。
  • 也许你可以通过只使用以下边缘来加速它:edges = knnsearch(frame,frame,'K',2) 而不是 delaunay-edges。然而,就计算复杂性而言,您的 delaunay 方法应该已经相当不错了。

标签: matlab nearest-neighbor delaunay


【解决方案1】:

如果你知道你搜索的组数,你可以使用matlab统计工具箱中的kmeans函数或者你可以在matlab交换中找到其他的实现(kmeans clustering

【讨论】:

  • 就我而言,我不知道我手头有多少个集群/组。
猜你喜欢
  • 2017-12-26
  • 1970-01-01
  • 2011-07-15
  • 2016-04-21
  • 1970-01-01
  • 2015-07-23
  • 2019-10-05
  • 2016-09-27
  • 2016-09-28
相关资源
最近更新 更多