通过 matlab/octave 中的二维索引访问 3 维矩阵
Accessing 3-dimensional matrix by a 2-dimensional index in matlab/octave
我有一个 3 维矩阵(第 3 维表示 M x N
灰度图像的多个副本)。
我取图像中每个像素的最大值,得到一个 max_val
和 max_ix
矩阵 (2x2)。
我想通过 max_ix
值引用原始 test
矩阵。
示例:my_max_val = test(max_ix,:)
应等于:
5 1
1 1
显然我可以在这个简化的示例中使用 max_val
,但不能在实际用例中使用。我正在改变 max_ix
,所以我需要通过我创建的新索引值(未在此简化示例中描述)来引用原始 3 维矩阵。
>> test
test(:,:,1) =
1 1
1 1
test(:,:,2) =
1 1
1 1
test(:,:,3) =
5 1
1 1
test(:,:,4) =
1 1
1 1
>> [max_val, max_ix] = max(test, [], 3)
max_val =
5 1
1 1
max_ix =
3 1
1 1
如何仅从 test
和 max_ix
重新创建 max_val
?
这是一种方法。
%// Generate matrix test
test = randi(50,4,4,4);
%// Get maximum value and indices
[max_val, max_ix] = max(test, [], 3);
%// We don't know the size in general so this is the Cartesian product
[y, x] = meshgrid(1:size(test, 1), 1:size(test,2));
%// sub2ind provide the single value indices for a matrix of size(test)
%// at positions [x(:), y(:), max_ix(:)] and reshape brings it back to the correct shape
max_val2 = reshape(test(sub2ind(size(test), x(:) , y(:), max_ix(:))), size(x));
一种方法-
%// Get size of 3D input array
[m,n,~] = size(test);
%// Calculate 2D starting, offset & finally actual indices array
start_idx = bsxfun(@plus,[1:m]',[0:n-1]*m); %//'
offset_idx = m*n*(max_ix-1);
actual_idx = start_idx + offset_idx;
%// Index into 3D input array to extract specific elements, for desired output
max_val = test(actual_idx)
因此,如果您喜欢 compact 代码 -
,则基本上为我们提供了一个双线解决方案
[m,n,~] = size(test);
max_val = test( bsxfun(@plus,[1:m]',[0:n-1]*m) + m*n*(max_ix-1) )
请注意 bsxfun(@plus,[1:m]',[0:n-1]*m)
可以替换为 reshape(1:m*n,m,n)
。
样本运行
输入:
test(:,:,1) =
12 66 75 98
65 75 24 87
33 59 74 9
test(:,:,2) =
37 60 21 21
37 79 9 39
69 37 78 56
test(:,:,3) =
23 16 30 10
65 79 24 41
49 11 54 11
test(:,:,4) =
12 61 70 66
79 97 76 11
30 44 44 94
max_ix =
1 2 2 2
2 4 1 2
4 2 3 3
输出:
max_val =
12 60 21 21
37 97 24 39
30 37 54 11
我有一个 3 维矩阵(第 3 维表示 M x N
灰度图像的多个副本)。
我取图像中每个像素的最大值,得到一个 max_val
和 max_ix
矩阵 (2x2)。
我想通过 max_ix
值引用原始 test
矩阵。
示例:my_max_val = test(max_ix,:)
应等于:
5 1
1 1
显然我可以在这个简化的示例中使用 max_val
,但不能在实际用例中使用。我正在改变 max_ix
,所以我需要通过我创建的新索引值(未在此简化示例中描述)来引用原始 3 维矩阵。
>> test
test(:,:,1) =
1 1
1 1
test(:,:,2) =
1 1
1 1
test(:,:,3) =
5 1
1 1
test(:,:,4) =
1 1
1 1
>> [max_val, max_ix] = max(test, [], 3)
max_val =
5 1
1 1
max_ix =
3 1
1 1
如何仅从 test
和 max_ix
重新创建 max_val
?
这是一种方法。
%// Generate matrix test
test = randi(50,4,4,4);
%// Get maximum value and indices
[max_val, max_ix] = max(test, [], 3);
%// We don't know the size in general so this is the Cartesian product
[y, x] = meshgrid(1:size(test, 1), 1:size(test,2));
%// sub2ind provide the single value indices for a matrix of size(test)
%// at positions [x(:), y(:), max_ix(:)] and reshape brings it back to the correct shape
max_val2 = reshape(test(sub2ind(size(test), x(:) , y(:), max_ix(:))), size(x));
一种方法-
%// Get size of 3D input array
[m,n,~] = size(test);
%// Calculate 2D starting, offset & finally actual indices array
start_idx = bsxfun(@plus,[1:m]',[0:n-1]*m); %//'
offset_idx = m*n*(max_ix-1);
actual_idx = start_idx + offset_idx;
%// Index into 3D input array to extract specific elements, for desired output
max_val = test(actual_idx)
因此,如果您喜欢 compact 代码 -
,则基本上为我们提供了一个双线解决方案[m,n,~] = size(test);
max_val = test( bsxfun(@plus,[1:m]',[0:n-1]*m) + m*n*(max_ix-1) )
请注意 bsxfun(@plus,[1:m]',[0:n-1]*m)
可以替换为 reshape(1:m*n,m,n)
。
样本运行
输入:
test(:,:,1) =
12 66 75 98
65 75 24 87
33 59 74 9
test(:,:,2) =
37 60 21 21
37 79 9 39
69 37 78 56
test(:,:,3) =
23 16 30 10
65 79 24 41
49 11 54 11
test(:,:,4) =
12 61 70 66
79 97 76 11
30 44 44 94
max_ix =
1 2 2 2
2 4 1 2
4 2 3 3
输出:
max_val =
12 60 21 21
37 97 24 39
30 37 54 11