如何从图像中裁剪出检测到的物体(圆形)并将其存储?

时间:2019-05-24 17:17:37

标签: image matlab image-processing

下面的代码使用bwboundaries根据对象的圆度对其进行分类。

它估计每个对象的面积和周长,并使用这些结果形成一个简单的度量标准,该度量标准使用以下度量标准指示对象的圆度:

metric = 4*pi*area/perimeter^2

仅对于一个圆,此度量等于1;对于其他任何形状,该度量均小于1。但是使用此代码,我将阈值设置为0.80,以便仅将度量值大于0.80的对象分类为圆形。

我的问题是,当给定对象归类为圆形时,如何从原始图像img(不是Ibw)中裁剪出来并将其另存为新图像图片?

我认为使用标签矩阵和边界矩阵足以做到这一点,但仍然不知道如何操作它们。

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'])

1 个答案:

答案 0 :(得分:2)

您还可以将BoundingBox属性添加到regionprops,这将有效地为您提供Blob在边界框内的延伸位置的限制,您可以使用它们来裁剪图像并将其保存。格式为[x y width height],其中xy是边界框的左上角坐标,而widthheight当然是宽度和高度。 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对其进行命名。因此,如果存在多个满足条件的斑点或圆形对象,则将它们全部保存。