スケールおよび回転不変テンプレートのマッチング


12

スケールと回転に不変なテンプレートマッチングの方法を探しています。私はすでにいくつか試してみましたが、それらは私の例にとってそれほどうまく機能しなかったか、実行するのに永遠にかかりませんでした。SIFTおよびSURF機能の検出は完全に失敗しました。Log-Polar Template Matching関数も実装しようとしましたが、まだ終りませんでした(正確な方法はわかりませんでした)。

これらの記事(最初はドイツ語)

http://cvpr.uni-muenster.de/teaching/ss08/seminarSS08/downloads/Wentker-Vortrag.pdf

http://www.jprr.org/index.php/jprr/article/viewFile/355/148

その方法について読みました。極座標のマッピングは機能しましたが、それが正しいかどうかはわかりません。画像は次のようになります。

source_log_polar.png http://www.shareimages.com/images/pics/0/0/3/62394-pZSfl5WenZysnpyVnKg-source_log_polar.png

template_log_polar.png

そして、これらの2つの画像をOpenCVのテンプレートマッチング機能でマッチングした後、私はその結果を得ました

match_log_polar.png

今はどうすればいいのかわからない。

私のテンプレートは、青写真と青写真自体を構築する上で常にシンプルなシンボルです。シンボルのサイズと向きは異なる場合があります。

たとえば、私の単純な青写真:

ここに画像の説明を入力してください

そして私のテンプレート

ここに画像の説明を入力してください

この例では、テンプレートは1つだけですが、設計図では、サイズや向きが含まれているものも含め、すべてのオカレンスを見つける必要があります。

誰も私がこれを解決する方法を持っていますか?

編集:

アンドレイのアプローチへの追加。放射状プロファイルの距離キャプチャアルゴリズム。(EmguCVを使用)

private float[] getRadialProfile( Image<Gray, byte> image, Point center, int resolution )
 {

 var roi = image.ROI;

 if ( !roi.Contains( center ) )
  {
   return null;
  }

 var steps = resolution;
 var degreeSteps = 360 / (double)resolution;
 var data = image.Data;
 var peak = 0.0f;
 var bottom = double.MaxValue;
 var bottomIndex = 0;
 var width = roi.Width;
 var height = roi.Height;
 var minX = roi.X;
 var minY = roi.Y;

 float[] distances = new float[resolution];
 for ( var i = 0; i < steps; i++ )
  {
   var degree = i * degreeSteps;
   var radial = degree * Math.PI / 180.0;
   var dy = Math.Sin( radial );
   var dx = Math.Cos( radial );

   var x = (double)center.X;
   var y = (double)center.Y;

   while ( true )
    {
    x += dx;
    y += dy;
    if ( x >= minX + width || y >= minY + height || x <= minX || y <= minY )
     {
      x = -1;
      y = -1;
      break;
     }
    var pixel = data[(int)y, (int)x, 0];
    if ( pixel == 0 )
     {
      break;
     }
    }

    float distance = 0.0f;
    if ( x != -1 && y != -1 )
    {
      distance = (float)Math.Sqrt( Math.Pow( (center.X - x), 2 ) + Math.Pow( (center.Y - y), 2 ) );
    }

    distances[i] = distance;
    if ( distance > peak )
    {
      peak = distance;
    }
    if ( distance < bottom )
    {
      bottom = distance;
      bottomIndex = i;
    }
   }

    // Scale invariance. Divide by peak
   for ( var i = 0; i < distances.Length; i++ )
   {
     distances[i] /= peak;
   }

    // rotation invariance, shift to lowest value
   for ( var i = 0; i < bottomIndex; i++ )
   {
     distances.ShiftLeft(); // Just rotates the array nothing special
   }

   return distances;
}

dsp.SEへようこそ。お手伝いさせていただきますが、より正確な情報を提供していただければ幸いです。SIFTとSURFが「完全に失敗した」とはどういう意味ですか?彼らは何を検出/一致しましたか?また、私は個人的にLog-Polar Template Matchingについて知りませんが、あなたが試みた場合、正確にどこに問題がありましたか?
ペネロペ

SIFTとSURFの特徴検出では、テンプレート画像に特徴が見つかりませんでした。テンプレートの情報が少なすぎるように見えました(その小さな弓と線だけです)。Log-Polarマッチングについては、説明されているが、その背後にある正確な数学ではない論文を見つけました。検索して追加します。
アーントビーバースタイン


ねえ、ここの人はドイツ語を理解できる人はほとんどいないだろう、と私は思う:Dしかし、他のすべてのために:あなたは自分の投稿を編集して、コメントではなく正しい場所に新しい情報を追加することができる。そして、あなたはまだあなたが何に問題があったかを正確に言っていませんでした。
ペネロペ

3
「ドイツ語の記事」の著者には英語の記事があります-www-cs.engr.ccny.cuny.edu/~wolberg/pub/icip00.pdf(googleに感謝)
SergV

回答:


6

はるかに簡単な方法で問題を解決できると思います。設計図を扱っていることを考慮すると、エッジの接続性、ノイズ、およびSIFTとSURFが対応するために構築された他の多くのものについて心配するべきではありません。テンプレートは、特定のエッジ形状を持つ中空の形状です。

したがって、私の推奨事項は次のとおりです。

  • 周囲を歩き回って、テンプレートの中心付近のエッジの距離のプロファイルを見つけます。これは、テンプレートの放射状プロファイルです。最大距離で除算し、スケール不変にします。最小の距離が最初になるようにベクトルを回転させ、回転不変にします。(テンプレートに支配的な距離がない場合は、ステップ2を後で変更できます)

ここに画像の説明を入力してください

  • 画像内のブロブを見つけます。パート(1)で説明した放射状プロファイルを計算し、正規化相関により2つのベクトルを比較します。テンプレートに支配的な距離がない場合、相関は正規化された相互相関になり、最大を選択します)。ある程度のしきい値を超えた人は一致すると見なされます。

開始するためのMatlabコードを次に示します。特定のBLOBの距離プロファイルを見つける部分を作成し、テンプレート用に計算しました。

function Doors
    im = imread('http://i.stack.imgur.com/Tf8EV.png');
    im = im(:,:,1);
    template = imread('http://i.stack.imgur.com/PlP4i.png');
    template = template(:,:,1);

    blobs = regionprops(template>0,'Area','Image');
    largestBlob = GetLargestBlob(blobs);
    [prof,edgeImage] = GetBlobRadialProfile(largestBlob);

    figure;
    subplot(1,2,1);plot(prof); title('Radial profile')
    subplot(1,2,2);imshow(edgeImage); title('Template');

end

function [prof,edgeImage] = GetBlobRadialProfile(blob)
    paddedImage = padarray( blob.Image,[8 8]);
    erodedImage = imerode(paddedImage,strel('disk',1));
    edgeImage = xor(erodedImage,paddedImage);

    c = regionprops(paddedImage,'Centroid');
    cx  = c.Centroid(1);
    cy  = c.Centroid(2);

    [y,x] = find(edgeImage);
    rad = (x(:)-cx).^2 + (y(:)-cy).^2;
    [~,minIndex] = min(rad);
    contour = bwtraceboundary(edgeImage, [y(minIndex), x(minIndex)],'N');
    prof = (contour(:,2)-cx).^2 + (contour(:,1)-cy).^2;
    prof = prof./max(prof);
end

function largestBlob = GetLargestBlob(blobs)    
    area = [blobs.Area];
    [~,index] = max(area);
    largestBlob = blobs(index);
end

これは閉じていない図形では機能しないと思いますか?または、シェイプのこれらの「穴」をスキップしますか。
アーントビーバースタイン

@ArndtBieberstein、うん、それは閉じた形状に対してのみ機能します。私はそれを拡張する何らかの方法があるべきだと思います。
アンドレイRubshtein

OpenCVにはbwtraceboundary関数が含まれていないため、独自に作成し、穴を「スキップ」してゼロで埋めました。以下に、結果がどのように見えるかを示す小さな例を示します。5各テンプレートのプロット。赤い点は開始点です。サンプルプロット
アルントBieberstein

@ArndtBieberstein、とても素敵!完了したら、結果を私たちと共有できるかもしれません。
アンドレイRubshtein

確かに、コードはそれほど良いものでもパフォーマンスのあるものでもありませんが、機能します。質問の下に添付します。C#で書かれています(私はEmguCVを使用しています)
Arndt Bieberstein

3

IIT MadrasのAnurag Mittal教授の講演に基づいて、私ができることの基本的な考え方を以下に示します。

アイデアは形状ベースのオブジェクト検出ですが、明らかに他の場所でも拡張できます。

  1. バークレーのエッジ検出器を使用してエッジを計算します。
  2. 得られたエッジを接続します。「グローバルオブジェクト境界検出」。
  3. 面取り距離またはハウストオフ距離を使用した形状マッチング。

同じことに関する彼の論文は次の場所で入手可能です:Multi-Stage Contour based Detection of Deformable Objects。

一方、コーナー検出アルゴリズムは、そこにあるテンプレート機能で動作するため、SIFTは動作するはずです。

注:SIFTは完全に回転不変ではありません。60度以上の回転には対応できません。そのため、複数のテンプレートを作成することをお勧めします。

対数極ベースのFourier-Mellin変換の場合:変換のサンプリング方法によって情報が失われます。


この方法は本当に有望です!リンクを開くことができませんが、アプローチをグーグルで検索しました。私は、SIFTが完全に回転不変ではないというSIFTを知りませんでした!非常に良い答えです!+1
アーントビーバースタイン

1
面取り距離とそれがどのように機能するかについてはほとんど見つけられませんでした。これを探している人はこのリンクを試しください。
アーントビーバースタイン

@Naresh SIFTは、平面の大きな回転に対して回転不変ではありません。同じ平面ではありません。
a-Jays

1

あまり考えたことはありませんが、従来のフーリエ記述子(FD)を使用すれば、問題なく堅牢なソリューションを得ることができると確信しています。あなたの問題はそのための非常に良い候補になると思います。黒い線画がある場合、エッジ検出を行う必要はないと思います。ピクセルがヒットするまでラスタースキャンを開始し、次の操作を行います。

部屋の周囲を1D信号であるかのように扱ってください。信号の振幅は、一定の速度でサンプリングされたオブジェクトの重心からの通常の距離です。そのため、ドアの単純なFDモデルを作成します。次に、各部屋のパラメーターを、立ち上がりエッジ、ピーク、および下降を探す一種の凸フィルターでスキャンし、キャプチャする「信号」の開始/停止ウィンドウを設定します。キャプチャされた「信号」に対してFFTまたは同様のFDアルゴを実行し、FDテンプレートと比較します。たぶん、テンプレート比較ステップは、一致をトリガーするためのしきい値との単純な相関関係になる可能性があります。あなたのドアだけが丸い縁を持っているので、それはかなり簡単なFDマッチング問題であるはずです。

データベースから画像や音楽を取得するFDを使用するようなものだと考えてください。それに関する多くのホワイトペーパー。

これは、おおよその形状にのFDを使用しての良いチュートリアルです: 私はあなたがそれをする必要があります疑うが、あなたはまた、最初に本論文で提案したように、回転に対処するためのフレームワークを極座標にあなたのイメージを変換することができます 形状ベースの画像検索使用します汎用フーリエ記述子

彼らがどのようにリンゴの境界検出をFDパラメータ化するか見てください?あなたのドアのような同じ考え。

ところで、極座標に回路図全体をマッピングしても回転不変は助けにならないでしょう。各ドアの重心についてそれを行う必要があります。これがまさにあなたの問題です。上記のリンクされた論文のように、ドア候補をキャプチャし、それらを極座標にマッピングしてFDドアテンプレートに一致させたいと思うのはそのためです。

このアプローチを試してみたらどうなるか教えてください。


0

おそらく、私が書いたこのMatlabコードが便利だと思うでしょう: Fractal Mosaics

私が見つけた従来の方法よりも堅牢性を必要とする芸術的なアプリケーションで、論文「対数極座標変換を使用した堅牢な画像登録」(pdf)を実装しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.