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.
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
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:
Et mon modèle
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;
}