2011-02-05 11 views
6

Sto usando python per lavorare con matrici di grandi dimensioni (circa 2000 x 2000), dove ogni punto I, J nella matrice rappresenta un singolo pixel.Python - rappresentazione efficiente di pixel e valori associati

Le matrici stesse sono sparse (ovvero una parte sostanziale di esse avrà valori zero), ma quando vengono aggiornate tendono ad essere operazioni di incremento, a un numero elevato di pixel adiacenti in un "blocco" rettangolare, piuttosto che pixel casuali qua e là (una proprietà non mi utilizzano attualmente a mio vantaggio ..). paura un po 'nuova alla matrice l'aritmetica, ma ho guardato in un certo numero di possibili soluzioni, tra le varie versioni di scipy matrici sparse. Finora coordinate (COO) matrici sembrano essere le più promettenti. Così, per esempio dove voglio incrementare forma un blocco, avrei dovuto fare qualcosa sulla falsariga di:

>>> from scipy import sparse 
>>> from numpy import array 
>>> I = array([0,0,0,0]) 
>>> J = array([0,1,2,3]) 
>>> V = array([1,1,1,1]) 
>>> incr_matrix = sparse.coo_matrix((V,(I,J)),shape=(100,100)) 
>>> main_matrix += incr_matrix #where main_matrix was previously defined 

in futuro, mi piacerebbe avere una rappresentazione valore di pixel più ricco di anycase (tuple per rappresentare RGB, ecc), qualcosa che NumPy serie doesnt sostegno fuori dalla scatola (o forse ho bisogno di usare this).

definitiva avrò un certo numero di queste matrici che avrei bisogno di fare semplici arithmitic, e avrei bisogno il codice per essere il più efficiente possibile - e distribuibili, quindi avrei bisogno di essere in grado perseverare e scambiare questi oggetti in una rappresentazione minuscola senza sanzioni sostanziali. Mi chiedo se questo è il modo giusto per andare, o dovrei cercare rotolare le mie strutture utilizzando dicts ecc?

+0

Dubito che si possa produrre qualcosa di meglio delle capacità scipy e numpy. Ma non sono abbastanza abile in loro per essere più affermativo. A proposito, non mi piace usare la parola "vettore". Da un lato, non esiste una struttura dati integrata denominata 'vector' in Python. D'altra parte, è improbabile che una tabella bidimensionale venga chiamata "vettore" in senso matematico. Quindi, la tua entità non è né un oggetto Python chiamato 'vector', né una struttura matematica chiamata 'vector' – eyquem

+0

che è vera - dovrebbe effettivamente dire matrix invece di vector (?) :) – malangi

+6

2000x2000 non è molto grande. Non è necessario utilizzare array sparsi. Si dovrebbe ottenere prestazioni molto migliori semplicemente usando i normali array numpy. Inoltre, numpy _very_ much supporta "qualcosa come" i vettori RGB "per ogni pixel ... È solo un array 2000x2000x3! Funziona bene, ed è veramente efficiente! –

risposta

4

La regola generale è, ottenere il codice di lavoro prima, quindi ottimizzare, se necessario ...

In questo caso, utilizzare un normale allineamento NumPy 2000x2000, o 2000x2000x3 per RGB. Questo sarà molto più facile e veloce da utilizzare, è solo un piccolo requisito di memoria e ha molti altri vantaggi, ad esempio, è possibile utilizzare gli strumenti di elaborazione delle immagini standard, ecc.

Quindi, se necessario, "per persistere e scambiare questi oggetti ", puoi semplicemente comprimerli usando gzip, pytables, jpeg o altro, ma non è necessario limitare i requisiti di archiviazione basati sulla manipolazione dei dati.

In questo modo si ottiene sia l'elaborazione più veloce e migliore compressione.

+0

Il codice funziona effettivamente con un array standard, ma il 2000 x 2000 è oltre 140 MB (~ 40 KB in formato zip) e questo è molto più grande per l'uso efficiente per me, motivo per cui sono stato a cercare le matrici sparse. – malangi

+0

Quali sono gli elementi nella matrice 2000x2000? Per me, una matrice 2000x2000 di uint8 è 4MB. (Per essere chiari, forse hai bisogno di una matrice sparsa, ma, in generale, alcune domande su SO mancano di un dettaglio, e alcune hanno bisogno di affrontare il problema in modo diverso, quindi è sufficiente risolvere questo problema. certo che sta succedendo qui, ma qualcosa sembra non adattarsi.) – tom10

+0

sto usando float64s - ma penso che dato questo thread molto utile, sembra che usare matrici sparse non sia probabilmente il modo giusto per andare a tutti. Grazie! – malangi

0

Si potrebbe prendere in considerazione esaminando un quadtree come un'implementazione. La struttura quadtree è piuttosto efficiente nella memorizzazione di dati sparsi e ha il vantaggio aggiunto che se si lavora con strutture composte da molti blocchi di dati simili, la rappresentazione può essere molto compatta. Non sono sicuro se ciò sarà particolarmente applicabile a quello che stai facendo, dal momento che non so cosa intendi con "lavorare in blocchi", ma è certamente da verificare come implementazione alternativa di una matrice sparsa.

2

Direi, sì, questa è la strada da percorrere. Sicuramente sopra la costruzione di qualcosa fuori dai dizionari! Quando si costruisce un "vettore", array, quindi utilizzare una matrice strutturata, cioè definire il proprio DTYPE:

rgbtype = [('r','uint8'),('g','uint8'),('b','uint8')] 

quando incrementare i vostri blocchi, sarà simile a questa:

main_matrix['r'][blk_slice] += incr_matrix['r'] 
main_matrix['g'][blk_slice] += incr_matrix['g'] 
main_matrix['b'][blk_slice] += incr_matrix['b'] 

Aggiornamento:

Sembra che non sia possibile eseguire operazioni matrice con una matrice coo, esistono semplicemente come un modo conveniente per popolare una matrice sparsa. Devi convertirli in un altro (sparse) tipo di matrice prima di fare gli aggiornamenti. documentation

+0

O semplicemente usa un array mxnx3. Soprattutto per i dati di immagine, una matrice 'mxnx numbands' è un modo migliore per gestire le cose rispetto a una matrice strutturata in quanto consente di separare le bande più facilmente (' x [..., 1] 'invece di' x ['r'] .reshape (m, n) '). Non c'è certamente niente di sbagliato nell'usare un array strutturato, ma personalmente trovo i semplici array 3D una corrispondenza migliore per i dati di immagine. Ad ogni modo, +1 da me. –

+0

Non sono sicuro se/come farlo con una matrice sparsa. – Paul

+0

Scusa, ho dimenticato che stavamo parlando di matrici sparse quando ho fatto il commento ... Le matrici sparse sono intrinsecamente 2D, quindi non puoi. Gli array sparsi strutturati sono sicuramente la strada da percorrere in questo caso. Continuo a sostenere che sarebbe meglio evitare l'uso di una matrice sparsa se ha intenzione di incrementare diversi blocchi di esso, ma questa è una domanda completamente diversa ... –

Problemi correlati