2013-08-30 20 views
5

Questo programma utilizza socket per trasferire array di byte 2D altamente ridondanti (simili all'immagine). Mentre la velocità di trasferimento è relativamente alta (10 Mbps), anche gli array sono altamente ridondanti (ad esempio, ogni riga può contenere più valori conseguentemente simili). Ho provato zlib e lz4 ei risultati sono stati promettenti, tuttavia penso ancora a un metodo di compressione migliore e per favore ricorda che dovrebbe essere relativamente veloce come in lz4. Eventuali suggerimenti?quale algoritmo di compressione utilizzare per dati altamente ridondanti

+1

Hai taggato "compressione immagine". I dati che stai comprimendo sono un flusso di immagini? Se così fosse, ti suggerirei di utilizzare i codec Video/Immagine senza perdita di dati. – Aron

+0

I dati non sono immagini reali, tuttavia soddisfano tutti i requisiti per comportarsi come immagini e ho dato un'occhiata ai codec video senza perdita di dati, tuttavia i dati sono generati in tempo reale e i codec video tendono ad essere lenti in fase di compressione. – beebee

+0

Prova a dare [questo articolo] (https://www.usenix.org/legacy/event/fast11/tech/full_papers/Meyer.pdf) una lettura. – jxh

risposta

1

si potrebbe creare il proprio, se i dati in righe è simile è possibile creare una mappa delle risorse/index riducendo in tal modo sostanziale le dimensioni, qualcosa di simile

del file originale:
riga 1: 1212, 34, 45,1212,45,34,56,45,56
riga 2: 34,45,1212,78,54,87, ....

è possibile creare un elenco di valori univoci, che utilizzare e indice in sostituzione,

34,45,54,56,78,87,1212

riga 1: 6,0,2,6,1,0, .....

questo può potantialy risparmiare oltre il 30% o più il trasferimento dei dati, ma dipende da come ridondante dei dati è

UPDATE

Ecco una semplice implementazione

std::set<int> uniqueValues 
DataTable my2dData; //assuming 2d vector implementation 
std::string indexMap; 
std::string fileCompressed = ""; 

int Find(int value){ 
    for(int i = 0; i < uniqueValues.size; ++i){ 
    if(uniqueValues[i] == value) return i; 
    } 
    return -1; 
} 

//create list of unique values 
for(int i = 0; i < my2dData.size; ++i){ 
    for(int j = 0; j < my2dData[i].size; ++j){ 
    uniqueValues.insert(my2dData[i][j]); 
    } 
}  

//create indexes 
for(int i = 0; i < my2dData.size; ++i){ 
    std::string tmpRow = ""; 
    for(int j = 0; j < my2dData[i].size; ++j){ 
    if(tmpRow == ""){ 
     tmpRow = Find(my2dData[i][j]);  
    } 
    else{ 
     tmpRow += "," + Find(my2dData[i][j]); 
    } 
    } 
    tmpRow += "\n\r"; 
    indexMap += tmpRow; 
} 

//create file to transfer 
for(int k = 0; k < uniqueValues.size; ++k){ 
    if(fileCompressed == ""){ 
     fileCompressed = "i: " + uniqueValues[k];  
    } 
    else{ 
     fileCompressed += "," + uniqueValues[k]; 
    } 
} 
fileCompressed += "\n\r\d:" + indexMap; 

ora sul lato di ricezione è sufficiente fare il contrario, se la linea di partenza con "i" si ottiene l'indice, se si inizia con " d "ottieni i dati

+0

Grazie Fabrizio. Ho in mente qualcosa di simile, tuttavia, prima di implementare tale metodo, sto cercando un algoritmo di compressione standard progettato per i dati ridondanti (con il modello specifico menzionato). – beebee

+0

Penso che @Fabrizio abbia ragione, ma immagino che zlib sia anche una soluzione abbastanza accettabile del tuo problema. È necessario trovare il punto di equilibrio tra alte prestazioni e alta complessità. – Netherwire

+1

la libreria che hai menzionato fa un buon lavoro, ma come tutte le librerie di carattere generale sono implementate per essere "generali" che potrebbero non essere le migliori per tutte le situazioni, l'esempio che ti ho fornito è usato dai file di dati 3d .obj formato, e non dovrebbe richiedere molto tempo per implementare ed è silenzioso potente http://en.wikipedia.org/wiki/Wavefront_.obj_file – Sherlock

4

Prima di eseguire la compressione, controllare PNG algorithms for filtering image data. Sono semplici metodi più sofisticati per la previsione dei valori in un array 2D basato su valori precedenti. Nella misura in cui le previsioni sono buone, il filtraggio può apportare notevoli miglioramenti nella successiva fase di compressione.

Dovresti semplicemente provare questi filtri sui tuoi dati e quindi inviarli a lz4.

+0

Grazie Mark, ho ottenuto il concetto e penso che il concetto di pixel vicini potrebbe essere esteso a più dei vicini 1 pixel vicini ... Sto pensando di avere una finestra di distanza n pixel in tutte le direzioni e quindi forse usare il filtro tipo 3 ... – beebee

+0

ma ancora non sono sicuro di come trovare 1 in tempo ragionevole e 2- cosa fare con i bordi ... – beebee

+0

Per i bordi, trattarlo come se fosse la matrice circondato da zeri. –