如何在MATLAB中仅对多维数组中的某些维使用逻辑条件

时间:2016-09-27 14:38:51

标签: matlab multidimensional-array

让我们有一个4D矩阵(张量),output

[X,Y,Z] = ndgrid(-50:55,-55:60,-50:60);
a = 1:4;
output = zeros([size(X),length(a)]);

接下来,我们确定椭圆体内的区域:

position = [0,0,0];
radius = [10,20,10];
test_func = @(X,Y,Z) ((X-position(1))/radius(1)).^2 ...
            + ((Y-position(2))/radius(2)).^2 ...
            + ((Z-position(3))/radius(3)).^2 <= 1;

condition = test_func(X,Y,Z);

我需要填充椭圆体内的矩阵output以获得前3个维度。但是对于第四个维度,我需要填充a。我需要做这样的事情:

 output(condition,:) = a;

但它不起作用。怎么做?请任何想法!

1 个答案:

答案 0 :(得分:3)

如果我正确理解你的问题,你有一个4D矩阵,其中每个4D切片的每个3D像素的时间blob都填充了一个数字......从1到4,其中每个数字告诉你哪个切片#39 ;重新进入。

您可以巧妙地使用bsxfunpermute来帮助您完成此任务:

output = bsxfun(@times, double(condition), permute(a, [1 4 3 2]));

这需要一些想象力来想象它是如何工作的,但它很简单。 conditionlogical值的3D数组,其中此3D空间中的每个位置如果不是0则为1,如果它属于某个点,则为a在椭圆体里面。 N是1到4之间的行向量,或者您想要以此结尾的多个元素。让我们称这个permute(a, [1 4 3 2])更为通用。

bsxfun改变尺寸,使得我们创建一个4D向量,其中我们有1行,1列和1个切片但是我们有4个元素进入第四维。

在这方面使用condition,它在两个输入上执行自动广播,其中输出数组中的每个维度将匹配两个输入中具有最大值的任何一个。条件是,对于每个维度,它们应该匹配,或者其中一个是单个维度(即1)。

因此,对于您的特定示例,106 x 116 x 111将为permute,而1 x 1 x 1 x N操作的输出将为condition106 x 116 x 111 x 1在技术上也是bsxfun并使用106 x 116 x 111 x N,因此我们会得到一个大小为@times的输出数组。执行逐元素a操作时,置换向量i将在所有维度广播本身,其中每个3D切片i将包含值{{ 1}}。然后,condition矩阵将在第四维上复制,因此我们拥有N矩阵的condition个副本,并执行逐元素乘法,从而完成您所需的内容。这是可行的,因为您创建的logical掩码仅包含0和1。通过将元素与此掩码相乘,只有值为1的值才会记录更改。具体来说,如果将这些位置的值乘以任何非零值,它们将更改为这些非零值。使用此逻辑,您希望生成这些值a。值得注意的是,我必须将condition转换为double,因为bsxfun仅允许使用相同类/数据类型的两个输入。

为了直观地看到这是正确的,我将显示每个blob的散点图,其中每个blob的颜色将表示它所属的a中的标签:

close all;
N = 4;
clrs = 'rgbm';
figure;
for ii = 1 : N
    blob = output(:,:,:,ii);
    subplot(2,2,ii);        
    plot3(X(blob == ii), Y(blob == ii), Z(blob == ii), [clrs(ii) '.']);
end

我们得到:

enter image description here

请注意,每个椭圆体的空间范围相同,但不同的是分配给每个斑点的颜色。我已经确定第一个blob的值或分配给a = 1的值为红色,分配给a = 2的值分配为绿色,a = 3为蓝色最后a = 4到洋红色。

如果您确定要确保每个blob的坐标在所有blob中相等,则可以在每个3D blob中单独使用find并确保非零索引全部相等:

inds = arrayfun(@(x) find(output(:,:,:,x)), a, 'un', 0);
all_equal = isequal(inds{:});

代码在每个blob中找到3D中所有非零位置的列主要索引。要知道我们是否正确,每个3D blob都应包含相同的非零列主要索引。 arrayfun调用遍历每个3D blob并返回一个单元格数组,其中每个单元格元素是特定blob的列主要索引。然后我们将其传递到isequal以确保所有这些列主索引数组都相等。我们得到:

>> all_equal

all_equal =

     1