下面的代码使用bwboundaries
根据对象的圆度对其进行分类。
它估计每个对象的面积和周长,并使用这些结果形成一个简单的度量标准,该度量标准使用以下度量标准指示对象的圆度:
metric = 4*pi*area/perimeter^2
仅对于一个圆,此度量等于1;对于其他任何形状,该度量均小于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'])
答案 0 :(得分:2)
您还可以将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 ID对其进行命名。因此,如果存在多个满足条件的斑点或圆形对象,则将它们全部保存。