Как вырезать обнаруженный объект (круг) из изображения и сохранить его?

В приведенном ниже коде объекты классифицируются по их округлости с помощью bwboundaries.

Он оценивает площадь и периметр каждого объекта и использует эти результаты для формирования простой метрики, указывающей округлость объекта со следующей метрикой:

metric = 4*pi*area/perimeter^2

Эта метрика равна 1 только для круга и меньше единицы для любой другой формы. Но в этом коде я использую порог 0,80, так что только объекты со значением метрики больше 0,80 будут классифицироваться как круглые.

Мой вопрос: когда данный объект классифицируется как круглый, как я могу вырезать его из исходного изображения img (не I и не bw) и сохранить его как новое изображение?

Я думаю, что для этого достаточно использовать матрицу меток и граничную матрицу, но до сих пор не знаю, как ими манипулировать.

img=imread('cap.png');
I = rgb2gray(img);

% Step 2: Threshold the Image
bw1 = imbinarize(I);
bw = imcomplement(bw1);

% Step 3: Remove the Noise
bw = bwareaopen(bw,30);      % remove small objects
bw = imfill(bw,'holes');    


% Step 4: Find the Boundaries
[B,L] = bwboundaries(bw,'noholes');
imshow(label2rgb(L,@jet,[.5 .5 .5]))
hold on
for k = 1:length(B)
  boundary = B{k};
  plot(boundary(:,2),boundary(:,1),'w','LineWidth',2)
end



% Step 5: Determine which Objects are Round
stats = regionprops(L,'Area','Centroid');
threshold = 0.80;
% loop over the boundaries
for k = 1:length(B)

  % obtain (X,Y) boundary coordinates corresponding to label 'k'
  boundary = B{k};

  % compute a simple estimate of the object's perimeter
  delta_sq = diff(boundary).^2;    
  perimeter = sum(sqrt(sum(delta_sq,2)));

  % obtain the area calculation corresponding to label 'k'
  area = stats(k).Area;

  % compute the roundness metric
  metric = 4*pi*area/perimeter^2;

  % display the results
  metric_string = sprintf('%2.2f',metric);

  % Test if the current object classified as a round
  if metric > threshold
    % HERE, I want to crop the current object from the 'img' 
    % and save it as a new image 
  end

end

title(['Metrics closer to 1 indicate that ',...
       'the object is approximately round'])
Применение градиента к изображению с помощью CSS
Применение градиента к изображению с помощью CSS
Здравствуйте, братья и сестры, как дела? Недавно я застрял на применении градиента к изображению. Я применял это много раз, но иногда наши требования...
Получение URL-адреса изображения курса в Moodle с помощью PHP
Получение URL-адреса изображения курса в Moodle с помощью PHP
Moodle - это популярная система управления обучением с открытым исходным кодом, используемая многими учебными заведениями и организациями по всему...
2
0
117
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете дополнительно добавить атрибут BoundingBox к regionprops, который эффективно даст вам пределы того, где BLOB-объект простирается в ограничивающей рамке, и вы можете использовать их, чтобы обрезать изображение и сохранить его. Он будет иметь вид [x y width height], где x и y — верхние левые координаты ограничивающей рамки, а width и height — конечно, ширина и высота. x будет координатой столбца, а y будет координатой строки. Вы можете использовать imcrop, чтобы окончательно обрезать изображение.

img=imread('cap.png');
I = rgb2gray(img);

% Step 2: Threshold the Image
bw1 = imbinarize(I);
bw = imcomplement(bw1);

% Step 3: Remove the Noise
bw = bwareaopen(bw,30);      % remove small objects
bw = imfill(bw,'holes');    


% Step 4: Find the Boundaries
[B,L] = bwboundaries(bw,'noholes');
imshow(label2rgb(L,@jet,[.5 .5 .5]))
hold on
for k = 1:length(B)
  boundary = B{k};
  plot(boundary(:,2),boundary(:,1),'w','LineWidth',2)
end



% Step 5: Determine which Objects are Round
stats = regionprops(L,'Area','Centroid','BoundingBox'); % Change
threshold = 0.80;
% loop over the boundaries
for k = 1:length(B)

  % obtain (X,Y) boundary coordinates corresponding to label 'k'
  boundary = B{k};

  % compute a simple estimate of the object's perimeter
  delta_sq = diff(boundary).^2;    
  perimeter = sum(sqrt(sum(delta_sq,2)));

  % obtain the area calculation corresponding to label 'k'
  area = stats(k).Area;

  % compute the roundness metric
  metric = 4*pi*area/perimeter^2;

  % display the results
  metric_string = sprintf('%2.2f',metric);

  % Test if the current object classified as a round
  if metric > threshold
    % HERE, I want to crop the current object from the 'img' 
    % and save it as a new image 

    % New - crop image
    bb = stats(k).BoundingBox;
    img_crop = imcrop(img, bb);

    % New - Save the image
    imwrite(img_crop, sprintf('crop%d.png', k));
  end

end

title(['Metrics closer to 1 indicate that ',...
       'the object is approximately round'])

Обратите внимание, что я использую imwrite для сохранения урожая в файл, и он назван в зависимости от идентификатора BLOB-объекта, на который вы смотрите. Поэтому, если есть несколько больших двоичных объектов или круглых объектов, удовлетворяющих критериям, вы сохраните их все.

Спасибо большое. это работает. За исключением: stats(k).BoundingBox вместо B(k).BoundingBox

Taha Kamil 24.05.2019 19:47

@TahaKamil Всегда пожалуйста. Если у вас больше нет вопросов или если ваша проблема решена, сообщите сообществу, приняв этот ответ. Это означает, что мы решили ваши проблемы. Удачи!

rayryeng 24.05.2019 19:48

@TahaKamil Да, извините за это! В моем первоначальном редактировании был B(k), но я изменил его некоторое время назад. Вы, наверное, видели первую версию и не видели мою правку. Ой!

rayryeng 24.05.2019 19:49

Другие вопросы по теме