# How do I find 4 or more consecutive zeros and replace these zero's?

50 views (last 30 days)
chels19 on 6 Jul 2016
Commented: Amin Azari on 25 Feb 2019
I have a large matrix and need to loop through it and find where there are instances of 4 or more 0's and replace these 0's with 2's. For example, in the below image I need to replace the 4 or more consecutive 0's (red) with 2's but the other 0 further down is fine. The image on the right is what I'm expecting.
I can count the number of times 0 appears but am stuck on how to alter these 0's. This is what I have so far:
for i = 1:length(x)
y = x(:,end);
if y(i) == 0
count = count + 1;
else if count >= 4
lastIndex = i - 1;
%change 0's in the block of 4 to 2's
%this is the bit I'm stuck on
count = 0; %reset count
end
count = 0;
end
end
Any help would be greatly appreciated.

Guillaume on 6 Jul 2016
Edited: Guillaume on 6 Jul 2016
Here is one way to do it, which does not involve looping over the whole vector (only over each run of zero)
transitions = diff([0; x == 0; 0]); %find where the array goes from non-zero to zero and vice versa
runstarts = find(transitions == 1);
runends = find(transitions == -1); %one past the end
runlengths = runends - runstarts;
%keep only those runs of length 4 or more:
runstarts(runlengths < 4) = [];
runends(runlengths < 4) = [];
%expand each run into a list indices:
indices = arrayfun(@(s, e) s:e-1, runstarts, runends, 'UniformOutput', false);
indices = [indices{:}]; %concatenate the list of indices into one vector
x(indices) = 2 %replace the indices with 2

#### 1 Comment

chels19 on 6 Jul 2016
Thank you for your help, it works brilliantly.

Azzi Abdelmalek on 6 Jul 2016
Edited: Azzi Abdelmalek on 6 Jul 2016
A=[0 0 1 1 0 0 0 0 1 1 1 0 0 1 0 0 0 0 0 0 0 1 1 0 1]'
ii=strfind([1 A'],[1 0])
jj=strfind([A' 1],[0 1])
kk=find(jj-ii+1>=4)
for k=1:numel(kk)
idx=ii(kk(k)):jj(kk(k))
A(idx)=2*ones(numel(idx),1)
end

chels19 on 6 Jul 2016
Phani kumar KSV on 26 Apr 2018
Simple and superb code... thankyou
Amin Azari on 25 Feb 2019
Nice.

Azzi Abdelmalek on 6 Jul 2016
A=[0 0 1 1 0 0 0 0 1 1 1 0 0 1 0 0 0 0 0 0 0 1 1 0 1]'
a=cumsum(A)+1
v=cell2mat(accumarray(a,(1:numel(a))',[],@(x) {2*(numel(x)>=4 & A(x)==0)+A(x)}))

Image Analyst on 6 Jul 2016
Here's a way using regionprops to find the areas >= 4 and replace them with 2:
m = [0 0 1 1 0 0 0 0 1 1 1 0 0 1 0 0 0 0 0 0 0 1 1 0 1]'
props = regionprops(bwlabel(m==0), 'Area', 'PixelIdxList');
indexesOf4orMore = find([props.Area] >= 4)
for k = indexesOf4orMore
theseIndexes = props(k).PixelIdxList
m(theseIndexes) = 2;
end
m % Echo result to command window.