避免使用sub2ind,ind2sub matlab

时间:2013-04-22 10:00:32

标签: matlab indexing computer-vision bsxfun

我需要在3d中的某个点附近访问几个索引。 例如,对于点(x1,y1,z1),我需要获得其3x3x3邻域的所有索引,使得(x1,y1,z1)居中。对于大小为3的社区,我是用

做的
 [x,y,z] = meshgrid(-1:1,-1:1,-1:1);
 x_neighbors = bsxfun(@plus,x,x1);
 y_neighbors = bsxfun(@plus,y,y1);
 z_neighbors = bsxfun(@plus,z,z1);

这里,我通过将(x1,y1,z1)的距离与3x3x3框中的任意点相加,将x1,y1,z1置于(0,0,0)。

给出了(x1,y1,z1)3x3x3邻域的坐标。然后我需要将它们变成线性索引,以便我可以访问它们:

 lin_ind = sub2ind(size(volume),y_neighbors,x_neighbors,z_neighbors);

这对我的工作来说代价很高。

我的问题是,如何避免sub2ind。如果inx是(x1,y1,z1)的线性指数,

inx = sub2ind(size(volume),y1,x1,z1);

如何通过添加或减法或任何其他简单的inx操作找到线性索引的3x3x3邻域?

2 个答案:

答案 0 :(得分:1)

只要您知道3D阵列的尺寸,就可以计算3x3x3邻域的所有元素的线性偏移。为了说明这一点,请考虑4x5矩阵的2D示例。线性指数如下所示:

1 5  9 13 17
2 6 10 14 18
3 7 11 15 19
4 8 12 16 20

10的3x3邻域是[5 6 7 9 10 11 13 14 15]。 15x的3x3邻域是[10 11 12 14 15 16 18 19 20]。如果我们减去中心元素的索引,在这两种情况下我们得到[-5 -4 -3 -1 0 1 3 4 5]。更一般地,对于MxN矩阵,我们将[-M-1 -M -M+1 -1 0 1 M-1 M M+1]或[(-M + [ - 1 0 1])-1 0 1(M + [ - 1 0 1])]

概括为三维,如果数组为MxNxP,则中心元素的线性索引偏移量为[(-M*N+[-M-1 -M -M+1 -1 0 1 M-1 M M+1]) [-M-1 -M -M+1 -1 0 1 M-1 M M+1] (M*N+[-M-1 -M -M+1 -1 0 1 M-1 M M+1])]。如果您愿意,可以将其重新整形为3x3x3。

请注意,这种索引不能很好地处理边缘;如果你想找到数组边缘元素的邻居,你应该首先在所有边上填充数组(从而改变M,N和P)。

答案 1 :(得分:0)

只需将(通用)代码添加到@nhowe答案: 这是大小为5X5X5的邻域的示例,因此r(半径)是2:

ns = 5;
r = 2;

[M,N,D] = size(vol);
rs = (1:ns)-(r+1);
% 2d generic coordinates:
neigh2d = bsxfun(@plus, M*rs,rs');
% 3d generic coordinates:
pages = (M*N)*rs;
pages = reshape(pages,1,1,length(pages));

neigh3d = bsxfun(@plus,neigh2d,pages);

获得任何线性索引vol的任何邻域,只需将线性索引添加到neigh3d:

new_neigh = bxsfun(@plus,neigh3d, lin_index);