Schnellster Algorithmus für die Distanztransformation


21

Ich suche nach dem schnellsten verfügbaren Algorithmus für die Distanztransformation.

Nach dieser Website http://homepages.inf.ed.ac.uk/rbf/HIPR2/distance.htm beschreibt es:

Die Distanztransformation kann mit cleveren Algorithmen in nur zwei Durchgängen wesentlich effizienter berechnet werden (z. B. Rosenfeld und Pfaltz 1968).

Ich suchte herum und fand: "Rosenfeld, A und Pfaltz, J L. 1968. Distanzfunktionen auf digitalen Bildern. Mustererkennung, 1, 33-61."

Aber ich glaube, wir sollten einen besseren und schnelleren Algorithmus haben als den von 1968? Tatsächlich konnte ich die Quelle von 1968 nicht finden, so dass jede Hilfe sehr geschätzt wird.


Es tut mir leid, dass ich diesen Thread wieder eingerichtet habe, aber ich versuche, das GDT auch zu implementieren, aber ich verwende Python. def of_column (dataInput): Ausgabe = Nullen (dataInput.shape) n = len (dataInput) k = 0 v = Nullen ((n,)) z = Nullen ((n + 1,)) v [0] = 0 z [0] = -inf z [1] = + inf s = 0 für q im Bereich (1, n): während True: s = (((Dateneingang [q] + q * q) - (Dateneingang [v [k ]] + v [k] * v [k]) / (2,0 * q - 2,0 * v [k])) wenn s <= z [k]: k - = 1 sonst: break k + = 1 v [ k] = qz [k] = sz [k + 1] = + inf k = 0 für q im Bereich (n): während z [k + 1] <q: k + = 1 Ausgang [q] = ((q - v [k]) * (q - v [k]) + dataInput [v [k]]) Ausgabe jedoch zurückgeben, wenn offeri
mkli90

Bitte stellen Sie eine neue Frage. Stellen Sie keine Fragen als Antworten.
MBaz

Willkommen bei der Signal Processing SE. Sie können eine Frage stellen, indem Sie oben rechts auf "Frage stellen" klicken.
Jojek

Antworten:


14

Pedro F. Felzenszwalb und Daniel P. Huttenlocher haben ihre Implementierung für die Ferntransformation veröffentlicht . Sie können es nicht für volumetrische Bilder verwenden, aber möglicherweise können Sie es erweitern, um 3D-Daten zu unterstützen. Ich habe es nur als Blackbox benutzt.


Wissen Sie zufällig, ob dies in OpenCV implementiert ist?
Matt M.

Ja, für bestimmte Werte von maskSizeund distanceType. Siehe: opencv.willowgarage.com/documentation/cpp/…
bjoernz

Gibt es bisher Implementierungen für volumetrische Bilder (z. B. Kinect Depth Image)?
Zhangxaochen

9

In diesem Artikel werden alle modernen exakten Distanztransformationen beschrieben:

"2D Euclidean distance transforms: eine vergleichende Umfrage", ACM Computing Surveys, Band 40, Ausgabe 1, Februar 2008 http://www.lems.brown.edu/~rfabbri/stuff/fabbri-EDT-survey-ACMCSurvFeb2008.pdf

Der Aufsatz zitiert die Technik von Meijster et al. al. als schnellster allgemeiner Zweck genaue Transformation. Diese Technik wird hier detailliert beschrieben:

"Ein allgemeiner Algorithmus zur Berechnung von Abstandstransformationen in linearer Zeit", A. Meijster, JBTM Roerdink und WH Hesselink. http://fab.cba.mit.edu/classes/S62.12/docs/Meijster_distance.pdf

Der Meijster-Algorithmus wird in meiner Open Source-Effektbibliothek verwendet: https://github.com/vinniefalco/LayerEffects

Ich hoffe das hilft jemandem.


Es wäre nützlich zu wissen, wo in Ihrer Bibliothek sich der jeweilige Code befindet.
Altar

6

Hier ist ein C # -Code für eine euklidische Distanztransformation im 1D-Quadrat nach der Arbeit von Felzenszwald & Huttenlocher :

private static void DistanceTransform(double[] dataInput, ref double[] dataOutput)
{
    int n = dataInput.Length;

    int k = 0;
    int[] v = new int[n];
    double[] z = new double[n + 1];

    v[0] = 0;
    z[0] = Double.NegativeInfinity;
    z[1] = Double.PositiveInfinity;

    double s;

    for (int q = 1; q < n; q++)
    {
        while (true)
        {
            s = (((dataInput[q] + q * q) - (dataInput[v[k]] + v[k] * v[k])) / (2.0 * q - 2.0 * v[k]));

            if (s <= z[k])
            {
                k--;
            }
            else
            {
                break;
            }
        }

        k++;

        v[k] = q;
        z[k] = s;
        z[k + 1] = Double.PositiveInfinity;
    }

    k = 0;

    for (int q = 0; q < n; q++)
    {
        while (z[k + 1] < q)
        {
            k++;
        }

        dataOutput[q] = ((q - v[k]) * (q - v[k]) + dataInput[v[k]]);
    }
}

Dies kann leicht für Binär- und Graustufenbilder verwendet werden, indem es zuerst auf Bildspalten und dann auf Zeilen angewendet wird (oder natürlich umgekehrt).

Die Transformation ist in der Tat sehr schnell.

Hier sind die Quell- und Ausgabebilder:

Bildbeschreibung hier eingeben

Bildbeschreibung hier eingeben

Die schwarzen Pixel haben den Wert 0, und die weißen Pixel haben einen großen Wert (müssen größer sein als der größtmögliche quadratische Abstand in den Bildern, aber nicht unendlich), damit die Transformation den Abstand von den schwarzen Pixeln zurückgibt und die weißen Pixel weggelassen werden.

Um eine echte euklidische Distanztransformation zu erhalten, ziehen Sie einfach eine Quadratwurzel jedes Pixels aus dem Ausgabebild.


Interessant. Was ist eine übliche Verwendung der Distanztransformation, Libor?
Spacey

1
Ich denke, die häufigsten Anwendungen sind das Finden von Pfaden, die Segmentierung, geometrische Messungen (Schwerpunkt) und Effekte (Abschrägungseffekt). Für das Zusammenfügen von Panoramabildern benötigte ich eine Abstandstransformation - um eine geometrisch optimale Mischmaske zu finden. Dies umfasste die Laufdistanztransformation für jedes Bild und die Berechnung der Mischmaske aus den Gewichten.
Libor

1
Die Abstandstransformation kann zum Abgleichen von [Kanten] Bildern verwendet werden, wobei eine Technik das " Fasenabgleichen " ist ( umiacs.umd.edu/~mingyliu/papers/liu_cvpr2010.pdf ). Das DT kann auch verwendet werden, um die Mittelachse (das Skelett) zu finden und andere Aufgaben auszuführen, wie z. B. den erwähnten Libor.
Rethunk
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.