我需要访问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邻域?
只要知道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]
。15的3x3邻域是[10 11 12 14 15 16 18 19 20]
。如果我们减去中心元素的索引,在这两种情况下,我们得到[-5 -4 -3 -1 0 1 3 4 5]
。更一般地说,对于M
x N
矩阵,我们将得到[-M-1 -M -M+1 -1 0 1 M-1 M M+1]
或[(-M+[-1 0 1]) -1 0 1 (M+[-1 0 1])]
。
推广到三维,如果数组为M
x N
x P
,则从中心元素的线性索引偏移量为[(-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
)。
只是添加(广义)代码到@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的任意线性指标的任意邻域,只需将线性指标加到neighbor3:
new_neigh = bxsfun(@plus,neigh3d, lin_index);