转换下标和索引

Converting subsripts and indices

我很难用 ind2sub 和 sub2ind 弄清楚空间之间的转换。有人可以帮忙吗?问题如下:

我有一个掩码 Y(或感兴趣区域),其中体素值为 1 或零:Y=72x72x33 double.然后我找到所有值为 1 的体素(其中有 15 个),然后使用 ind2sub 获取这些体素的 x y z 坐标:

indx = find(Y>0);
[x,y,z] = ind2sub(size(Y),indx); 
XYZ = [x y z]'; 

因为有 15 个值为 1 的体素,我最终得到 XYZ=3x15 double,包含这 15 个体素的坐标,如下所示:

25 26 24 25 26 ...26
28 28 29 29 29 ...30
8  8  8  8  8  ...9

根据一些任意标准,我删除了 6 个体素,因此 XYZ 变成 3x9 double。我们称之为 new_XYZ。现在我想将此 new_XYZ 转换回掩码(我们称之为 new_Y)。我试过这个:

new_Y=sub2ind(size(Y),new_XYZ);

在这里,我可能对 sub2ind 做错了,因为 new_Y 没有给我预期的结果。尺寸也不是 72x72x33。旧面具是一个球体,所以我希望新面具接近球体。相反,我得到一条直线。有人可以帮我改造一下吗?

谢谢。

A.

您的方法有几处错误。详细地说,我将使用稍微小一点的示例数据集,但解释可以扩展到任何大小。

Y = randi(10,5,5,3)-5 ;

这将创建一个 5x5x3,其中包含从 -5 到 5 的随机整数(因此很有可能其中大约一半为正数 (>0)。

在我进一步讨论之前,您可以在矩阵的相同形状中直接获得您的条件掩码:

mask_positive_Y = Y>0 ;

>> whos mask_positive_Y
  Name                 Size             Bytes  Class      Attributes
  mask_positive_Y      5x5x3               75  logical

这为您提供了一个逻辑(布尔)数组,与您的矩阵大小相同,包含 0 (false) 和 1 (true),其中验证了您的条件 (Y>0).

如果您可以直接使用此蒙版,则无需来回使用 ind2subsub2ind。例如,执行 Y(mask_positive_Y) = NaN; 会将掩码指示的所有值替换为 NaN

既然要修改掩码(去掉一些点),可能还需要获取它们的索引,这时可以直接调用:

indx = find( mask_positive_Y ) ; %// will give the same result as: indx = find(Y>0);

现在假设您按照指定的方式获得索引,删除 6 个点并获得 new_XYZ 矩阵。重建面具的方法如下

ind2sub 给了你 3 个向量作为输出,并且足够正确,sub2ind 将期望 3 个向量作为输入(而不是像你那样的 3 列矩阵)。因此,在将 new_XYZ 发送到 sub2ind.

之前,您必须将其分解为 3 个向量
new_indx = sub2ind(size(Y), new_XYZ(:,1) , new_XYZ(:,2) , new_XYZ(:,3) );

但是不要忘记在 XYZ = [x y z]'; 时你确实转置了你的结果矩阵,所以在分解它之前确保你的 new_XYZ 也被转置回 new_XYZ = new_XYZ.' ;上面的代码行(或者只是发送 new_XYZ 的行而不是显示的列)。

顺便说一下,正确的 transpose shorthand 表示法是 .' (而不是简单的 'Complex conjugate transpose)。

现在这个 new_indx 只是 线性索引 的新向量,与您之前的 indx 同质。您已经可以使用它在掩码下分配值,但是如果您想要一个与矩阵形状相同的新掩码 Y,您必须更进一步:

new_Ymask = false( size(Y) ) ;  %// build an empty mask (false everywhere)
new_Ymask(new_indx) = true ;    %// assign true to the masked values

这将与您的初始矩阵 Y 大小相同,但也与我向您展示的第一个布尔掩码大小相同 mask_positive_Y