Counting consecutive repeat values for each row in matrix

18 views (last 30 days)
I have a matrix for a black and white photo, so 1s and 0s.
I want to horizontally measure the length, in pixels, of each black region in the photo. So the number of 0s.
How can I count the number of consecutive 0's for each row? Bare in mind for each row it is likely there are more than one group of consecutive 0's. I want a count value for each group of consecutive 0s in each row.
For example: I have a matrix
X = [1 1 1 1 0 0 0 0 0 1 1 1 0 0 0 0;
1 0 0 0 1 1 1 0 0 0 0 1 1 1 0 0]
So I want it to tell me:
Row 1: 2 groups of 0's, length of each: 5 and 4 respectively
Row 2: 3 groups of 0's, length of each: 3, 4, and 2 respectively
Any help would be greatly appreciated!

Accepted Answer

the cyclist
the cyclist on 19 Nov 2019
Edited: the cyclist on 19 Nov 2019
First, I would download Jan's RunLength utility from the File Exchange, which was designed to solve exactly this kind of problem.
X = [1 1 1 1 0 0 0 0 0 1 1 1 0 0 0 0;
1 0 0 0 1 1 1 0 0 0 0 1 1 1 0 0];
for nr = 1:size(X,1)
[b{nr} n{nr}] = RunLength(X(nr,:))
end
Each element of b will be the values of each consecutive "run", and n will have the lengths of those runs. So, in this example, the outputs are
% Row 1 results
[b{1}; n{1}]
ans =
1 0 1 0
4 5 3 4
% Row 2 results
[b{2}; n{2}]
ans =
1 0 1 0 1 0
1 3 3 4 3 2
You may need to do another step or two to get the output exactly as you want it, but this could be your first building block.

More Answers (2)

David Hill
David Hill on 19 Nov 2019
X = [1 1 1 1 0 0 0 0 0 1 1 1 0 0 0 0;
1 0 0 0 1 1 1 0 0 0 0 1 1 1 0 0];
for k = 1:size(X,1)
a=num2str(X(k,:));
a=a(a~=' ');
a=regexp(a,'([0]+)','tokenExtents');
b(k)=max(cellfun(@(y)max(diff(y))+1,a));%b array will have the maximum number of consecutive zeros of each row
end
  1 Comment
b
b on 22 Dec 2021
Edited: b on 22 Dec 2021
David, in your above answer, how to output the positions of b-vector?
For example, if we are counting number of '1' in each row,
b(1)=4
the corrsponding position is
X(1,1:4)
and for
b(2)=3
the corresponding positions are:
X(2,5:7) and X(2,12:14)
How to get these X-values also?

Sign in to comment.


Guillaume
Guillaume on 19 Nov 2019
Edited: Guillaume on 20 Nov 2019
It's a job for the image processing toolbox, in particular bwconncomp (with a custom connectivity):
cc = bwconncomp(~yourphoto, [0 0 0; 1 1 1; 0 0 0]); %only consider connection on a row
rowcount = cell(size(yourphoto, 1), 1);
for idx = 1:cc.NumObjects
row = mod(cc.PixelIdxList{idx}(1)-1, size(yourphoto, 1)) + 1; %find which row correspond to the connected component
rowcount{row} = [rowcount{row}, numel(cc.PixelIdxList{idx}-1)]; %number of pixels in the component
end
edit: fixed lots of typos.
  2 Comments
Daniel M
Daniel M on 20 Nov 2019
Edited: Daniel M on 20 Nov 2019
This does not work. Is youphoto supposed to be X?
After changing 'yourphoto' to 'youphoto', and 'Pixel' and 'PixelIdx' to 'PixelIdxList', I get the error:
Expected one output from a curly brace or dot indexing expression, but there were 3 results.
But I'm curious for the solution using image processing. Can you correct your code?
Guillaume
Guillaume on 20 Nov 2019
Indeed, I shouldn't write answers just before going to bed, there were lots of typos. All fixed now.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!