2013-06-09 11 views
5

Sto lavorando con un dato set di dati utilizzando OpenCV, senza Kinect al mio fianco. E vorrei mappare i dati di profondità dati alla sua controparte RGB (in modo da ottenere il colore e la profondità effettivi)Come si mappano i dati di profondità di Kinect al colore RGB?

Poiché utilizzo OpenCV e C++ e non possiedo un Kinect, purtroppo I non può utilizzare il metodo MapDepthFrameToColorFrame dall'API Kinect ufficiale.

Da intrinseche delle dato telecamere e coefficienti di distorsione, ho potuto mappare la profondità alle coordinate mondo, e di nuovo a RGB in base all'algoritmo fornito here

Vec3f depthToW(int x, int y, float depth){ 
    Vec3f result; 
    result[0] = (float) (x - depthCX) * depth/depthFX; 
    result[1] = (float) (y - depthCY) * depth/depthFY; 
    result[2] = (float) depth; 
    return result; 
} 

Vec2i wToRGB(const Vec3f & point) { 
    Mat p3d(point); 
    p3d = extRotation * p3d + extTranslation; 

    float x = p3d.at<float>(0, 0); 
    float y = p3d.at<float>(1, 0); 
    float z = p3d.at<float>(2, 0); 

    Vec2i result; 
    result[0] = (int) round((x * rgbFX/z) + rgbCX); 
    result[1] = (int) round((y * rgbFY/z) + rgbCY); 
    return result; 
} 


void map(Mat& rgb, Mat& depth) { 
    /* intrinsics are focal points and centers of camera */ 
    undistort(rgb, rgb, rgbIntrinsic, rgbDistortion); 
    undistort(depth, depth, depthIntrinsic, depthDistortion); 

    Mat color = Mat(depth.size(), CV_8UC3, Scalar(0)); 
    ushort * raw_image_ptr; 

    for(int y = 0; y < depth.rows; y++) { 
     raw_image_ptr = depth.ptr<ushort>(y); 

     for(int x = 0; x < depth.cols; x++) { 
      if(raw_image_ptr[x] >= 2047 || raw_image_ptr[x] <= 0) 
       continue; 

      float depth_value = depthMeters[ raw_image_ptr[x] ]; 
      Vec3f depth_coord = depthToW(y, x, depth_value); 
      Vec2i rgb_coord = wToRGB(depth_coord); 
      color.at<Vec3b>(y, x) = rgb.at<Vec3b>(rgb_coord[0], rgb_coord[1]); 
     } 
    } 

Ma il risultato sembra essere disallineati. Non riesco a impostare manualmente le traduzioni, poiché il set di dati è ottenuto da 3 diversi Kinect e ognuno di essi è disallineato in una direzione diversa. Si poteva vedere uno dei suoi sotto (a sinistra: non distorta RGB, Medio: senza distorsioni di profondità, a destra: mappato RGB a profondità)

enter image description here

La mia domanda è, che cosa devo fare a questo punto? Mi sono perso un passaggio mentre cercavo di proiettare la profondità nel mondo o nel mondo in RGB? Chiunque abbia esperienza con la fotocamera stereo può far notare i miei passi falsi?

Grazie mille in anticipo!

+0

Stai usando OpenNI? –

+0

Purtroppo no. Solo OpenCV –

+0

Suggerisco, dovresti usare OpenNI per recuperare i dati da Kinect. C'è una funzione incorporata in OpenNI che può farlo per te. –

risposta

0

OpenCV non ha funzioni per l'allineamento del flusso di profondità al flusso video a colori. Ma so che c'è special function chiamato MapDepthFrameToColorFrame in "Kinect per Windows SDK".

Non ho codice per esempio, ma spero che questo sia un buon punto di partenza.

Aggiornamento: Here is stesso esempio di mappatura dell'immagine a colori utilizzando KinectSDK con interfaccia a OpenCV (non il mio codice).

+0

Sì, come per il post originale, non posso usare MapDepthFrameToColorFrame (il set di dati è pgm e ppm e non ho kinect con cui lavorare). E purtroppo quello che sto cercando sono gli algoritmi interni in NuiImageGetColorPixelCoordinatesFromDepthPixel, che non riesco a trovare da nessuna parte (non sembra che sia open source) –

1

Suppongo che sia necessario calibrare il sensore di profondità con i dati RGB nello stesso modo in cui si calibrano le telecamere stereo. OpenCV ha alcune funzioni (e tutorial) che potresti essere in grado di sfruttare.

A poche altre cose che possono essere utili

  1. http://www.ros.org/wiki/kinect_calibration/technical
  2. https://github.com/robbeofficial/KinectCalib
  3. http://www.mathworks.com/matlabcentral/linkexchange/links/2882-kinect-calibration-toolbox Questo contiene un articolo su come farlo.
+0

Ah, sto già usando i parametri (intrinseca della fotocamera, distorsioni e parametri estrinseci) che altri utenti hanno già eseguito su di esso la calibrazione. Il mio problema principale sembra essere l'allineamento, che potrebbe essere un passo che ho perso, o così. –

0

Sembra che tu non stia considerando nella tua soluzione gli estrinseci tra le due telecamere.

0

Sì, non è stata considerata la trasformazione tra RGB e profondità. Ma è possibile calcolare questa matrice usando il metodo cvStereoCalibrate() che passa semplicemente le sequenze di immagini sia di RGB che di Profondità con gli angoli della scacchiera. Il dettaglio si può trovare in OpecvCV documentazione: http://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#double stereoCalibrate (InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints1, InputArrayOfArrays imagePoints2, InputOutputArray cameraMatrix1, InputOutputArray distCoeffs1, InputOutputArray cameraMatrix2, InputOutputArray distCoeffs2, Dimensioni ImageSize, outputArray R, outputArray T, outputArray E, outputArray F, TermCriteria criteri, bandiere int)

E il metodo intera idea alla base di questo è:

colore uv < - colore normalizzare < - spazio colore < - DTOC trasformazione < - profondità dello spazio < - profondità di normalizzare < - Profondità uv (uc, vc) <-< - ExtrCol * (pc) < - stereo calibrare MAT < - ExtrDep^-1 * (pd) <-< (UD - cx) * d/fx, (vd- cy) * d/fy, d> < - (UD, vd)

Se si desidera aggiungere la distorsione a RGB, non vi resta che seguire il passo in: http://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html

Problemi correlati