Algoritmo più veloce per la trasformazione a distanza


21

Sto cercando l'algoritmo più veloce disponibile per la trasformazione a distanza.

Secondo questo sito http://homepages.inf.ed.ac.uk/rbf/HIPR2/distance.htm , descrive:

La trasformazione della distanza può essere calcolata in modo molto più efficiente utilizzando algoritmi intelligenti in soli due passaggi (ad esempio Rosenfeld e Pfaltz 1968).

Cercando in giro, ho trovato: "Rosenfeld, A e Pfaltz, J L. 1968. Funzioni a distanza su immagini digitali. Pattern Recognition, 1, 33-61."

Ma credo che dovremmo avere un algoritmo migliore e più veloce di quello del 1968 già? In effetti, non sono riuscito a trovare la fonte dal 1968, quindi ogni aiuto è molto apprezzato.


Ci scusiamo per aver ripreso questo thread, ma sto anche cercando di implementare GDT, ma usando Python. def of_column (dataInput): output = zeri (dataInput.shape) n = len (dataInput) k = 0 v = zeri ((n,)) z = zeri ((n + 1,)) v [0] = 0 z [0] = -inf z [1] = + inf s = 0 per q nell'intervallo (1, n): mentre True: s = (((dataInput [q] + q * q) - (dataInput [v [k ]] + v [k] * v [k])) / (2.0 * q - 2.0 * v [k])) se s <= z [k]: k - = 1 altrimenti: interrompi k + = 1 v [ k] = qz [k] = sz [k + 1] = + inf k = 0 per q nell'intervallo (n): mentre z [k + 1] <q: k + = 1 output [q] = ((q - v [k]) * (q - v [k]) + dataInput [v [k]]) restituisce output Tuttavia quando offeri
mkli90

Per favore, fai una nuova domanda. Non pubblicare domande come risposte.
MBaz,

Benvenuti in Signal Processing SE. Puoi porre una domanda usando "Poni domanda" nell'angolo in alto a destra.
jojek

Risposte:


14

Pedro F. Felzenszwalb e Daniel P. Huttenlocher hanno pubblicato la loro implementazione per la trasformazione a distanza . Non puoi usarlo per immagini volumetriche, ma forse puoi estenderlo per supportare i dati 3d. L'ho usato solo come scatola nera.


Ti capita di sapere se questo è implementato in OpenCV?
Matt M.

Sì, per determinati valori di maskSizee distanceType. Vedi: opencv.willowgarage.com/documentation/cpp/…
bjoernz

ci sono implementazioni per immagini volumetriche (ad es. immagine di profondità Kinect) fino ad ora?
zhangxaochen,

9

Questo documento discute tutte le moderne trasformazioni esatte della distanza:

"Trasformazioni 2D della distanza euclidea: un'indagine comparativa", ACM Computing Surveys, Vol 40, Issue 1, Feb 2008 http://www.lems.brown.edu/~rfabbri/stuff/fabbri-EDT-survey-ACMCSurvFeb2008.pdf

L'articolo cita la tecnica di Meijster, et. al. come lo scopo generale più veloce, trasformazione esatta. Questa tecnica è dettagliata qui:

"Un algoritmo generale per il calcolo della distanza si trasforma in tempo lineare", A. Meijster, JBTM Roerdink e WH Hesselink. http://fab.cba.mit.edu/classes/S62.12/docs/Meijster_distance.pdf

L'algoritmo Meijster viene utilizzato nella mia libreria di effetti open source: https://github.com/vinniefalco/LayerEffects

Spero che questo aiuti qualcuno.


Sarebbe utile sapere dove possiamo trovare il codice particolare nella tua libreria.
Akaltar,

6

Ecco un codice C # per la trasformazione della distanza euclidea al quadrato 1D secondo il documento di 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]]);
    }
}

Questo può essere facilmente usato per le immagini binarie e in scala di grigi applicandolo prima sulle colonne delle immagini e poi sulle righe (o viceversa, ovviamente).

La trasformazione è davvero molto veloce.

Ecco le immagini di origine e di output:

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

I pixel neri hanno valore 0 e i bianchi hanno un valore maggiore (devono essere più grandi della distanza quadrata possibile più grande nelle immagini ma non l'infinito) in modo che la trasformazione ritorni distanza dai pixel neri e quelli bianchi siano ommigati.

Per ottenere una vera trasformazione della distanza euclidea, basta prendere una radice quadrata di ciascun pixel dall'immagine di output.


Interessante. Qual è un uso comune della trasformazione a distanza, Libor?
Spacey,

1
Penso che gli usi comuni siano nella ricerca di percorsi, segmentazione, misure geometriche (centro di massa) ed effetti (effetto smusso). Per trovare una maschera di miscelazione geometricamente ottimale, avevo bisogno di trasformare la distanza per cucire immagini panoramiche. Ciò ha comportato la trasformazione della distanza di corsa su ogni immagine e quindi il calcolo della maschera di fusione dai pesi.
Libor,

1
La trasformazione della distanza può essere utilizzata nell'abbinamento delle immagini [bordo], una tecnica è la "corrispondenza smusso" ( umiacs.umd.edu/~mingyliu/papers/liu_cvpr2010.pdf ). Il DT può anche essere usato per trovare l'asse mediale (scheletro) ed eseguire altri compiti come il Libor menzionato.
Rethunk,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.