Please help, logical indexing of 3D matrices

Hello
I'm stuck on this stupid thing and i know is obvious.
I have this matrice A: 480x848x3
And this logical matrice B: 480x848
And I want a matrice C=zeros(480, 848) like this: C(B)=A(B,1)
It should work but there's something wrong. I thought it might be like this:
C(B)=A([B 1])
or like this:
C(B)=A([B, 1])
or like this:
C(B)=A([B; 1])
But nothing works.
I know it works if i make:
D=A(:,:,1)
C(B)=D(B)
But how do i make it work with the indexes in 3D???
Thanks!!!

10 件のコメント

James Tursa
James Tursa 2015 年 3 月 6 日
What's wrong with using the last 2-line form that works?
Miguel Lopes
Miguel Lopes 2015 年 3 月 6 日
I have to store another matrix!! And i'm getting out of memory messages!!
Sad Grad Student
Sad Grad Student 2015 年 3 月 6 日
I am unable to understand what exactly you want.. Can you give an example of the sample input of A and B matrices and sample output where what content of A is combined with that of B ?
James Tursa
James Tursa 2015 年 3 月 6 日
編集済み: James Tursa 2015 年 3 月 6 日
@Miguel: Do you mean that the statement D = A(:,:,1) is in an of itself causing an out of memory error? Where, exactly, are you getting an out of memory error? Sizes you show above are not that large.
Miguel Lopes
Miguel Lopes 2015 年 3 月 6 日
編集済み: Miguel Lopes 2015 年 3 月 6 日
@ sad I can't because A is in 3D so I don't know how to write that.
But these 2 lines: D=A(:,:,1) C(B)=D(B)
are what i want but i wanted to remove D because when I create D I get out of memory message.
Miguel Lopes
Miguel Lopes 2015 年 3 月 6 日
編集済み: Miguel Lopes 2015 年 3 月 6 日
@ james Yes is the D=A(:,:,1) that creates the out of memory message! The problem is that I have many fotos (A) and for each one a different mask (matrice B) and I need to create C but i can't free A or B.
Miguel Lopes
Miguel Lopes 2015 年 3 月 6 日
@james and if I do like this: D=A(:,:,1) C(B)=D(B)
I have to create a different D for each dimension! Althought I think I can just overwrite for each one, but it's not efficient! Isn't it possible to work with the 3D matrices indexes like I want??
James Tursa
James Tursa 2015 年 3 月 6 日
編集済み: James Tursa 2015 年 3 月 6 日
Here is what I get ... as you can see the memory usage is not that much:
>> A = rand(480,848,3);
>> B = rand(480,848)<0.5;
>> C = zeros(480,848);
>> D = A(:,:,1);
>> C(B) = D(B);
>> whos
Name Size Bytes Class Attributes
A 480x848x3 9768960 double
B 480x848 407040 logical
C 480x848 3256320 double
D 480x848 3256320 double
What am I missing? Apparently I don't understand what you mean by the phrase "work with indexes in 3D".
Miguel Lopes
Miguel Lopes 2015 年 3 月 6 日
yes but I have many fotos like that, not just one!!! I also need the HSV channel for each one (i have to do the same), so I get no memory at a point!
James Tursa
James Tursa 2015 年 3 月 6 日
So, it sounds like the memory problem isn't this calculation for a single photo, but the fact that you have very many of these photos in memory at the same time?

サインインしてコメントする。

回答 (5 件)

Star Strider
Star Strider 2015 年 3 月 6 日
編集済み: Star Strider 2015 年 3 月 6 日

0 投票

Your ‘A’ matrix looks like it could be an image. To collapse the third dimension, use the rgb2gray function in the Image Processing Toolbox.
For example:
A = uint8(randi([0 255], 480, 848, 3));
figure(1)
imshow(A)
G = rgb2gray(A);
figure(2)
imshow(G)
Another option is to expand ‘C’ to three dimensions by replicating it three times in the third dimension:
C = zeros(480,848);
Cx = repmat(C, 1, 1, 3);

2 件のコメント

Miguel Lopes
Miguel Lopes 2015 年 3 月 6 日
What you mean "to collapse"??
I need the 3 channels and I have different masks for each channel! I need the data from the 3 channels!!
Star Strider
Star Strider 2015 年 3 月 6 日
If you need all three channels, then don’t collapse them into grayscale.
If you have different masks for each channel, concatenate them:
C1 = uint8(randi([0 255],480,848)); % Red Mask
C2 = uint8(randi([0 255],480,848)); % Green Mask
C3 = uint8(randi([0 255],480,848)); % Blue Mask
Cc= cat(3, C1, C2, C3); % All Masks
That creates a (480x848x3) matrix in ‘Cc’ that you may be able to use.

サインインしてコメントする。

Adam
Adam 2015 年 3 月 6 日
編集済み: Adam 2015 年 3 月 6 日

0 投票

(Edited version as in comments below - original edit was incorrect!)
C = zeros( size(B) );
ind2d = find(B);
C( ind2d ) = A( ind2d );
works without needing to create another matrix. Note that it works specifically because it is the 1st index of the 3rd dimension that you want. If you wanted the 2nd then you would need to add the x*y size to the ind2d array and for the 3rd index of the 3rd dimension you would need to add twice the x*y size to the indices.
In case you aren't aware, this works because you can use 1d (linear) indexing into an array of any dimension in addition to the standard subscript access of e.g. (300,200,3)

4 件のコメント

James Tursa
James Tursa 2015 年 3 月 6 日
This does not give a 480 x 848 result C as Miguel stated he wants.
David Young
David Young 2015 年 3 月 6 日
Note the solution above gives a vector - C contains only the elements of A corresponding to the non-zero elements of B. I think what is requested is the matrix given by
C = zeros(size(B));
ind2d = find(B);
C(ind2d) = A(ind2d);
where I have used ind2d to fit in with the comment about mulitplying to get planes other than the first.
Adam
Adam 2015 年 3 月 6 日
Ah yes, I tried to simplify my original answer and messed up the result:
C = zeros( size(B) );
ind2d = find(B);
C( ind2d ) = A( ind2d );
was what I meant.
I should stick to the way I usually program stuff with logical matrices assigned to their own variable rather than trying to simplify it in-place without checking it first in Matlab!
Adam
Adam 2015 年 3 月 6 日
Wow, that is odd...we both corrected it to the same solution even to the naming of the intermediate variable!!

サインインしてコメントする。

David Young
David Young 2015 年 3 月 6 日
編集済み: David Young 2015 年 3 月 6 日

0 投票

One way, slightly fiddly but the simplest I can think of now:
[rowsB, colsB] = find(B);
C = zeros(size(B));
ind3 = 1; % index of the plane of A that is wanted
C(B) = A(sub2ind(size(A), rowsB, colsB, ind3*ones(size(rowsB))));
Sad Grad Student
Sad Grad Student 2015 年 3 月 6 日

0 投票

Does changing from D = A(:,:,1) to D = A(:,:,1).*B and then assign C(B) = D help? Or does it still give memory problems?
Tongyao Pu
Tongyao Pu 2019 年 11 月 6 日

0 投票

Hello,
I am a bit confused that you would like C to be 480*848.
I wonder if you would like to index each layer of A with logical matrix B? If that is the case, that is how I do it:
C = A;
B2 = repmat(B, [1,1,3]); % just copy B into a 480*848*3 array
C(B2) = 'something you would like it to be, e.g. NaN'

カテゴリ

質問済み:

2015 年 3 月 6 日

回答済み:

2019 年 11 月 6 日

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by