How can I loop over a binary image to get 4 equal quadrants always?
Show older comments
I am following this steps to get 4 equal quadrants from a binary image:
r1=q1(1:size(q1,1)/2,1:size(q1,2)/2,:);
r2=q1(size(q1,1)/2+1:size(q1,1),1:size(q1,2)/2,:);
r3=q1(1:size(q1,1)/2,size(q1,2)/2+1:size(q1,2),:);
r4=q1(size(q1,1)/2+1:size(q1,1),size(q1,2)/2+1:size(q1,2),:);
After this, I want to get 4 equal quadrants from r1,r2,r3,r4 indivisually. This process will continue as long as we can get 4 equal quadrants . How can I simply do this with the help of any loop.
3 Comments
Walter Roberson
on 17 Apr 2019
To confirm: if the original image happened to be a power of 2 on each side, such as 512 x 512, then you would want the division into equal quadrants to continue right down to the point where the quadrant sizes were 1 x 1 ? But for a 513 x 513 matrix, then no sub-division would be done, since you cannot make equal quardrants ?
Answers (2)
Using 4 distinct variables is less convenient than reshaping the array:
s = size(q1);
q2 = reshape(q1, s(1)/2, 2, s(2)/2, 2);
Now you have e.g. your r4 stored in q2(:, 2, :, 2). In general:
s = size(q1); % Assuming that q1 is a binary image ==> 2D!
% How often can the size be divided by 2:
n = min(sum(factor(s(1)) == 2), sum(factor(s(2)) == 2));
twos = repmat(2, 1, n);
div = 2^n;
qq = reshape(q1, [s(1) / div, twos, s(2) / div, twos]);
Perhaps you want to permute the array (you did not mention, what you need as output).
qq = permute(qq, [1, n+2, 2:n+1, n+3:2*n+2]);
% And maybe:
qq = reshape(qq, s(1)/div, s(2)/div, []);
Now qq(:, :, i) contains the i.th quadrant.
Walter Roberson
on 17 Apr 2019
function splitted = rsplit4(img)
[r, c, p] = size(img);
if mod(r,2) || mod(c,2)
splitted = img;
else
splitted = {rsplit4(img(1:end/2,1:end/2, :)), rsplit4(img(1:end/2,end/2+1:end, :));
rsplit4(img(end/2+1:end,1:end/2,:)), rsplit4(img(end/2+1:end,end/2+1:end,:))};
end
end
13 Comments
Walter Roberson
on 17 Apr 2019
You cannot define a function at the command prompt.
If you are using R2016a or earlier, you cannot define a function as part of a script and would need to store the function I posted as rsplit4.m
If you are using R2016b or later, you can define a function as part of a script. But you might as well store the function I posted as rsplit4.m so that you can use it from multiple places.
Walter Roberson
on 17 Apr 2019
The 79 x 79 result is the only block.
You need to define more clearly how you want to handle even and odd sizes. If you have:
ABCDEFGH
then where would you divide that, what would go into each half? And if you had
ABCDEFGHI
then how would you divide that, what would go into each half?
When you talk about "on each side of the centroid", that could imply that you want to divide as ABCD and FGHI since the centroid is at E and those two would be "on each side" of the centroid. However, if you do this, then you are likely to miscount the whitespace that occurs on column E.
Zara Khan
on 17 Apr 2019
Zara Khan
on 17 Apr 2019
Walter Roberson
on 17 Apr 2019
Are you saying that the taking of quardants should be based upon the content of the image ?
What if there was a blob that looked like
**
**
**
********************
**
**
**
Centroid is 7.25 into the middle row. Maximum distance from centroid to bounding box is 12.75. But 12.75 to the left of the centroid is outside the image.
Zara Khan
on 17 Apr 2019
Walter Roberson
on 17 Apr 2019
The rsplit4 code I posted would take an 80 x 80 and convert it to a 2 x 2 cell array, each entry of which was a 2 x 2 cell array, and so on, until it got down to 5 x 5. After 5 x 5, it can no longer divide the into equal parts -- not unless it leaves out rows and columns like I was asking about in the ABCDEFGHI example (which you did not answer.)
Walter Roberson
on 17 Apr 2019
I do not see an attached picture.
The code I posted creates hierarchy of cell arrays. It does not assume that all of the subarrays will be the same size.
Anyhow: take the code I posted, and change the
splitted = img;
to
splitted = nnz(img);
then in the other assignment to splitted, change the { } brackets to [ ] brackets.
Note that if your image happens to be a power of 2 in each direction, then the output will happen to exactly equal the input when the input is a binary matrix, because you keep subdividing into quadrants until you get down to 1 x 1, and the number of whitespace elements in that is the same as the question of whether the pixel is true or not.
Zara Khan
on 17 Apr 2019
Walter Roberson
on 17 Apr 2019
So you have, in this example, an 80 x 160 image, and you want to sub-divide down to 10 x 10 ? It is not clear why you did not continue on to 5 x 5.
The centroid of the 80 x 160 would be at (40, 80), and the maximum horizontal or vertical distance from the centroid to the edge would be 80. Your previous requirements say that we must take an 80 x 80 square on each side of the centroid. However, with the centroid being at (40,80), we cannot take an 80x80 square to either side of it.
Categories
Find more on Computer Vision with Simulink in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!