在Matlab中找到距离矩阵中一组点的最接近匹配距离

时间:2013-07-07 00:46:56

标签: matlab distance vectorization template-matching

我有M个平面之间的测量角度矩阵

 0    52    77    79
52     0    10    14
77    10     0     3
79    14     3     0

我有一个平面之间已知角度的列表,这是一个N-by-N矩阵,我将其命名为rho。这是它的一个子集(它太大而无法显示):

 0    51    68    75    78    81    82
51     0    17    24    28    30    32
68    17     0     7    11    13    15
75    24     7     0     4     6     8
78    28    11     4     0     2     4
81    30    13     6     2     0     2
82    32    15     8     4     2     0

我的任务是找到rho角度最接近测量角度的M个平面集。 例如,上面所示平面的测量角度相对接近平面1,2,4和6之间的已知角度。

换句话说,我需要在距离矩阵(使用与余弦相关的距离)中找到一组点,这些点与我测量的一组距离相匹配。这也可以被认为是将模式与模具匹配。

在我的问题中,我有M = 5和N = 415。

我真的试图绕过它,但已经没时间了。因此,目前我使用最简单的方法:迭代3个平面的每个可能组合,但这很慢,目前仅针对M = 3编写。然后我返回一个按匹配分数排序的匹配平面列表:

function [scores] = which_zones(rho, angles)
    N = size(rho,1);
    scores = zeros(N^3, 4);
    index = 1;
    for i=1:N-2
        for j=(i+1):N-1
            for k=(j+1):N
                found_angles = [rho(i,j) rho(i,k) rho(j,k)];
                score = sqrt(sum((found_angles-angles).^2));
                scores(index,:)=[score i j k];
                index = index + 1;
            end
        end;
    end
    scores=scores(1:(index-1),:); % was too lazy to pre-calculate #
    scores=sortrows(scores, 1);
end

我有一种感觉pdist2可能有所帮助,但不确定如何。我很感激任何帮助来解决这个问题。

1 个答案:

答案 0 :(得分:1)

最近的点搜索有http://www.mathworks.nl/help/matlab/ref/dsearchn.html,但这需要相同的维度。我认为你无论如何都必须发现它,因为它只是一个特殊的问题。

这是一种通过强制迭代第二个矩阵的所有独特组合并计算score的方法,之后您可以找到具有最低分数的那个。

A=[ 0    52    77    79;
   52     0    10    14;
   77    10     0     3;
   79    14     3     0];
B=[ 0    51    68    75    78    81    82;
   51     0    17    24    28    30    32;
   68    17     0     7    11    13    15;
   75    24     7     0     4     6     8;
   78    28    11     4     0     2     4;
   81    30    13     6     2     0     2;
   82    32    15     8     4     2     0];

M = size(A,1);
N = size(B,1);

% find all unique permutations of `1:M`
idx = nchoosek(1:N,M);
K = size(idx,1); % number of combinations = valid candidates for matching A

score = NaN(K,1);
idx_triu = triu(true(M,M),1);
Atriu = A(idx_triu);

for ii=1:K
    partB = B(idx(ii,:),idx(ii,:));
    partB_triu = partB(idx_triu);
    score = norm(Atriu-partB_triu,2);
end

[~, best_match_idx] = min(score);
best_match = idx(best_match_idx,:);

您的示例的解决方案实际上是[1 2 3 4],因此B的上半部分而不是[1 2 4 6]

理论上这可以解决你的问题,我不知道如何更快地制作这个算法。但对于大数字来说,它仍然会很慢。例如,对于M=5N=415的情况,100 128 170 583的{​​{1}}组合是可能的解决方案;只是生成选择器索引在32位是不可能的,因为你无法全部解决它们。

我认为这里的真正优化在于切掉前面过滤部分中B矩阵中的一些平面。