# Grouping data according to the connected components, which may have a value 1 unit different

1 view (last 30 days)
Julia on 16 Mar 2011
Dear all,
I am trying to group different values according to the value of their neighbors, which can have a difference value of 1. I show you an example with matrix to clarify my intention:
M = [0 1 0 0; 1 0 1 3; 0 1 0 2; 0 2 0 4]
I would like to get the following matrix:
M_groups=[0 1 0 0; 1 0 1 1; 0 1 0 1; 0 1 0 2];
I don't know how to proceed for a general case, I was thinking about the following conditions: If the cell has a non-zero value and a neighbor which is 1 unit higher or lower
Then, I should identify them somehow per groups, but I was not able to program this.
I have seen that there exists the function bwconncomp.m, but in my case I firstly need to obtain the binary image according to the condition about the difference of 1 unit between neighbors.
Julia
Julia on 25 Mar 2011
I have been working on it and I have now this:
Input matrix: M
M_results=zeros(1,3);
M_margins=zeros(size(M,1)+2,size(M,2)+2);
M_margins(2:end-1,2:end-1)=M;
M_origen=M_margins;
for k=1:max(max(M_margins))
[row,col]=find(M_margins==k);
for i=1:size(row,1)
M_aux=M_margins(row(i)-1:row(i)+1,col(i)-1:col(i)+1);
M_dif=M_aux(2,2)-M_aux;
[row_dif,col_dif]=find(M_dif==0 | M_dif==(-1));
for j=1:size((row_dif),1)
if M_margins(row_dif(j)-2+row(i),col_dif(j)-2+col(i))==0
M_margins(row_dif(j)-2+row(i),col_dif(j)-2+col(i))=0;
else
M_margins(row_dif(j)-2+row(i),col_dif(j)-2+col(i))=(max(max(M_aux(row_dif,col_dif))));
end
end
end
end
It works with a matrix like this:
M1 = [0 2 1; 3 0 0; 4 0 0; 5 6 0]
but not with one like this:
M2 = [0 2 1; 3 0 0; 4 5 6]
M_margins for the first case is:
M1_margins=[0 0 0 0 0; 0 0 6 6 0; 0 6 0 0 0; 0 6 0 0 0; 0 6 6 0 0; 0 0 0 0 0]
for the second one, it is:
M2_margins=[0 0 0 0 0; 0 0 5 3 0; 0 6 0 0 0; 0 6 6 6 0; 0 0 0 0 0]
Since I change the values of M_margins, if there is some previous neighbor (8-connected) that has been changed, the algorthim does not detect that they are in fact neighbors...
Do you know how could I fix it?
Thank you very much.

Wolfgang Schwanghart on 18 Mar 2011
You might want to take a look at Tim Davis' function find_components ( http://www.mathworks.com/matlabcentral/fileexchange/21366-findcomponents ). In combination with my function ixneighbors ( http://www.mathworks.com/matlabcentral/fileexchange/16991-neighbor-indexing ), I am sure you'll be able to compute your label matrix.
##### 2 CommentsShowHide 1 older comment
Julia on 27 Mar 2011
Hi,
here again. I think I have done it! However, I have not used ixneighbours. What do you think about this solution to consider diagonal elements?
%-------------------------------------------------------------------------------
% look to the south_east
%-------------------------------------------------------------------------------
A_aux=A(1:m-1,1:n-1);
K_aux=K(1:m-1,1:n-1);
K_resta=K_aux+m+1;
A_resta=A(K_aux) - A(K_resta)
South_east = [(K_resta .* (A_resta == 0 | A_resta == 1 | A_resta == -1)) ; zeros(1,n-1)] ;
South_east = [South_east zeros(size(South_east,1),1)] ;
SE = find (South_east) ;
%-------------------------------------------------------------------------------
% look to the north_east
%-------------------------------------------------------------------------------
A_aux=A(2:m,1:n-1);
K_aux=K(2:m,1:n-1);
K_resta=K_aux+m-1;
A_resta=A(K_aux) - A(K_resta)
North_east = [zeros(1,n-1); (K_resta .* (A_resta == 0 | A_resta == 1 | A_resta == -1))] ;
North_east = [North_east zeros(size(North_east,1),1)] ;
NE = find (North_east) ;
Thank very much again!!!