Crop matrix based on entries

7 views (last 30 days)
Alec Bledsoe
Alec Bledsoe on 29 May 2021
Edited: Matt J on 30 May 2021
I am working with matrix that contains only zeros and ones. I am trying to find a way to crop the matrix to include only the parts of the image where there are ones.
[0,0,0,0,0,0,0,0,0,0;
0,0,0,0,0,0,0,0,0,0;
0,0,0,0,0,0,0,1,0,0;
0,0,1,0,0,0,0,0,0,0;
0,1,1,1,0,0,0,0,0,0;
0,0,0,1,0,0,0,1,0,0;
0,0,1,1,0,0,1,1,0,0;
0,0,0,1,0,0,1,1,0,0;
0,0,1,0,0,0,0,0,0,0;
0,0,0,0,0,0,0,0,0,0]
This is just an example of the matrix but I am really working with a 10000x10000 array. The ones are largely near the center of that image so I am trying to basically filter out all of the extraneous zeros. Any ideas on how I would accomplish this?

Accepted Answer

Matt J
Matt J on 29 May 2021
Edited: Matt J on 29 May 2021
A=[0,0,0,0,0,0,0,0,0,0;
0,0,0,0,0,0,0,0,0,0;
0,0,0,0,0,0,0,1,0,0;
0,0,1,0,0,0,0,0,0,0;
0,1,1,1,0,0,0,0,0,0;
0,0,0,1,0,0,0,1,0,0;
0,0,1,1,0,0,1,1,0,0;
0,0,0,1,0,0,1,1,0,0;
0,0,1,0,0,0,0,0,0,0;
0,0,0,0,0,0,0,0,0,0];
I=find(any(A,2));
J=find(any(A,1));
A=A(min(I):max(I) , min(J):max(J))
A = 7×7
0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 1 0 0 0 1 0 1 1 0 0 1 1 0 0 1 0 0 1 1 0 1 0 0 0 0 0
  3 Comments
Image Analyst
Image Analyst on 29 May 2021
You could also skip the any() calls:
[r, c] = find(A); % Find all non-zero rows and columns.
ACropped = A(min(r):max(r), min(c):max(c));
Not sure which way is faster - you'd have to try both with tic() and toc() to see.
Matt J
Matt J on 30 May 2021
Edited: Matt J on 30 May 2021
Using any() is going to be much faster (EDIT: when there is a thin boundary of zeros) because it requires finding only the first 1 in the columns and rows of A.
A=randi([0,1],6000);
A([1:10,end-10:end],:)=0;
A(:,[1:10,end-10:end])=0;
timeTest(A)
Elapsed time is 0.004106 seconds. Elapsed time is 0.694781 seconds.
When the boundary is thick (as seems to be the case for the OP), using any() is slower, but only because we are not given the matrix in sparse form.
A=randi([0,1],6000);
A([1:2500,end-2500:end],:)=0;
A(:,[1:2500,end-2500:end])=0;
timeTest(A)
Elapsed time is 0.526749 seconds. Elapsed time is 0.063143 seconds.
timeTest(sparse(A))
Elapsed time is 0.001937 seconds. Elapsed time is 0.006975 seconds.
function timeTest(A)
tic;
I=find(any(A,2));
J=find(any(A,1));
[a,b,c,d]=deal(min(I), max(I), min(J), max(J));
toc;
tic;
[r, c] = find(A); % Find all non-zero rows and columns.
[a,b,c,d]=deal(min(r), max(r), min(c), max(c));
toc
disp ' '
end

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!