Correspondance de modèle invariant d'échelle et de rotation

12

Je recherche une méthode de mise en correspondance de modèles invariants à l'échelle et à la rotation. J'en ai déjà essayé, mais ils n'ont pas fonctionné si bien pour mes exemples ou ont pris pour toujours à exécuter. La détection des fonctionnalités SIFT et SURF a totalement échoué. J'ai aussi essayé d'implémenter une fonction Log-Polar Template Matching, mais je n'ai jamais terminé (je ne savais pas exactement comment).

Dans ces articles (le premier est en allemand)

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

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

J'ai lu sur cette méthode. La cartographie des coordonnées polaires a fonctionné, mais je ne sais pas si c'est vrai. Les images ressemblent à ceci.

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

template_log_polar.png

Et après avoir fait correspondre ces 2 images avec la fonction de correspondance de modèles d'OpenCV, j'ai obtenu ce résultat

match_log_polar.png

Maintenant, je ne sais plus comment continuer.

Mes modèles sont toujours de simples symboles dans la création de plans et les plans eux-mêmes. Les symboles peuvent différer en taille et en orientation.

Par exemple, mon plan simple:

entrez la description de l'image ici

Et mon modèle

entrez la description de l'image ici

Dans cet exemple, il n'y a qu'un seul modèle, mais dans les plans, il devrait trouver toutes les occurrences, même celles avec des tailles et / ou des orientations.

Quelqu'un at-il une approche pour résoudre ce problème?

Éditer:

Un ajout à l'approche d'Andrey. L'algorithme de capture de distance pour un profil radial. (Utilisation d'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;
}
Arndt Bieberstein
la source
bienvenue sur dsp.SE. Nous essaierons de vous aider, mais fournir des informations plus précises serait bien. Que voulez-vous dire par SIFT et SURF "totalement échoué"? Qu'ont-ils détecté / assorti? De plus, personnellement, je ne connais pas la correspondance de modèles Log-Polar, mais, si vous avez essayé, où était exactement le problème?
penelope
Les détections des fonctionnalités SIFT et SURF n'ont trouvé aucune fonctionnalité dans l'image du modèle. Il semble que le modèle contient trop moins d'informations (juste ce petit arc et une ligne). Pour la correspondance Log-Polar, j'ai trouvé un article où il est décrit, mais pas les mathématiques exactes derrière. Je vais le rechercher et l'ajouter.
Arndt Bieberstein
Hé, pas beaucoup de gens ici peuvent comprendre l'allemand, je pense: D Mais, pour tout le reste: vous pouvez éditer votre propre message pour ajouter de nouvelles informations au bon endroit, plutôt que dans les commentaires. Et, aussi, vous n'avez toujours pas dit avec quoi exactement vous aviez des problèmes.
penelope
3
L'auteur de "l'article allemand" a un article en anglais - www-cs.engr.ccny.cuny.edu/~wolberg/pub/icip00.pdf (merci à google)
SergV

Réponses:

6

Je pense que vous pouvez résoudre votre problème d'une manière beaucoup plus facile. Étant donné que vous avez affaire à des plans, vous ne devez pas vous soucier de la connectivité des bords, du bruit et de bien d'autres choses pour lesquelles SIFT et SURF ont été conçues. Votre modèle est une forme creuse avec des formes de bord spécifiques.

Ainsi, ma recommandation est:

  • Parcourez le périmètre et trouvez un profil des distances des bords autour du centre du gabarit. Il s'agit du profil radial du gabarit. Divisez par la plus grande distance, pour être invariant à l'échelle. Faites pivoter le vecteur de sorte que la plus petite distance soit la première, pour être invariante en rotation. (Si votre modèle n'a pas de distance dominante, vous pouvez modifier l'étape 2 plus tard)

entrez la description de l'image ici

  • Trouvez des taches dans l'image. Calculez le profil radial décrit à la partie (1) et comparez les deux vecteurs par corrélation normalisée. Si votre modèle n'a pas de distance dominante, la corrélation devient une corrélation croisée normalisée et la sélection du maximum). Ceux qui dépassent un certain seuil sont considérés comme des matchs.

Voici un code Matlab pour commencer - j'ai écrit la partie qui trouve le profil de distance pour un blob spécifique et l'ai calculé pour le modèle:

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
Andrey Rubshtein
la source
Je suppose que cela ne fonctionne pas avec des formes non fermées? Ou dois-je simplement sauter ces "trous" dans la forme.
Arndt Bieberstein
@ArndtBieberstein, Yep cela ne fonctionne que pour les formes fermées. Je suppose qu'il devrait y avoir une méthode pour l'étendre.
Andrey Rubshtein
Comme OpenCV ne contient pas la fonction bwtraceboundary, j'ai écrit la mienne et j'ai juste "sauté" les trous et rempli de zéros. Voici un petit exemple à quoi ressemblent maintenant les résultats. 5 tracés pour chaque modèle. Les points rouges sont les points de départ. Sample Plot
Arndt Bieberstein
@ArndtBieberstein, très sympa! Vous pourriez peut-être partager les résultats avec nous une fois que vous aurez terminé.
Andrey Rubshtein
Bien sûr, le Code n'est pas si agréable ou performant, mais ça marche. Je vais le joindre sous ma question. C'est écrit en C # (j'utilise EmguCV)
Arndt Bieberstein
3

Voici l'idée de base de ce que je sais pouvoir faire, basée sur une conférence du professeur Anurag Mittal de l'IIT Madras.

L'idée est la détection d'objets basée sur la forme, mais peut évidemment être étendue ailleurs également.

  1. Calculez les bords à l'aide du détecteur de bord Berkeley.
  2. Reliez les bords obtenus. "Détection globale de frontière d'objet".
  3. Correspondance de forme en utilisant la distance de chanfrein ou la distance de Houstoff.

Son article sur le même sujet est disponible sur: Détection multi-étapes basée sur les contours d'objets déformables.

D'un autre côté, je pense que SIFT devrait fonctionner car les algorithmes de détection des coins fonctionneraient sur la fonctionnalité de modèle que vous avez là-bas.

Remarque: SIFT n'est pas complètement invariant par rotation. Il n'est pas en mesure de faire face à des rotations> 60 degrés environ. La formation de plusieurs modèles est donc une bonne idée.

Comme sur les transfroms de Fourier-Mellin à base log-polaire: ils provoquent une perte d'informations en raison de la façon dont l'échantillonnage a lieu pour les transformées.

Naresh
la source
Cette méthode semble vraiment prometteuse! Je ne peux pas ouvrir votre lien, mais j'ai googlé votre approche. Je ne savais pas que SIFT n'était pas complètement ivariant par rotation! Très bonne réponse! +1
Arndt Bieberstein
1
Je n'ai presque rien trouvé sur la distance de chanfrein et comment cela fonctionne, pour ceux qui le recherchent également, essayez ce lien.
Arndt Bieberstein
@Naresh SIFT n'est pas invariant en rotation pour les grandes rotations hors plan. Pas dans le même avion.
a-Jays
1

Je n'y ai pas beaucoup réfléchi, mais je suis sûr qu'une solution robuste peut être trouvée sans trop de difficulté en utilisant des descripteurs de Fourier (FD) classiques. Je pense que votre problème pourrait être un très bon candidat pour cela. Ne pensez pas que vous devez effectuer une détection de bord car vous avez des dessins au trait noir. Commencez simplement la numérisation raster jusqu'à ce que vous atteigniez un pixel, puis procédez comme suit:

Traitez simplement le périmètre de votre pièce comme s'il s'agissait d'un signal 1D, où l'amplitude du signal est la distance normale du centre de gravité de l'objet, échantillonnée à une certaine vitesse constante. Alors, faites un modèle FD simple pour la porte. Ensuite, scannez les paramètres de chaque pièce avec une sorte de filtre convexe à la recherche d'un front montant, d'un pic et d'une chute, qui définit une fenêtre de démarrage / arrêt de "signal" à capturer. Faites un algorithme FFT ou FD similaire sur ce "signal" capturé et comparez-le au modèle FD. Peut-être que l'étape de comparaison du modèle peut être une simple corrélation avec un seuil pour déclencher une correspondance. Étant donné que seules vos portes ont des bords arrondis, cela devrait être un problème d'appariement FD assez facile.

Pensez-y comme utiliser la récupération d'images ou de musique de FD à partir d'une base de données. Beaucoup de livres blancs à ce sujet.

Ceci est un bon tutoriel sur l'utilisation des FD pour approximer les formes: je doute que vous en ayez besoin, mais vous pouvez également d'abord transformer vos images en un cadre de coordonnées polaires pour gérer les rotations, comme proposé dans cet article: récupération d'images basée sur des formes à l'aide descripteur de Fourier générique

voir comment ils FD paramètrent la détection du périmètre de la pomme? Même idée que votre porte.

BTW, je suis presque sûr que cartographier l'ensemble du schéma en coordonnées polaires n'aidera pas l'invariance rotationnelle - vous devriez le faire pour le centroïde de chaque porte, ce qui est exactement le problème avec lequel commencer. C'est pourquoi je pense que vous voulez simplement capturer les candidats de porte, et peut-être les mapper aux coordonnées polaires pour les faire correspondre avec le modèle de porte FD, comme cela est fait dans cet article lié ci-dessus.

laissez-moi savoir comment ça se passe si vous essayez cette approche.

Ariel Bentolila
la source
0

Vous trouverez peut-être ce code Matlab que j'ai écrit utile: Fractal Mosaics

Il implémente le document "Enregistrement d'image robuste utilisant la transformation log-polaire" ( pdf ) dans une application artistique qui nécessitait plus de robustesse que les méthodes traditionnelles que j'ai trouvées.

user2348114
la source