В приведенном ниже коде объекты классифицируются по их округлости с помощью 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'])
Вы можете дополнительно добавить атрибут 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-объекта, на который вы смотрите. Поэтому, если есть несколько больших двоичных объектов или круглых объектов, удовлетворяющих критериям, вы сохраните их все.
@TahaKamil Всегда пожалуйста. Если у вас больше нет вопросов или если ваша проблема решена, сообщите сообществу, приняв этот ответ. Это означает, что мы решили ваши проблемы. Удачи!
@TahaKamil Да, извините за это! В моем первоначальном редактировании был B(k)
, но я изменил его некоторое время назад. Вы, наверное, видели первую версию и не видели мою правку. Ой!
Спасибо большое. это работает. За исключением: stats(k).BoundingBox вместо B(k).BoundingBox