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")

参考

| | | | | | |

関連するトピック