2012-03-22 11 views
5

Ho una nuvola di punti 3D con milioni di punti. Voglio memorizzare questi punti nello spazio voxel 3D. Il numero di voxle lungo l'asse delle coordinate è superiore a 3000 (x), 4000 (y), 1500 (z), per un totale di 3000 * 4000 * 1500 voxel. Ho bisogno di conservare in un voxel; numero massimo di punti, altezza minima, altezza massima e centorid. Tuttavia, il 90% dei voxel è vuoto. Quindi ci vuole molta memoria per memorizzare questo. In realtà, voglio cercare 26 voxel vicini di ciascun voxel in seguito. Quindi qual è il modo migliore per archiviare questi dati nello spazio voxel e ottenere l'accesso a questo in modo efficiente?Come gestire i voxel 3D in modo efficiente?

Creare un array multidimensionale, non è la soluzione migliore, in termini di prestazioni ... per favore qualche suggerimento?

+4

Al 90% di spazio vuoto, hai ancora 1.800.000.000 voxel. In ogni caso, non volerà. È possibile memorizzare esecuzioni di voxel lungo una dimensione, ma la ricerca sarà costosa. – Anteru

+1

Il "voxel 3D" non è un pleonasma? – leftaroundabout

+1

@leftaroundabout, potrebbe essere un voxel 4D o no? – usr

risposta

1

Un approccio potrebbe essere il backup dei dati effettivi con i dati di una raccolta.

Facciamo un esempio:

struct t_voxel { 
    size_t nPoints, minHeight, maxHeight, centorid; 
}; 

struct t_voxel_id { 
    uint16_t index; 
}; 

// one dimension 
class t_voxel_collection { 
    // the actual voxel data needed for the indices represented by the collection of voxelId 
    std::vector<t_voxel> d_voxel; 
    // here, empty voxel is designated by t_voxel.index = 0 
    // this collection is your primary array representation 
    // these elements just refer to a unique or shared index in this->d_voxel 
    std::vector<t_voxel_id> d_voxelId; 
public: 
    // >> the interface to access and set, which abstracts the backing collection. 
    // and prohibits the client from accessing the actual data. 

    t_voxel get(const size_t& idx) const { 
    return this->d_voxel[this->d_voxelId[idx].index]; 
    } 
    // ... 
}; 

è possibile ottenere un forte calo nel consumo di memoria in questo modo (supponendo che si vede il senso questo sta andando).

Questa non è una risposta completa, ma potrebbe aiutare in questo scenario.

Esistono diversi modi per ottimizzare ulteriormente e condividere i dati voxel in questa raccolta, a seconda dell'utilizzo.

+0

Grazie per la tua idea. spero che il modo in cui hai spiegato possa essere d'aiuto per risparmiare problemi di allocazione della memoria.Mi piacerebbe conoscere il modo efficace per ottenere i voxel del proprio vicinato in 3D con i voxel 26 !!! qualsiasi idea per questo ..... – user1286780

+0

@ user1286780 usando questo approccio, 't_voxel_collection' rappresenta una dimensione. l'approccio semplice per introdurre le dimensioni è usare un contenitore, ad es. 'std :: vector >'. simile all'implementazione di 't_voxel_collection', ci possono essere modi più ottimali per rappresentare una dimensione delle collezioni, a seconda di come si desidera bilanciare memoria, CPU e così via. altri hanno menzionato alternative che consumano meno memoria della mia (anche se la mia risparmierà molto nello scenario), ma la ricerca è molto veloce usando il mio approccio - con un set di dati così grande, l'equilibrio è importante. – justin

+0

Grazie justin. Mi piacerebbe anche avere un'idea della ricerca nel seguente caso. – user1286780

2

Se sono davvero "solo" milioni di punti, molto più del 90% dei voxel si svuoterà. Proverei un multimap hash (std::unordered_multimap in C++ 11) dalle coordinate voxel ai punti. Questo ti dà la ricerca O (1), come un array. Tuttavia, presenta un sovraccarico, ma è probabilmente il miglior compromesso.

L'unica cosa di cui hai bisogno per questo funzionamento è un confronto di uguaglianza nella classe voxel e una specializzazione del modello std::hash<voxel>. Non otterrai il "numero massimo di punti" implementato in alcun modo automatico, ma è davvero utile?

+0

La ricerca dei vicini sarà comunque costosa. – usr

+0

@usr: non proprio. Come ho detto, la ricerca è _O_ (1), per ogni punto. I vicini non sono più veloci di altri punti. – leftaroundabout

+0

Ci sono 26 di questi che rendono un costoso O (1). – usr

3

Strutture dati classiche per questo tipo di dati sono kd-Trees e octrees..

Inoltre, si consiglia di dare un'occhiata alle strutture di dati spatial searching and sorting implementate in CGAL.

+0

Qual è la migliore struttura dati per questo, kd tree o octree? Possiamo usare la struttura dei dati voxels con l'octree o .... mi spiace non ho una chiara idea di queste strutture di dati. – user1286780

+1

@ user1286780 nella tua domanda originale hai solo chiesto informazioni sulle strutture dei dati voxel, quindi non sto mettendo questa come una risposta separata. Ma il tuo commento a questa risposta ha suggerito che sei aperto ad altre strutture di dati. Dal momento che dici di voler guardare ai vicini, potresti dare un'occhiata al nostro documento del 2012 "Confronto tra strategie di ricerca del vicino più vicino e implementazioni per una registrazione efficiente delle forme" in Journal of Software Engineering for Robotics (JOSER), https://robotik.informatik.uni-wuerzburg.de/telematics/download/joser2012.pdf – josch

1

Stai per sbloccarti qualunque cosa tu faccia, anche se trovi un layout di memoria perfetto per la tua griglia sparsa - è ancora troppa memoria richiesta. Il vero problema è riuscire a memorizzarlo in modo efficiente su disco e memorizzare in modo intelligente le regioni di interesse.

Per fortuna Field3D è stato sviluppato proprio per questo.

Problemi correlati