【问题标题】:Matlab - Find indices of nearest non-zero element for every zero matrix elementMatlab - 为每个零矩阵元素查找最近的非零元素的索引
【发布时间】:2023-04-09 10:25:01
【问题描述】:

在 Matlab 中,我有一个矩阵,其中一些元素设置为零。例如:

0 1 0 0 0
2 5 0 3 0
0 0 0 0 0
0 5 0 2 1

对于每个为零的矩阵元素,我想找到最近的不为零的元素的索引。如果可能有多个索引,则应返回所有索引。这里有什么聪明的解决方案,我怎样才能避免很多 for 循环的东西?

【问题讨论】:

  • diff 可能会有所帮助。
  • 最近是什么意思?垂直、水平、对角线?
  • @dean_sh:应该考虑您列出的所有方向。
  • 很好奇,发布的解决方案是否适合您?
  • @Divakar:接受 Amro 的回答,因为它很简单,但我也喜欢你的回答。学习如何从头开始实现类似的东西总是有用的。

标签: matlab matrix nearest-neighbor


【解决方案1】:

在 IPT 中有一个高效的 bwdist function 计算 distance transform

M = [
    0 1 0 0 0
    2 5 0 3 0
    0 0 0 0 0
    0 5 0 2 1
];
[D,IDX] = bwdist(M~=0)

结果:

D =
    1.0000         0    1.0000    1.0000    1.4142
         0         0    1.0000         0    1.0000
    1.0000    1.0000    1.4142    1.0000    1.0000
    1.0000         0    1.0000         0         0

IDX =
           2           5           5          14          14
           2           6           6          14          14
           2           6           6          14          20
           8           8           8          16          20

返回的IDX 包含M 中最接近的非零值的线性索引。每个元素只返回一个索引。

【讨论】:

  • 距离变换是解决这个问题的第一选择......特别是因为它有非常有效的实现,而不是蛮力。来自我的 +1。
【解决方案2】:

这是一种使用bsxfunmat2cell 的矢量化方法,它为每个单元格中的每个零元素存储非零最近元素的索引(按欧几里德距离)-

%// Assuming A as the input matrix. Store rows, columns of zero and non-zeros
[rz,cz] = find(A==0);
[rnz,cnz] = find(A~=0);

%// Store zero pt indices
zero_pts = [rz cz];

%// Get squared euclidean distances
dists = bsxfun(@minus,rnz,rz.').^2 + bsxfun(@minus,cnz,cz.').^2;

%// Get all nearest XY indices of nonzeros for each zero pt
[R_idx,C_idx] = find(bsxfun(@eq,min(dists,[],1),dists));
idx = [rnz(R_idx) cnz(R_idx)];

%// Cut at each shifting positions and thus create a cell array, with a
%// cell of indices of non-zero nearest elements for each zero element 
nearest_nnonzero_pts = mat2cell(idx,histc(C_idx,1:max(C_idx)))

样本输入、输出-

输入:

>> A
A =
     0     1     0     0     0
     2     5     0     3     0
     0     0     0     0     0
     0     5     0     2     1

输出(零分):

>> disp(zero_pts)
     1     1
     3     1
     4     1
     3     2
     1     3
     2     3
     3     3
     4     3
     1     4
     3     4
     1     5
     2     5
     3     5

输出(对应最近的非零点):

>> celldisp(nearest_nnonzero_pts)
nearest_nnonzero_pts{1} =
     2     1
     1     2
nearest_nnonzero_pts{2} =
     2     1
nearest_nnonzero_pts{3} =
     4     2
nearest_nnonzero_pts{4} =
     2     2
     4     2
nearest_nnonzero_pts{5} =
     1     2
nearest_nnonzero_pts{6} =
     2     2
     2     4
nearest_nnonzero_pts{7} =
     2     2
     4     2
     2     4
     4     4
nearest_nnonzero_pts{8} =
     4     2
     4     4
nearest_nnonzero_pts{9} =
     2     4
nearest_nnonzero_pts{10} =
     2     4
     4     4
nearest_nnonzero_pts{11} =
     2     4
nearest_nnonzero_pts{12} =
     2     4
nearest_nnonzero_pts{13} =
     4     5

【讨论】:

    猜你喜欢
    • 2014-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多