Most efficient way to find the indices of rectangular annuli in a 2D matrix

Hello,
I have a 2D matrix of dimensions 400 x 400. I am interested in extracting the indices of the regions marked in pink, green, and yellow in the below figure. One way to go about this would be: First, find the indices where the X > 100 & X < 300 & Y > 100 & Y < 300 and that is the pink region. Here, the Xs represent the columns and the Ys represent the rows. For the green and yellow regions, it will be useful if I can do something like: find the indices where the X > 50 & X < 350 & Y > 50 & Y < 350 and add an additional condition that the indices should not correspond to the pink region. Similarly, the yellow region is simply all the indices that do not correspond to the pink or green regions. How do I implement this?

 Accepted Answer

I=[ones(1,50), 2*ones(1,50), 3*ones(1,100)];
I=[I,flip(I)];
pink = (I==3 & I.'==3);
green = (I>=2) & (I.'>=2)&~pink;
yellow = ~(pink|green);
imshow(pink)
imshow(green)

9 Comments

Dear Matt,
The code looks really neat. However, I won't have the luxury of having all the values in pink, green, and yellow as uniform. Please start with an nonuniform array of random numbers, for example. Can you achieve the same thing using indices and not the values (I can't use I == 3 for example) ?
Thank you.
You have indices. The arrays yellow, green, and pink that the code creates for you are logical indices. You can use them to access regions of an array very compactly, for example,
I=[ones(1,50), 2*ones(1,50), 3*ones(1,100)];
I=[I,flip(I)];
pink = (I==3 & I.'==3);
green = (I>=2) & (I.'>=2)&~pink;
yellow = ~(pink|green);
[~,Stripes]=ndgrid(ceil((1:400)/20)/20);
%%Use yellow, green, and pink as indices to create an image
Image=nan(400);
Image(yellow)=rand(1,nnz(yellow));
Image(green)=1;
Image(pink)=Stripes(pink);
imshow(Image)
Aah, I see what you mean. You can use these dummy numbers to capture the indices and define the pink, green, and yellow zones regardless of the actual values of the arrays. That will work, thank you!
Can you please tell me how you created these stripes? What does the following do and how would I adapt it if I had a grid that was not a square? For example, if I did not have: 400 x 400, but had 414 x 381 instead.
[~,Stripes]=ndgrid(ceil((1:400)/20)/20);
It's just one way to generate a repeated pattern of elements. You could just as well use repelem and repmat.
Sorry, I don't follow. How would you rewrite [~,Stripes]=ndgrid(ceil((1:400)/20)/20) if you had 414 x 381? Could you use repelem or repmat and show me, please?
Wouldn't this create a uniform grid of 381 x 381? And we started with a nonuniform grid of 414x 381. How will this work?
True. Well, then you could do
[~,Stripes]=ndgrid(1:414, ceil((1:381)/20)/20 ) ;
or you could do,
Stripes=repmat( ceil( (1:381)/20)/20) , 414,1)

Sign in to comment.

More Answers (0)

Categories

Asked:

on 4 Nov 2020

Edited:

on 12 Nov 2020

Community Treasure Hunt

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

Start Hunting!