Ayesha Khan
Ayesha Khan

Reputation: 155

Centroid of objects/connected components in matlab?

I am trying to find centroid of objects. I have already implemented connected components labeling and I have developed following code for centroid, it does give result but does not gives correct result: I have following output matrix i.e matrix_img:

 0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
 0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
 0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
 0     0     0     0     0     0     0     0     0     0     1     1     1     1     0     0
 2     2     2     2     0     0     0     0     0     1     1     1     1     1     1     0
 2     2     2     2     0     0     0     0     1     1     1     1     1     1     1     1
 2     2     2     2     0     0     0     0     1     1     1     1     1     1     1     1
 2     2     2     2     0     0     0     0     1     1     1     1     1     1     1     1
 2     2     2     2     0     0     0     0     0     1     1     1     1     1     1     0
 2     2     2     2     0     0     0     0     0     0     1     1     1     1     0     0
 2     2     2     2     0     0     0     0     0     0     0     0     0     0     0     0
 2     2     2     2     0     0     0     0     0     0     0     0     0     0     0     0
 2     2     2     2     0     0     5     5     5     0     0     0     0     0     0     0
 2     2     2     2     0     0     5     5     5     0     0     0     0     0     0     0
 2     2     2     2     0     0     5     5     5     0     0     0     0     0     0     0
 2     2     2     2     0     0     0     0     0     0     0     0     0     0     0     0

and following is the code

n= max(max(matrix_img));
for k=1:n
a(k)=length(find(matrix_img==k)); 



 sx(k)=0;
    sy(k)=0;
    cx=0;
    cy=0;

for i=1:1:r
    for j=1:1:c
        if(matrix_img(i,j)==k)

           sx(k)=sx(k)+i;
           sy(k)=sy(k)+j;
           cx=sx(k)/a(k);
           cy=sy(k)/a(k);

       end
    end 
end
  fprintf('Centroid of Object %d is %d and %d \n', k, cx, cy);   
end

It gives result like :

Centroid of Object 1 is 7 and 1.250000e+001 
Centroid of Object 2 is 1.050000e+001 and 2.500000e+000 
Centroid of Object 3 is 0 and 0 
Centroid of Object 4 is 0 and 0 
Centroid of Object 5 is 14 and 8 

Object 5 result is correct, object 2 is completely wrong and object 1 is partially wrong.. what shall I do?

Upvotes: 0

Views: 4642

Answers (2)

Egon
Egon

Reputation: 4787

The values you obtain are the exact centroids for those objects. So you might want to define what you'd expect to get as results.

To make this more clear, I've colored the objects in your matrix. By the symmetry on your cartesian grid, there should be an equal number of points to the left and right of your centroid and the same for above/below the centroid. I've drawn a figure with your objects colored in, together with lines to represent the horizontal and vertical center lines. Those are lines for which, we have an equal number of points to the left/right (or above/below) of them that are part of a certain object.

Their intersection is the centroid, so you can see for object 5 (blue one) that the centroid is at (8, 14). For the other two objects, these center lines do not lie on the integer grid you have: the red object (1) has its centroid at (12.5, 7) which is also the outcome of your code and the green object (2) is centered around (2.5, 10.5).

You will either have to live with inaccuracy introduced by rounding your centroids (e.g. round(cx)) or you will have to live with the non-integer coordinates of the centroids.

Graphical representation

Next to that, I also recommend you vectorize your code as oli showed: this allows you to run your code faster and it is easier to understand when you are somewhat familiar with MATLAB than for loops.

Perhaps a little note with regard to your string representation: don't use %d for non-integers, as you see that will cause real numbers to be displayed in scientific notation. I think it's clearer if you use something like %0.2f as your format string.

Upvotes: 6

Oli
Oli

Reputation: 16065

When you use matlab, avoid using loops, it makes your code very slow, and it is much longer.

You can do the same thing by doing that:

[y x]=ndgrid(1:size(matrix_img,1),1:size(matrix_img,2));
n=max(matrix_img(:));
for k=1:n
  cy=mean(y(matrix_img==k));
  cx=mean(x(matrix_img==k));
  fprintf('Centroid of Object %d is %2.2g and %2.2g \n', k, cx, cy);
end

(Maybe you want to swap x and y in that code)

Upvotes: 3

Related Questions