Как рисовать квадраты определенной области пикселей с центром в центроиде

Я написал некоторый код в MATLAB, который преобразует изображение (звезд) в двоичное изображение с использованием заданного порога, а затем помечает каждый кластер пикселей (звезд), превышающий этот порог. Маркировка производит вывод: например.

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

Таким образом, каждый кластер из 1, 2, 3 и т. д. представляет собой звезду. Я использовал ответ, предоставленный по этой ссылке: Как найти все связанные компоненты в бинарном изображении в Matlab? чтобы пометить пиксели. После этого код находит площадь и центроиды каждого кластера пикселей.

Теперь я хочу включить некоторый код, который будет автоматически рисовать прямоугольники определенной площади пикселя с центром в каждом центроиде. Например, центроид имеет местоположение [41, 290], а кластер пикселей имеет площадь 6 пикселей, я хочу нарисовать блок площадью nx 6 пикселей с центром блока [41, 290]. . И мне нужно это, чтобы перебрать каждый центроид и сделать то же самое.

Как мне это сделать?

Центроид и код области показаны ниже.

%% Calculate centroids of each labelled pixel cluster within binary image

N = max(B(:));    % total number of pixel labels generated in output array B
sum_v = zeros(N,1);    % create N x 1 array of 0's
sum_iv = zeros(N,1);    % "
sum_jv = zeros(N,1);    % "
for jj=1:size(B,2)    % search through y positions
   for ii=1:size(B,1)    % search through x positions
      index = B(ii,jj);
      if index>0     
         sum_v(index) = sum_v(index) + 1;
         sum_iv(index) = sum_iv(index) + ii;
         sum_jv(index) = sum_jv(index) + jj;
      end
   end
end
centroids = [sum_jv, sum_iv] ./ sum_v    % calculates centroids for each cluster

for pp = 1:N
    id_index = find(B == pp);
    pixels = numel(id_index);    %  counts number of pixels in each cluster    
    area(pp) = pixels;    % area = no. of pixels per cluster
end

hold on
for i=1:size(centroids,1)
    plot(centroids(i,1),centroids(i,2),'rx','MarkerSize',10)
end
hold off

person Community    schedule 10.05.2019    source источник
comment
'ID_counter' undefined near line 24 column 12. Должно быть просто N?   -  person HansHirse    schedule 10.05.2019
comment
Ах да, я указал ID_counter ранее в своем коде, но N тоже должен работать.   -  person    schedule 10.05.2019
comment
Тогда вы должны отредактировать свой код/вопрос. Люди могут разочароваться в том, чтобы помочь вам, если предоставленный код не работает «из коробки».   -  person HansHirse    schedule 10.05.2019
comment
Я добавил полный код сейчас. Должно все работать.   -  person    schedule 10.05.2019
comment
Ах, нет! Ваш предыдущий код был - за исключением этой незначительной проблемы - в порядке! Теперь вы предоставили много ненужного кода, который лишний. Просто отредактируйте исходный код таким образом, чтобы он работал как есть. (Я откатил ваш исходный код.)   -  person HansHirse    schedule 10.05.2019
comment
Хорошо, спасибо, я изменил «ID_counter» на «N».   -  person    schedule 10.05.2019


Ответы (1)


Мне удалось решить это, выполнив следующие действия:

  • Разделите координаты (x, y) центроидов на x и y.
  • Вычтите или добавьте определенное количество «пикселей» к каждой координате x и y, чтобы вычислить xmin, xmax, ymin, ymax.
  • Ограничьте 4 координаты (ограничивающую рамку), чтобы они поместились на изображении.
  • Найдите ширину и высоту каждой ограничивающей рамки, вычитая xmin из xmax, ymax из ymin и т. д.
  • Затем используйте цикл for и функцию прямоугольника, чтобы пройтись по списку центроидов и применить координаты ограничивающей рамки к изображению.

Код ниже.

N = max(B(:));    % total number of pixel labels generated in output array
sum_total = zeros(N,1);    % create N x 1 array of 0's
sum_yv = zeros(N,1);    % "
sum_xv = zeros(N,1);    % "
for xx=1:size(B,2)    % search through y positions
   for yy=1:size(B,1)    % search through x positions
      index = B(yy,xx);
      if index>0
          sum_total(index) = sum_total(index) + 1;
          sum_yv(index) = sum_yv(index) + yy;
          sum_xv(index) = sum_xv(index) + xx;
      end
   end
end
centroids = [sum_xv, sum_yv] ./ sum_total    % calculates centroids for each cluster


x_lower_limits = centroids(:,1)-4;
y_lower_limits = centroids(:,2)+4;    % lower on image means larger y coord number
x_upper_limits = centroids(:,1)+4;
y_upper_limits = centroids(:,2)-4;    % higher on image means lower y coord number

x_lower_limits(x_lower_limits<1)=1;    % limit smallest x coord to image axis (1,y)
y_lower_limits(y_lower_limits>size(binary_image,1))=size(binary_image,1);    % limit largest y coord to image axis (x,517)
x_upper_limits(x_upper_limits>size(binary_image,2))=size(binary_image,2);    % limit largest x coord to image axis (508,y)
y_upper_limits(y_upper_limits<1)=1;    % limit smallest y coord to image axis (x,1)


width = x_upper_limits(:,1) - x_lower_limits(:,1);    % width of bounding box
height = y_lower_limits(:,1) - y_upper_limits(:,1);    % height of bounding box

% for pp = 1:ID_counter
%     id_index = find(B == pp);
%     pixels = numel(id_index);    %  counts number of pixels in each cluster    
%     area(pp) = pixels;    % area = no. of pixels per cluster
%     gray_area = area*2;
% end


hold on
for xl=1:size(x_lower_limits,1)
                rectangle('Position',[x_lower_limits(xl,1) y_upper_limits(xl,1) width(xl,1) height(xl,1)],'EdgeColor','r')
end
for i=1:size(centroids,1)
    plot(centroids(i,1),centroids(i,2),'rx','MarkerSize',10)
end
hold off
person Community    schedule 15.05.2019