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

조회 수: 1 (최근 30일)
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.
Could you please give me some insight about this? I would really appreciate your help.
Julia
  댓글 수: 3
Ashish Uthama
Ashish Uthama 2011년 3월 16일
As Jan asked, you need to define 'neighbors'.i.e are they four connected (two above and two on the side) or 8 connected (includes the diagonally adjacent 'neighbors').
What about 'cells' along the borders? How do you want to deal with them?
It would help to formulate your thoughts as pseudo code, it would make the question clear and might also just lead you to the solution. Something along these lines:
Consider one cell (or element) in the matrix
Take its four-connected neighbors
If any of these neighbors are 1 unit above or below current cell
Mark current cell as <> ...
Etc
Julia
Julia 2011년 3월 25일
First of all, thank you for your answers and comments.
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
Wolfgang Schwanghart 2011년 3월 18일
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
Julia
Julia 2011년 3월 27일
Dear Wolfgang,
I have seen your answer today. I have been trying to understand both functions and they are clear for me but I don't know how to combine them to consider an 8-connectivity. I have modified find_components to consider the 1 unit difference between numbers but I am not able to introduce diagonal connectivities. Could yo give me some more help? What I have modified in find_components is:
line 91: East = [(K (:,2:n) .* ((A (:,2:n) - A (:,1:n-1)) == 0 | (A (:,2:n) - A (:,1:n-1)) == 1 | (A (:,2:n) - A (:,1:n-1)) == -1)) zeros(m,1)] ;
and
line 114: South = [(K (2:m,:) .* (A (2:m,:) - A (1:m-1,:) == 0 | A (2:m,:) - A (1:m-1,:) == 1 | A (2:m,:) - A (1:m-1,:) == -1)) ; zeros(1,n)] ;
Thank you very much.
Julia
Julia 2011년 3월 27일
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!!!

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Data Distribution Plots에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by