Utilizzo di IOS Accelerate Framework per l'elaborazione del segnale 2D su immagini non potenziali-due?

StackOverflow https://stackoverflow.com//questions/10708667

Domanda

// Modifica ...

Sto modificando leggermente la mia domanda per affrontare il problema di lavorare specificamente con immagini non potenziali. Ho una struttura di base che funziona con immagini di scala di grigi quadrate con dimensioni come 256x256 o 1024x1024, ma non riescono a vedere come generalizzare le immagini arbitrariamente di dimensioni. Le funzioni FFT sembrano voler includere il log2 della larghezza e dell'altezza, ma quindi non è chiaro come disimballare i dati risultanti, o se i dati non si stanno solo facendo arrabbiare. Suppongo che la cosa ovvia da fare sarebbe quella di centrare l'immagine NPOT all'interno di un'immagine più grande, tutta nera e quindi ignorare qualsiasi valori in tali posizioni quando guardi i dati. Ma chiedendo se c'è un modo meno imbarazzante per lavorare con i dati NPOT.

// ... END EDIT

Sto avendo un po 'di problemi con la documentazione di acceliera quadro. Normalmente userei FFTW3, ma sto avendo problemi a ottenerlo a compilare su un vero dispositivo iOS (vedi questo Domanda ). Qualcuno può indirizzarmi a un'implementazione super semplice usando l'accelerazione che fa qualcosa come il seguente:

1) Spegne i dati dell'immagine in una struttura dati appropriata che può essere passata per accelerare i metodi FFT accelerati.
In FFTW3, al suo più semplice, utilizzando un'immagine in scala di grigi, ciò comporta il posizionamento dei byte non firmati in un array "fftw_complex", che è semplicemente una struttura di due galleggianti, uno che tiene il valore reale e l'altro l'immaginario (e dove l'immaginario è Inizializzato a zero per ogni pixel).

2) Accetta questa struttura dati ed esegue un FFT su di esso.

3) Stampa la grandezza e la fase.

4) Esegue un IFFT su di esso.

5) Ricrea l'immagine originale dai dati derivanti dall'iscerto.

Sebbene questo sia un esempio molto semplice, sto avendo problemi a utilizzare la documentazione dal sito di Apple. Il Risposta di PI Qui è molto utile, ma sono ancora Un po 'confuso su come usare accelerare per eseguire questa funzionalità di base utilizzando un'immagine 2D in scala di grigi (o colore).

Comunque, qualsiasi suggerimento o in particolare alcuni semplici codice di lavoro che elabora un'immagine 2D sarebbe estremamente utile!

\\\ Modifica \\\\

Okay, dopo aver preso del tempo per immergersi nella documentazione e un codice molto utile su come su Pkmital's GitHub Repo , ho un codice di lavoro che pensavo che avrei pubblicato da 1) mi ci è voluto un po 'per capirlo e 2) da quando ho un paio di Domande rimanenti ...

Inizializza FFT "Plan". Supponendo una potenza quadrata di due immagini:

#include <Accelerate/Accelerate.h>
...
UInt32 N = log2(length*length);
UInt32 log2nr = N / 2; 
UInt32 log2nc = N / 2;
UInt32 numElements = 1 << ( log2nr + log2nc );
float SCALE = 1.0/numElements;
SInt32 rowStride = 1; 
SInt32 columnStride = 0;
FFTSetup setup = create_fftsetup(MAX(log2nr, log2nc), FFT_RADIX2);
.

Passa in un array di byte per un'immagine di gradazione di potenza quadrata e trasformarlo in un complesso_split:

COMPLEX_SPLIT in_fft;
in_fft.realp = ( float* ) malloc ( numElements * sizeof ( float ) );
in_fft.imagp = ( float* ) malloc ( numElements * sizeof ( float ) );

for ( UInt32 i = 0; i < numElements; i++ ) {
    if (i < t->width * t->height) {
      in_fft.realp[i] = t->data[i] / 255.0;
      in_fft.imagp[i] = 0.0;
    }
}
.

Eseguire il FFT sui dati immagine trasformati, quindi prendi la magnitudine e la fase:

COMPLEX_SPLIT out_fft;
out_fft.realp = ( float* ) malloc ( numElements * sizeof ( float ) );
out_fft.imagp = ( float* ) malloc ( numElements * sizeof ( float ) );

fft2d_zop ( setup, &in_fft, rowStride, columnStride, &out_fft, rowStride, columnStride, log2nc, log2nr, FFT_FORWARD );

magnitude = (float *) malloc(numElements * sizeof(float));
phase = (float *) malloc(numElements * sizeof(float));

for (int i = 0; i < numElements; i++) {
   magnitude[i] = sqrt(out_fft.realp[i] * out_fft.realp[i] + out_fft.imagp[i] * out_fft.imagp[i]) ;
   phase[i] = atan2(out_fft.imagp[i],out_fft.realp[i]);
}
.

Ora è possibile eseguire un IFFT sui dati OUT_FFT per ottenere l'immagine originale ...

COMPLEX_SPLIT out_ifft;
out_ifft.realp = ( float* ) malloc ( numElements * sizeof ( float ) );
out_ifft.imagp = ( float* ) malloc ( numElements * sizeof ( float ) );
fft2d_zop (setup, &out_fft, rowStride, columnStride, &out_ifft, rowStride, columnStride, log2nc, log2nr, FFT_INVERSE);   

vsmul( out_ifft.realp, 1, SCALE, out_ifft.realp, 1, numElements );
vsmul( out_ifft.imagp, 1, SCALE, out_ifft.imagp, 1, numElements );
.

O puoi eseguire un IFFT sulla grandezza per ottenere un'autocorrelazione ...

COMPLEX_SPLIT in_ifft;
in_ifft.realp = ( float* ) malloc ( numElements * sizeof ( float ) );
in_ifft.imagp = ( float* ) malloc ( numElements * sizeof ( float ) );
for (int i = 0; i < numElements; i++) {
  in_ifft.realp[i] = (magnitude[i]);
  in_ifft.imagp[i] = 0.0;
}

fft2d_zop ( setup, &in_fft, rowStride, columnStride, &out_ifft, rowStride, columnStride, log2nc, log2nr, FFT_INVERSE );      

vsmul( out_ifft.realp, 1, SCALE, out_ifft.realp, 1, numElements );
vsmul( out_ifft.imagp, 1, SCALE, out_ifft.imagp, 1, numElements );
.

Infine, è possibile inserire i risultati IFFT in un array di immagini:

for ( UInt32 i = 0; i < numElements; i++ ) {
  t->data[i] = (int) (out_ifft.realp[i] * 255.0);
}     
.

Non ho capito come utilizzare il quadro accelerato per gestire immagini non potenziali. Se allocco abbastanza memoria nel setup, allora posso fare un FFT, seguito da un IFFT per ottenere la mia immagine originale. Ma se cerca di fare un'autocorrelazione (con la grandezza del FFT), la mia immagine ottiene risultati netti. Non sono sicuro del modo migliore per rimuovere l'immagine in modo appropriato, quindi spero che qualcuno abbia un'idea di come farlo. (O condividere una versione funzionante del metodo VDSP_CONV!)

È stato utile?

Soluzione

Direi che per eseguire il lavoro su dimensioni dell'immagine arbitrarie, tutto ciò che devi fare è la dimensione del tuo valore di ingresso in modo appropriato alla potenza successiva di 2.

La parte difficile è dove mettere i tuoi dati dell'immagine originale e cosa riempire. Quello che stai davvero cercando di fare all'immagine o alla miniera dei dati dall'immagine è cruciale.

Nel PDF collegato sotto, prestare particolare attenzione al paragrafo appena sopra i 12.4.2 http://www.mathcs.org/java/programs/fft /FFTINFO/C12-4.pdf

Mentre i precedenti parla della manipolazione lungo 2 assi, potremmo eseguire potenzialmente un'idea simile prima della seconda dimensione e seguendo la seconda dimensione. Se sono corretto, questo esempio potrebbe applicarsi (e questo non è affatto un algoritmo esatto ancora):

Dì che abbiamo un'immagine che è 900 entro il 900: Per prima cosa potremmo dividere l'immagine in strisce verticali di 512, 256, 128 e 4. Procederemmo quindi 4 FFT 1D per ogni riga, uno per i primi 512 pixel, il prossimo per i seguenti 256 pixel, il successivo per il seguente 128, quindi l'ultimo per il restante 4. Poiché l'uscita del FFT è essenzialmente popolarità di frequenza, allora questi potrebbero essere semplicemente aggiunti (dalla frequenza solo prospettiva, non l'offset angolare). Potremmo quindi spingere questa stessa tecnica verso la 2a dimensione. A questo punto avremmo preso in considerazione ogni pixel di input senza effettivamente dover tagliare.

Questo è davvero solo il cibo per il pensiero, non ne ho provato io stesso, e in effetti dovrebbe ricercare questo stesso. Se stai veramente facendo questo tipo di lavoro in questo momento, potresti avere più tempo di me a questo punto però.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top