主要内容

このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。

イメージ内の円形オブジェクトの検出と測定

この例では、イメージ内の円または円形オブジェクトを自動的に検出し、検出された円を可視化する方法を説明します。

手順 1: イメージの読み込み

さまざまな色の円形プラスチック チップのイメージを読み取って表示します。検出対象となるたくさんの円があるだけでなく、円を検出するという観点でこのイメージを捉えると、いくつかの興味深い点が見えてきます。

  1. さまざまな色のチップがあり,これらは背景とのコントラストも異なっています。青と赤のチップはこの背景とのコントラストがはっきりとしています。一方,一部の黄色のチップは背景とのコントラストがあいまいです。

  2. 他のチップの上に重なっているチップもあれば,お互い触れそうなくらいに近いものもあります。オブジェクトの境界の重なりとオブジェクトのオクルージョンは,オブジェクト検出においては常に難題です。

rgb=imread('coloredChips.png'); imshow(rgb)

手順2:円を探索するための半径の範囲の判別

関数画直线を使用して、円の適切な半径の範囲を検索します。チップのおおよその直径の上に線を描画します。

d=抽绳;

ライン 投资回报率の長さはチップの直径です。通常のチップの直径は 40 ~ 50 ピクセルの範囲にあります。

pos=d.位置;diffPos=diff(pos);直径=hypot(diffPos(1),diffPos(2))
直径=45.3448

手順 三:円を検出する最初の試行

関数imfindcirclesにより、ある半径の範囲を持つ円を検索します。20 ~ 25 ピクセルの範囲の半径を持つ円を検索します。その前に、背景と比較してオブジェクトが明るいか暗いかを確認しておきます。これを確認するために、このイメージのグレースケール バージョンを見てみましょう。

灰度图像=rgb2gray(rgb);imshow(灰度图像)

背景がかなり明るく、ほとんどのチップが背景より暗いことがわかります。しかし、既定では、imfindcirclesは背景よりも明るい円形オブジェクトを検出します。このため,imfindcirclesでパラメーター '对象极性'を '黑暗的に設定して、暗い円を探索します。

[中心,半径]=imfind圆(rgb,[20 25],“对象极性”,“黑暗”)
中心=[]半径=[]

出力中心半径が空になっていますが、これは円が検出されなかったことを表しています。このような結果になることはよくあります。これは、imfindcirclesが円の"検出器"であり、多くの検出器と同じように、imfindcirclesには感度を決定する内部の"検出しきい値"があるためです。つまり,検出器の特定の(円の)検出が"有効"であると見なされるには、その検出に対する信頼度が一定のレベルを超えていなければなりません。imfindcirclesにはパラメーター“灵敏度”があり,これを使用して,この内部しきい値と,結果的に得られるアルゴリズムの感度を制御できます。灵敏度的を高い値にすると検出しきい値が低くなり,検出される円が多くなります。これは,ホームセキュリティシステムで使用されるモーション検出器での感度制御と似ています。

手順 4: 検出感度を上げる

チップのイメージに戻ります。既定の感度レベルではすべての円が内部しきい値より低く、そのために円が検出されなかった可能性があります。敏感度'は 0から 1.までの数値で、既定では 0.85に設定されています。敏感度'を 0.9に上げます。

[中心,半径]=imfind圆(rgb,[20 25],“对象极性”,“黑暗”,...“敏感”,0.9)
中心=8×2146.1895 198.5824 328.8132 135.5883 130.3134 43.8039 175.2698 297.0583 312.2831 192.3709 327.1316 297.0077 243.9893 166.4538 271.5873 280.8920
半径=8×123.1604 22.5710 22.9576 23.7356 22.9551 22.9995 22.9055 23.0298

今回は、imfindcirclesが円をいくつか検出しました。正確には、8.つです。中心には円の中心の場所が格納されており,半径にはこれらの円の推定半径が格納されています。

手順 5: イメージ上での円の描画

関数维斯圈を使用すると,イメージ上に円を描画できます。imfindcirclesからの出力変数中心半径は、维斯圈に直接渡すことが可能です。

imshow(rgb)h=内圆(中心、半径);

円の中心は正しく配置されており、対応する半径も実際のチップとうまく一致しているようです。しかし、まだ検出されていないチップがかなりあります。敏感度'をもう少し高い 0.92に上げてみましょう。

[中心,半径]=imfind圆(rgb,[20 25],“对象极性”,“黑暗”,...“敏感”,0.92);长度(中心)
ans = 16

“敏感性”を上げたら、円の数も増えました。これらの円をイメージ上にもう一度プロットします。

删除(h)%删除先前绘制的圆h = viscircles(中心、半径);

手順 6: 円の検出に 2.つ目の方法 (2 段階) を使用

この方法の方が、よい結果になります。imfindcirclesには円を検出するための方法が 2.つあります。ここまでは、円を検出するために"位相符号化"メソッドという既定のメソッドを使用してきました。imfindcirclesには、一般に"2 段階"メソッドと呼ばれているもう1つのメソッドがあります。2段階メソッドを使用して結果を表示します。

[中心,半径]=imfind圆(rgb,[20 25],“对象极性”,“黑暗”,...“敏感”,0.92,“方法”,“二级”);删除(h)h=内圆(中心、半径);

0.92の 体贴で、2.段階メソッドのほうが多くの円を検出しています。概略を述べると、これらの 2.つのメソッドは異なる長所をもっていて、補完しあっています。通常、位相符号化メソッドは 2.段階メソッドよりも速く、ノイズに対するロバスト性がわずかに優れています。しかし、2.段階メソッドと同じ数を検出するには、'敏感度'レベルを高くしなければなりません。たとえば、位相符号化メソッドで '敏感度'レベルを 0.95に上げると、同じ数のチップが検出されます。

[中心,半径]=imfind圆(rgb,[20 25],“对象极性”,“黑暗”,...“敏感”,0.95); 删除(h)内圆(中心、半径);

imfindcirclesの両方のメソッドが、一部だけ見えている (隠れている) チップの中心と半径を正確に検出することに注意してください。

手順7:まだ検出されない円がある理由

最後の結果を見てみると,面白いことに,imfindcirclesはイメージ内の黄色のチップを検出していません。黄色のチップは,背景とのコントラストが強くありません。それどころか,背景とかなり近い強度をもっているようです。黄色のチップは,想定していたほど背景より”暗く”ないということでしょうか。これを確認するために,このイメージのグレースケールバージョンをもう一度表示します。

imshow (gray_image)

手順8:イメージ内の“明るい”円の検出

黄色のチップは、背景と比較すると、ほとんど同じ強度です。背景より明るいかもしれません。そこで、黄色のチップを検出するために、'对象极性'を '光明的に変更します。

[centersBright,radibright]=imfind圆(rgb,[20 25],...“对象极性”,“光明”,“敏感”,0.92);

手順 9: 異なる色での "明るい" 円の描画

维斯圈の“颜色”パラメーターを変更して,異なる色で“明るい”円を描画します。

imshow(rgb)hBright=内圆(中心光、半径光、,“颜色”,“b”);

検出されていなかった黄色のチップが 3.つ検出されましたが、黄色のチップがまだ 1.つ抜け落ちています。これらの黄色のチップは、この背景では他のチップのように "際立って"いないため,検出が困難です。

手順 10:“EdgeThreshold”の値を下げる

imfindcirclesには 'EdgeThreshold'という別のパラメーターがあり、ここで役に立ちます。円を検出するために、imfindcirclesはイメージ内のエッジ ピクセルのみを使用します。これらのエッジ ピクセルは、基本的には高い勾配値をもつピクセルです。EdgeThreshold'パラメーターは、あるピクセルがエッジ ピクセルであると見なされ計算に組み込まれるには、そのピクセルでの勾配値がどの程度"高く"なければならないかを制御します。このパラメーターに高い(1に近い)値を指定すると,強いエッジ(高い勾配値)のみが計算に組み込まれ,低い(0に近い)値を指定すると,許容範囲が広くなり,弱いエッジ(低い勾配値)も計算に組み込まれます。検出されない黄色のチップの場合は,コントラストが低いため,チップ外周の境界ピクセルの一部は低い勾配値をもつことが予想されます。したがって,EdgeThresholdパラメーターの値を下げて,黄色のチップのほとんどのエッジピクセルが計算に組み込まれるようにします。

[centersBright,radibright,metricBright]=imfind圆(rgb,[20 25],...“对象极性”,“光明”,“敏感”,0.92,“EdgeThreshold”,0.1);删除(hBright)hBright=内圆(中心亮度、半径亮度、,“颜色”,“b”);

手順 11: "暗い" 円と "明るい" 円を同時に描画

これで、imfindcirclesはすべての黄色のチップと1つの緑のチップを検出しました。これらのチップを青で,‘ObjectPolarityを‘黑暗’にして先に検出していた他のチップを赤で描画します。

h = viscircles(中心、半径);

すべての円が検出されています。最後に、注意の必要な点があります。パラメーターを検出率が高くなるような値に変更すると、検出される円は増えますが、円を誤って検出する可能性も高くなります。正しく検出できる円の数 (検出率) と誤って検出される円の数 (誤認率) の間にはトレードオフがあります。

円探しをお楽しみください!

参考

|

関連するトピック