3

我需要访问 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);

在这里,我通过添加从 ( , , ) 到 3x3x3 框中任意点的距离来x1y1、、居中。z1x1y1z1

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);

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

4

2 回答 2

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]. 15 的 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])]

推广到三个维度,如果数组是Mx Nx 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。

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

于 2013-04-24T01:29:51.840 回答
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);
于 2013-04-30T07:08:04.560 回答