Центроид объектов / связанных компонентов в Matlab? - PullRequest
0 голосов
/ 26 ноября 2011

Я пытаюсь найти центр тяжести объектов. Я уже реализовал маркировку подключенных компонентов и разработал следующий код для Centroid, он дает результат, но не дает правильный результат: У меня есть следующая матрица вывода, т.е. 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

и следующий код

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

Это дает результат как:

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 

Результат объекта 5 правильный, объект 2 совершенно неправильный, а объект 1 частично неправильный ... что мне делать?

Ответы [ 2 ]

6 голосов
/ 26 ноября 2011

Полученные вами значения являются точными центроидами для этих объектов.Так что вы можете определить, что вы ожидаете получить в качестве результата.

Чтобы сделать это более ясным, я раскрасил объекты в вашей матрице.По симметрии вашей декартовой сетки, должно быть равное количество точек слева и справа от вашей центроида и одинаковое для выше / ниже центроида.Я нарисовал фигуру с вашими объектами в цвете вместе с линиями, чтобы представить горизонтальные и вертикальные центральные линии.Это линии, для которых у нас есть равное количество точек слева / справа (или выше / ниже) из них, которые являются частью определенного объекта.

Их пересечение - это центроид, так что вы можете видетьдля объекта 5 (синего цвета) центр тяжести находится на (8, 14).Для двух других объектов эти центральные линии не лежат на вашей целочисленной сетке: красный объект (1) имеет центр тяжести на (12.5, 7), который также является результатом вашего кода, а зеленый объект (2) центрируется вокруг(2.5, 10.5).

Вам придется либо жить с неточностью, введенной округлением центроидов (например, round(cx)), либо вам придется жить с нецелыми координатами центроидов.

Graphical representation

Кроме того, я также рекомендую вам векторизовать ваш код, как показало oli: это позволяет быстрее выполнять ваш код, и его легче понять, если вы немного знакомы с MATLAB, чем forloops.

Возможно, небольшое замечание относительно вашего строкового представления: не используйте %d для нецелых чисел, поскольку вы видите, что реальные цифры будут отображаться в научной нотации.Я думаю, что будет понятнее, если вы используете что-то вроде %0.2f в качестве строки формата.

3 голосов
/ 26 ноября 2011

Когда вы используете matlab, избегайте использования циклов, это делает ваш код очень медленным и намного длиннее.

Вы можете сделать то же самое, сделав это:

[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

(Может быть, вы хотите поменять местами x и y в этом коде)

...