Ich suche nach einer Methode zur Skalierung und Rotation invarianten Template-Matching. Ich habe bereits einige ausprobiert, aber sie haben für meine Beispiele nicht so gut funktioniert oder dauernd ausgeführt. Die Erkennung von SIFT- und SURF-Features ist vollständig fehlgeschlagen. Ich habe auch versucht, eine Log-Polar-Template-Matching-Funktion zu implementieren, bin aber nie fertig geworden (wusste nicht genau, wie).
In diesen Artikeln
http://cvpr.uni-muenster.de/teaching/ss08/seminarSS08/downloads/Wentker-Vortrag.pdf
http://www.jprr.org/index.php/jprr/article/viewFile/355/148
Ich habe über diese Methode gelesen. Das Kartieren der Polarkoordinaten hat funktioniert, aber ich weiß nicht, ob es richtig ist. Die Bilder sehen so aus.
Und nachdem ich diese 2 Bilder mit OpenCVs Template Matching-Funktion abgeglichen habe, habe ich dieses Ergebnis erhalten
Jetzt weiß ich nicht, wie ich weitermachen soll.
Meine Vorlagen sind immer einfache Symbole beim Erstellen von Blaupausen und der Blaupausen selbst. Die Symbole können sich in Größe und Ausrichtung unterscheiden.
Zum Beispiel meine einfache Blaupause:
Und meine Vorlage
In diesem Beispiel gibt es nur eine Vorlage, aber in den Blaupausen sollten alle Vorkommen gefunden werden, auch diejenigen mit Größen und / oder Ausrichtungen.
Hat jemand einen Ansatz, wie ich das lösen könnte?
Bearbeiten:
Eine Ergänzung zu Andrey Ansatz. Der Entfernungserfassungsalgorithmus für ein radiales Profil. (Mit 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;
}