2012-04-11 15 views
5

Riguarda la decompressione dei valori rgb codificati in un file pcl. L'ho fatto con la procedura descritta nella documentazione di pcl, ma i valori rgb decompressi che ottengo non sono del tutto corretti. Quando li diagramma con R, la rappresentazione data non corrisponde ai colori nel contesto reale (sono certo che il problema non è il modo in cui è stato tracciato con R).Disimballaggio dei valori RGB in un dataset nuvola di punti

Ad esempio nell'immagine allegata l'area delimitata dovrebbe avere i colori grigio e blu (due sedie e un tavolo). unpacked pcl data plotted with the rgl library in R

di file PCL fonte potrebbe essere trovata a: https://docs.google.com/open?id=0Bz5-HVcDiF6SanBZU0JWVmJwWHM e il file con i valori di colore non imballati in: https://docs.google.com/open?id=0Bz5-HVcDiF6SV2pYQ0xUbTAwVmM. Inoltre segue è il codice utilizzato per decomprimere i valori di colore in un c plus plus impostazione:

uint32_t rgbD = *reinterpret_cast<int*>(&kinectValue); 

    uint16_t rD = (rgbD >> 16) & 0x0000ff; 
    uint16_t gD = (rgbD >> 8) & 0x0000ff; 
    uint16_t bD = (rgbD)  & 0x0000ff; 

Vorrei davvero apprezzare se potesse farmi sapere dove ho sbagliato.

Aggiornamento:

seguito riporta il codice R frammento di che ho usato nel tracciare i valori in 3D:

library(rgl) 
pcd <- read.table(file.choose(),sep="") 
names(pcd) <- c("x","y","z","r","g","b") 
plot3d(pcd$x,pcd$y,pcd$z,col=rgb(pcd$r,pcd$g,pcd$b,maxColorValue=255)) 

Aggiornamento:

seguito è il codice che ho usato per leggere i dati, in C++ :

/* 
Reads in a file from Kinect with unpacked color values, filter the color value component and 
sends it to be unpacked 
*/ 
int fileRead(){ 

    string line; 
    int lineNum = 0; 

    ifstream myfile ("res/OnePerson4.pcd"); 

    if (myfile.is_open()) 
    { 
    while (myfile.good()) 
    { 
     lineNum++; 
     getline (myfile,line); 

     // Exclude the header information in the kinect file from the unpacking process 
     //if(lineNum > 10 && lineNum <20){//This for loop is activated when testing 
     if(lineNum > 10){ 
     //Test code to extract the x,y,z values 
     string xyzvalFromKinectStr = line.substr(0,line.find_last_of(' ')); 
     //cout<<xyzvalFromKinectStr<<"\n"; 
     //Extract the packed rgb value 
     string valFromKinectStr = line.substr(line.find_last_of(' ')); 
     double kinectVal = ::atof(valFromKinectStr.c_str()); 
     kinectToRgb(kinectVal, xyzvalFromKinectStr); 

     } 
    } 
    myfile.close(); 
    } 
    else 
    { 
     cout << "Unable to open file"; 
    } 

    return 0; 
} 
+1

Entrambi i collegamenti scaricano zero byte per me. –

+0

@ MichaelDaum, mi dispiace per quello. Rettificherò presto il problema. Grazie per aver dedicato del tempo a guardare al problema. –

+1

RGB viene in genere rappresentato come RGBA. Questo può essere diverso a seconda della piattaforma, ma dovresti provare (rgbD >> 24), >> 16 e >> 8 per R G e B rispettivamente. Ma poiché probabilmente non è questo il problema ... Stai cercando di ottenere R-G-B in uno spazio tridimensionale spoglio. Credi che il disimballaggio del colore sia errato, ma sei completamente sicuro che non sia il codice del disegno o il codice I/O del file? –

risposta

9

Ecco la mia soluzione di lavoro. In primo luogo ho incontrato il vostro input attraverso grep per filtrare i Nans in coordinate:

$ grep -v nan OnePerson4.pcd > OnePerson4.pcd.filtered 

Poi ho estratto i dati tramite codice C++ in questo modo:

#include <stdio.h> 

int main() 
{ 
    if (FILE *f = fopen("OnePerson4.pcd.filtered", "rt")) 
    { 
     for (;;) 
     { 
      float x = 0; 
      float y = 0; 
      float z = 0; 
      float color_float = 0; 
      if (fscanf(f, "%f %f %f %f", &x, &y, &z, &color_float) != 4) 
      { 
       break; 
      } 

      unsigned color = *(unsigned const *)&color_float; 
      unsigned r = color & 0xff; 
      unsigned g = (color >> 8) & 0xff; 
      unsigned b = (color >> 16) & 0xff; 
      printf("%f,%f,%f,%d,%d,%d\n", x, y, z, r, g, b); 
     } 

     fclose(f); 
    } 

    return 0; 
} 

non sapevo in quale ordine di byte RGB è memorizzato, quindi potresti dover scambiare R e B. Di solito è RGB o BGR.

poi ho usato il codice per tracciare i punti (ho cambiato read.table-read.csv):

library(rgl) 
pcd <- read.csv(file.choose()) 
names(pcd) <- c("x","y","z","r","g","b") 
plot3d(pcd$x,pcd$y,pcd$z,col=rgb(pcd$r,pcd$g,pcd$b,maxColorValue=255)) 

E questo è ciò che ottengo:

enter image description here

quindi sto assumendo il problema è con il codice in cui leggi il tuo colore dal file pcd. Il resto mi sta bene.

Aggiornamento: Il tuo problema è il tipo double. Cambialo a float e dovrebbe funzionare. Anche se la memorizzazione di unsigned int come float è, per lo meno, discutibile. Questo è fragile e non garantisce che i colori siano corretti dopo la lettura. Alcuni bit potrebbero essere spenti.

Un'altra nota: è possibile utilizzare l'operatore di flusso >> per estrarre i numeri dal file. È molto più facile che analizzarlo manualmente con i metodi string. Puoi leggere a riguardo, ad esempio, here.

+0

grazie mille per la risposta. Questo sembra molto interessante. Pubblicherò il codice che ho usato anch'io, quindi potresti essere in grado di vedere dove ho sbagliato. –

+0

Ho aggiunto il codice C++ con cui ho letto i dati. –

+1

Ho aggiornato il post con i miei commenti sul codice. – detunized

Problemi correlati