2012-10-31 13 views
8

Nella mia applicazione ottengo la cornice di profondità simile alla cornice di profondità recuperata dall'esempio di base di profondità. Quello che non capisco è, perché ci sono livelli discreti nell'immagine? Non so come posso chiamare questi improvvisi cambiamenti nei valori di profondità. Chiaramente la mia metà della mia mano destra è tutta nera e la mia mano sinistra sembra divisa in 3 di questi livelli. Cos'è questo e come lo rimuovo?Immagine profondità Kinect

Kinect Depth Basics Sample http://i46.tinypic.com/2hwekxd.jpg

Quando esegue l'esempio app KinectExplorer ottengo la profondità come segue. Questa è l'immagine di profondità che voglio generare dai dati di profondità grezza.

Kinect Explorer http://i50.tinypic.com/2rwx1z5.jpg

Sto usando Microsoft Kinect SDK (v1.6) NuiApi con OpenCV. Ho il codice seguente:

BYTE *pBuffer = (BYTE*)depthLockedRect.pBits; //pointer to data having 8-bit jump 
USHORT *depthBuffer = (USHORT*) pBuffer; //pointer to data having 16-bit jump 
int cn = 4; 
this->depthFinal = cv::Mat::zeros(depthHeight,depthWidth,CV_8UC4); //8bit 4 channel 
for(int i=0;i<this->depthFinal.rows;i++){ 
    for(int j=0;j<this->depthFinal.cols;j++){ 
     USHORT realdepth = ((*depthBuffer)&0x0fff); //Taking 12LSBs for depth 
     BYTE intensity = (BYTE)((255*realdepth)/0x0fff); //Scaling to 255 scale grayscale 
     this->depthFinal.data[i*this->depthFinal.cols*cn + j*cn + 0] = intensity; 
     this->depthFinal.data[i*this->depthFinal.cols*cn + j*cn + 1] = intensity; 
     this->depthFinal.data[i*this->depthFinal.cols*cn + j*cn + 2] = intensity; 
     depthBuffer++; 
    } 
} 
+0

Si prega di ricontrollare le immagini, non vengono visualizzati. –

+0

Modificato l'URL dell'immagine. Controlla di nuovo. – thinkquester

+0

Che cos'è '' cn'' e deve essere davvero '' 4'' e non '' 3''? Sarebbe anche gread per vedere dove effettivamente l'output dell'immagine. – Tim

risposta

0

La visualizzazione dei dati di immagine di profondità ha livelli discreti che sono grossolana (da 0 a 255 in esempio di codice), ma i dati dell'immagine profondità effettiva sono numeri compresi tra 0 e 2047. Ancora discreto, certo, ma non in unità così grossolane come i colori scelti per rappresentarli.

5

Le strisce che si vedono sono dovute al valore di profondità wrapping come causato dall'operazione %256. Invece di applicare dell'operazione modulo (%256), che causa le bande di presentarsi, riassociare i valori di profondità lungo l'intero intervallo, ad esempio:

BYTE intensity = depth == 0 || depth > 4095 ? 0 : 255 - (BYTE)(((float)depth/4095.0f) * 255.0f); 

nel caso la profondità massima è 2048, sostituire il 4095 con 2047 .

Più puntatori:

  1. il Kinect ritorna presumibilmente un valore 11bit (0-2047), ma si usa solo 8bit (0-255).
  2. nuove versioni Kinect sembrano restituire un valore a 12 bit (0-4096)
  3. nel codice sorgente di Kinect esploratore, c'è un file chiamato DepthColorizer.cs dove la maggior parte della magia sembra accadere. Credo che questo codice renda i valori di profondità così semplici nell'esploratore di kinect - ma potrei sbagliarmi.
+0

Se avete avvolto i valori di profondità usando un valore minore come modulo, le bande dovrebbero essere più distanti? –

1

Ho affrontato lo stesso problema mentre stavo lavorando a un progetto che prevedeva la visualizzazione della mappa di profondità. Comunque ho usato OpenNI SDK con OpenCV invece delle librerie di Kinect SDK. Il problema era lo stesso e quindi la soluzione funzionerà per te come ha fatto per me.

Come menzionato nelle precedenti risposte alla tua domanda, la mappa della profondità di Kinect è 11 bit (0-2047). Mentre negli esempi, vengono utilizzati i tipi di dati a 8 bit.

Quello che ho fatto nel mio codice per aggirare il problema è stato quello di acquisire la mappa di profondità in una stuoia a 16 bit, e quindi convertirlo in 8-bit uchar Mat utilizzando le opzioni di scala in convertTo funzione per Mat

prima inizializzo un Mat per acquisire dati di profondità

Mat depthMat16UC1(XN_VGA_Y_RES, XN_VGA_X_RES, CV_16UC1); 

Qui XN_VGA_Y_RES, XN_VGA_X_RES definisce la risoluzione della mappa di profondità acquisita.

Il codice dove faccio questo è il seguente:

depthMat16UC1.data = ((uchar*)depthMD.Data()); 
depthMat16UC1.convertTo(depthMat8UC1, CV_8U, 0.05f); 
imshow("Depth Image", depthMat8UC1); 

depthMD è metadati contenente i dati recuperati dal sensore Kinect.

Spero che questo ti aiuti in qualche modo.

0

Il kinect v2 può vedere una profondità di 8 metri (ma la precisione oltre 4,5 diminuisce). Inizia circa 0,4 metri. Quindi è necessario esprimere un numero 8000 a un colore. Un modo per farlo è usare i colori RGB solo un numero. quindi potresti potenzialmente memorizzare un numero come 255x255x255 i un pixel. Oppure se avessi un diverso formato di colore, sarebbe diverso. Memorizzando 8000 in quel numero massimo 255x255x255 si otterrà un certo numero di R + G + B, e questo produce questo effetto di banding.

Tuttavia, è possibile distinguere 8000 o sottrarre un numero o rimuovere oltre un determinato valore.