使用三角测量对点进行分组

时间:2015-04-07 19:38:15

标签: matlab nearest-neighbor delaunay

语言:MATLAB

问题定义:

我在太空中有一组2D点。我想根据他们的欧氏距离对点进行分组。我的数据有一个属性,即两个组总是至少相隔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是用户定义的,用于选择将其视为感兴趣的簇所需的最小点数。

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

Result of running my grouping algorithm

红线与上面代码所标识的单个组相邻。显然,有交叉的群体是错误的。

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

问题2 任何其他比Triangulation更快获得组的替代方法也会很棒!

提前谢谢

1 个答案:

答案 0 :(得分:0)

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