Reputation: 32051
I have a 3 dimensional matrix (3rd dimension represents multiple copies of an M x N
grayscale image).
I'm taking the max value of each pixel across the images, giving me a max_val
and max_ix
matrix (2x2).
I want to reference the original test
matrix by the max_ix
values.
Example: my_max_val = test(max_ix,:)
should equal:
5 1
1 1
Obviously I can just use max_val
in this simplified example, but not in the real use case. I'm altering max_ix
, so I need to reference the original 3-dimensional matrix by the new index values I create (not depicted in this simplified example).
>> 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
How do I recreate max_val
just from test
and max_ix
?
Upvotes: 2
Views: 111
Reputation: 221514
One approach -
%// 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)
Thus, essentially giving us a two-liner solution, if you are into compact codes -
[m,n,~] = size(test);
max_val = test( bsxfun(@plus,[1:m]',[0:n-1]*m) + m*n*(max_ix-1) )
Please note that bsxfun(@plus,[1:m]',[0:n-1]*m)
could be replaced by reshape(1:m*n,m,n)
.
Sample run
Inputs:
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
Output:
max_val =
12 60 21 21
37 97 24 39
30 37 54 11
Upvotes: 2
Reputation: 3440
Here's one way to do it.
%// 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));
Upvotes: 1