kurokirasama
kurokirasama

Reputation: 777

Number 0's and 1's blocks in a binary vector

In MATLAB, there is the bwlabel function, that given a binary vector, for instance x=[1 1 0 0 0 1 1 0 0 1 1 1 0] gives (bwlabel(x)):

[1 1 0 0 0 2 2 0 0 3 3 3 0]

but what I want to obtain is

[1 1 2 2 2 3 3 4 4 5 5 5 6]

I know I can negate x to obtain (bwlabel(~x))

[0 0 1 1 1 0 0 2 2 0 0 0 3]

But how can I combine them?

Upvotes: 2

Views: 146

Answers (4)

kurokirasama
kurokirasama

Reputation: 777

I found this function that does exactly what i wanted:

https://github.com/davidstutz/matlab-multi-label-connected-components

So, clone the repository and compile in matlab using mex :

mex sp_fast_connected_relabel.cpp

Then,

labels = sp_fast_connected_relabel(x);

Upvotes: -1

gnovice
gnovice

Reputation: 125854

You can still do it using bwlabel by vertically concatenating x and ~x, using 4-connected components for the labeling, then taking the maximum down each column:

>> max(bwlabel([x; ~x], 4))

ans =

     1     1     2     2     2     3     3     4     4     5     5     5     6

However, the solution from Bentoy13 is probably a bit faster.

Upvotes: 3

Adriaan
Adriaan

Reputation: 18177

x=[1 1 0 0 0 1 1 0 0 1 1 1 0];
A = bwlabel(x);
B = bwlabel(~x);

if x(1)==1
    tmp = A>0;
    A(tmp) = 2*A(tmp)-1;
    tmp = B>0;
    B(tmp) = 2*B(tmp);
    C = A+B
elseif x(1)==0
    tmp = A>0;
    A(tmp) = 2*A(tmp);
    tmp = B>1;
    B(tmp) = 2*B(tmp)-1;
    C = A+B
end
C =

     1     1     2     2     2     3     3     4     4     5     5     5     6

You know the first index should remain 1, but the second index should go from 1 to 2, the third from 2 to 3 etc; thus even indices should be doubled and odd indices should double minus one. This is given by A+A-1 for odd entries, and B+B for even entries. So a simple check for whether A or B contains the even points is sufficient, and then simply add the two arrays.

Upvotes: 1

Bentoy13
Bentoy13

Reputation: 4956

All in one line:

y = cumsum([1,abs(diff(x))])

Namely, abs(diff(x)) spots changes in the binary vector, and you gain the output with the cumulative sum.

Upvotes: 6

Related Questions