Main Content

标识圆形目标

此示例说明如何使用边界跟踪例程 bwboundaries 根据对象的圆度对其进行分类。

步骤 1:读取一个图像

pills_etc.png 中进行读取。

RGB = imread("pillsetc.png");
imshow(RGB)

步骤 2:阈值化图像

将图像转换为黑白,以便使用 bwboundaries 为边界跟踪做准备。

I = im2gray(RGB);
bw = imbinarize(I);
imshow(bw)

步骤 3:预处理图像

使用形态学函数,删除不属于感兴趣对象的像素。

删除包含少于 30 个像素的所有对象。

minSize = 30;
bw = bwareaopen(bw,minSize);
imshow(bw)

填充笔帽中的间隙。

se = strel("disk",2);
bw = imclose(bw,se);
imshow(bw)

填充任何孔洞,以便可以使用 regionprops 来估计每个边界所包围的面积

bw = imfill(bw,"holes");
imshow(bw)

步骤 4:找到边界

只关注外边界。指定 "noholes" 选项将通过阻止 bwboundaries 搜索内部轮廓来加快处理速度。

[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
title("Objects with Boundaries in White")

步骤 5:确定哪些对象为圆形

使用 regionprops 函数估计所有对象的圆度和质心。对于理想圆,圆度度量值等于 1,而对于其他形状,圆度度量值小于 1。

stats = regionprops(L,"Circularity","Centroid");

可以通过设置适当的阈值来控制分类过程。此示例中使用 0.94 的阈值,以便只将药丸分类为圆形。

threshold = 0.94;

遍历检测到的边界。对于每个对象:

  • 获取 (x,y) 边界坐标和圆度测量值

  • 将圆度测量值与阈值进行比较。如果圆度超出阈值,则计算质心的位置并将质心显示为黑色圆圈。

  • 在对象上以黄色文本显示圆度测量值。

for k = 1:length(B)

  % Obtain (X,Y) boundary coordinates corresponding to label "k"
  boundary = B{k};
  
  % Obtain the circularity corresponding to label "k"
  circ_value = stats(k).Circularity;
  
  % Display the results
  circ_string = sprintf("%2.2f",circ_value);

  % Mark objects above the threshold with a black circle
  if circ_value > threshold
    centroid = stats(k).Centroid;
    plot(centroid(1),centroid(2),"ko");
  end
  
  text(boundary(1,2)-35,boundary(1,1)+13,circ_string,Color="y",...
       FontSize=14,FontWeight="bold")
  
end
title("Centroids of Circular Objects and Circularity Values")

另请参阅

| | | | | | |

相关主题