How to eliminate standalone 1 or 0 in binary matrix
3 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Simon Allosserie
le 23 Nov 2020
Commenté : Setsuna Yuuki.
le 24 Nov 2020
Hello
I have large binary matrices (order 30000 x 5000 values) in which I have to eliminate stand-alone 1's or 0's.
E.g. when a row looks like this: 0 0 1 1 1 0 1 1 0 0 1 0 1 1 1
It should be adapted to: 0 0 1 1 1 1 1 1 0 0 0 0 1 1 1
Or thus, when there's only one 1 between some 0's or one 0 between some 1's, it should be changed to a 0 or 1 respectively.
I have no clue how to do this except from running through the entire matrix and keeping count of the length of the series of 1's or 0's - which seems utterly inefficiënt to me. Any ideas on functions or better ways to tackle this? Thanks!
0 commentaires
Réponse acceptée
Rik
le 23 Nov 2020
I would suggest using a convolution with a flat kernel.
kernel=ones(1,3,1);kernel=kernel/sum(kernel(:));
A=[0 0 1 1 1 0 1 1 0 0 1 0 1 1 1];
B=convn(A,kernel,'same');
C=round(B);
clc,disp([A;B;C])%display the original, the convolution result and the final output
Note that the [0 0 1 0 1 1] is changed to [0 0 0 1 1 1]. If you don't want that, you can change the kernel to something like this:
kernel=[1 1 1 0 0];kernel=kernel/sum(kernel(:));
4 commentaires
Rik
le 23 Nov 2020
The more fundamental question is what the values should be. If you have a clear description of that, I might be able to help you find the right kernel.
Also note that this kernel only considers rows. It will work on a 2D array as well, but it will not check multiple rows at once. You can change the kernel to 2D if you want to change that.
Plus de réponses (1)
Setsuna Yuuki.
le 23 Nov 2020
Modifié(e) : Setsuna Yuuki.
le 23 Nov 2020
You only need a loop and correct conditional statement, the conditional can be:
if(A(n) ~= A(n+1) && A(n) ~= A(n-1) && A(n) == 1)
A(n) = 0;
elseif(A(n) ~= A(n+1) && A(n) ~= A(n-1) && A(n) == 0)
A(n) = 1;
end
so you compare only with the previous bit and the next.
5 commentaires
Rik
le 24 Nov 2020
This code can be simplified (or at least be edited to remove duplicated code):
%option 1:
sz=size(A);
for m = 1:sz(1)
for n=1:sz(2)
if ...
( n==1 && ...
(A(m,n) ~= A(m,2 ) && A(m,n) ~= A(m,3 )) ) || ...
( n==sz(2) && ...
( A(m,n) ~= A(m,end-1)) ) || ...
( ( n~=1 && n~=sz(2) ) && ...
(A(m,n) ~= A(m,n+1) && A(m,n) ~= A(m,n-1 )) )
A(m,n) = abs(A(m,n)-1);
end
end
end
%option 2:
sz=size(A);
for m = 1:sz(1)
for n=1:sz(2)
if n==1
L = (A(m,n) ~= A(m,2 ) && A(m,n) ~= A(m,3 )) ;
elseif n==sz(2)
L = A(m,n) ~= A(m,end-1)) ;
else
L = (A(m,n) ~= A(m,n+1) && A(m,n) ~= A(m,n-1 )) ;
end
if L
A(m,n) = abs(A(m,n)-1);
end
end
end
Setsuna Yuuki.
le 24 Nov 2020
I did it this way:
A = [0 0 1 1 1 0 1 1 0 ;0 0 0 1 0 1 0 1 1]';
[r,c,~]=size(A);
A = reshape(A,[1, r*c]);
for n = 2:r*c-1
if(A(n) ~= A(n+1) && A(n) ~= A(n-1) && A(n) == 1)
A(n) = 0;
elseif(A(n) ~= A(n+1) && A(n) ~= A(n-1) && A(n) == 0)
A(n) = 1;
end
end
A = reshape(A,[r,c])';
Voir également
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!