Setting lone 1s to 0s in a logical vector/matrix

If I have this vector for example: [ 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0]
And I want to replace the lone 1 (the sixth element in this case) with a zero, is there an existing algorithm which can do this?
i.e. [ 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0] ----> [ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0]
For context, this is an example of a row of pixels which has been colour thresholded to return 1s in areas of green and 0s otherwise.
The lone 1 represents an anomalous point, there is no green there and hence I wish to replace it with a 0.
For a further condition, I'd like to do the same for any section of 1s less than 3 in length.
i.e. [0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0] would go to [0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0]

 Accepted Answer

You can use bwareaopen() in the Image Processing Toolbox. You specify the smallest region length you want to keep, like to get rid of single 1's keep runs of 2 or longer
v = [ 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0]
v2 = bwareaopen(v, 2) % Keep runs of 2 or longer

6 Comments

Abbas, are you still there?
Thank you so much, one more question:
Is there a function that can take [ 0 0 0 0 1 1 1 1 0 1 1 1 0 0 0] say and return [ 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0], i.e. bridge the gap in the sequence of ones?
found brmorph 'bridge' to do a good job of this, for the example:
[ 0 0 0 0 1 1 1 1 0 1 1 1 0 0 0] ------> [ 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0]
but is there a way to specify say if I wanted this to work when there were more 0s?
e.g. [ 0 0 0 0 1 1 1 1 0 0 1 1 0 0 0] ------> [ 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0]
It's a little tricky but it can still be done with only bwareaopen(). I've done it in multiple steps so you can follow long each step of the way:
v = [ 0 0 0 0 1 1 1 1 0 0 1 1 0 0 0 1 1 0] % Need to remove one stretch of 2 zeros.
% Allow 3 or more 0's in a row (they remain). 2 or less will get filled.
minAllowableHoleSize = 3;
% Pad with 1's on each end so we do not remove any zeros on the ends
% no matter how long or short they are because there is no one outside of them.
v2 = [ones(1, minAllowableHoleSize), ~v, ones(1, minAllowableHoleSize)]
v3 = bwareaopen(logical(v2), minAllowableHoleSize)
% Remove padding that we added
v4 = v3(minAllowableHoleSize+1:end-minAllowableHoleSize)
v5 = ~v4
v5 is the same as v except any runs of 2 or fewer 0s are filled in with 1s.
Brilliant, worked a charm, thank you!!!

Sign in to comment.

More Answers (1)

Jan
Jan on 2 Apr 2021
Edited: Jan on 2 Apr 2021
a = [0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0];
[val, n] = RunLength(a);
del = (val == 1) & (n == 1); % Or: n < limit
val(del) = 0;
b = RunLength(val, n);
% b = [0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0];

Community Treasure Hunt

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

Start Hunting!