如何从图像中裁剪出检测到的对象(圆圈)并存储它?
Posted
技术标签:
【中文标题】如何从图像中裁剪出检测到的对象(圆圈)并存储它?【英文标题】:How to crop out a detected object (circle) from image and store it? 【发布时间】:2019-05-24 17:17:36 【问题描述】:下面的代码使用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 = Bk;
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 = Bk;
% 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'])
【问题讨论】:
【参考方案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 = Bk;
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 = Bk;
% 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 命名。因此,如果有多个满足条件的 blob 或圆形对象,您将全部保存。
【讨论】:
非常感谢。它正在工作。除了它是: stats(k).BoundingBox 而不是 B(k).BoundingBox @TahaKamil 不客气。如果您没有更多问题或您的问题已得到解决,请通过接受此答案让社区知道。这意味着我们已经解决了您的问题。祝你好运! @TahaKamil 是的,很抱歉!我最初的编辑有B(k)
,但我不久前改变了它。您可能看到了第一个版本,但没有看到我的编辑。糟糕!以上是关于如何从图像中裁剪出检测到的对象(圆圈)并存储它?的主要内容,如果未能解决你的问题,请参考以下文章