Matlab - 为每个零矩阵元素查找最近的非零元素的索引
Matlab - Find indices of nearest non-zero element for every zero matrix element
在 Matlab 中,我有一个矩阵,其中一些元素设置为零。例如:
0 1 0 0 0
2 5 0 3 0
0 0 0 0 0
0 5 0 2 1
对于每个为零的矩阵元素,我想找到最近的非零元素的索引。当可能有多个索引时,应返回所有索引。这里有什么聪明的解决方案,我怎样才能避免很多 for 循环的东西?
有一个高效的bwdist
function in IPT that computes the 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
returned IDX
包含 线性索引 M
中最接近的非零值。每个元素只有 return 个索引。
这是一种使用 bsxfun
and mat2cell
的矢量化方法,它为每个单元格中的每个零元素存储非零最近元素的索引(按欧氏距离) -
%// 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
在 Matlab 中,我有一个矩阵,其中一些元素设置为零。例如:
0 1 0 0 0
2 5 0 3 0
0 0 0 0 0
0 5 0 2 1
对于每个为零的矩阵元素,我想找到最近的非零元素的索引。当可能有多个索引时,应返回所有索引。这里有什么聪明的解决方案,我怎样才能避免很多 for 循环的东西?
有一个高效的bwdist
function in IPT that computes the 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
returned IDX
包含 线性索引 M
中最接近的非零值。每个元素只有 return 个索引。
这是一种使用 bsxfun
and mat2cell
的矢量化方法,它为每个单元格中的每个零元素存储非零最近元素的索引(按欧氏距离) -
%// 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