2013-06-09 19 views
5

OpenCV kullanarak herhangi bir Kinect kullanmadan, verili bir veri kümesiyle çalışıyorum. Ve ben verilen derinlik verisini RGB karşıtına eşlemek istiyorum (böylece gerçek rengi ve derinliği elde edebilirim)Kinect'in derinlik verilerini RGB rengine nasıl eşlersiniz?

OpenCV ve C++ kullanıyorum ve bir Kinect'e sahip olmadığım için ne yazık ki resmi Kinect API'sinden MapDepthFrameToColorFrame yöntemini kullanamaz. Dünya koordinatları verilen kameraların intrinsics ve distorsiyon katsayıları itibaren

, bu derinliği harita olabilir ve geri RGB 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]); 
     } 
    } 

sağlanan algoritmaya göre Ama sonuç yanlış hizalanmış gibi görünüyor. Çevirileri el ile ayarlayamıyorum, çünkü veri kümesi 3 farklı Kinekt'ten elde edildi ve her biri farklı yönde yanlış hizalanmış. Bu noktada yapmalı,

enter image description here

Benim sorum (Derinliği RGB eşleştirilmiş: dağılmayan RGB, Orta: dağılmayan Derinlik, Sağ Sol) Aşağıdaki bunun birini görebiliyordu? Dünyaya ya da dünyaya geri dönüşü RGB'ye yansıtmaya çalışırken bir adımı özledim mi? Stereo kamera ile deneyimleyen herkes benim yanlışlarımı işaret edebilir mi?

Çok şimdiden teşekkür ederiz!

+0

Eğer OpenNI kullanıyor musunuz? –

+0

Ne yazık ki hayır. Sadece OpenCV –

+0

Önerirseniz, verileri Kinect'ten almak için OpenNI kullanmalısınız. OpenNI'da sizin için bunu yapabilecek bir dahili işlev var. –

cevap

0

OpenCV, derinlik akışını renkli video akışına hizalamak için bir fonksiyona sahip değildir. Ancak "Windows SDK için Kinect" içinde MapDepthFrameToColorFrame adlı special function olduğunu biliyorum.

Örneğin kodum yok, ancak bunun iyi bir başlangıç ​​noktası olduğunu umuyorum.

Upd: OpenCV (değil benim code) arayüzü ile KinectSDK kullanarak derinliğe haritalama renk görüntüsünün Here is aynı örnek.

+0

Orijinal postaya göre Evet, MapDepthFrameToColorFrame'yi kullanamıyorum (veri kümesi pgm ve ppm resimleridir ve üzerinde çalışmak için bir kinem yok). Ne yazık ki, gerçekten aradığım şey, NuiImageGetColorPixelCoordinatesFromDepthPixel içindeki herhangi bir yer bulamamış dahili algoritmalardır (açık kaynak kodlu gibi görünmüyor) –

1

Derinlik sensörünü bir RGB kamera ile kalibre edeceğiniz şekilde RGB verisiyle kalibre etmeniz gerektiğini düşünmekteyim. OpenCV, kaldırabileceğiniz bazı işlevlere (ve öğreticilere) sahiptir.

Bu bunu yapmak için nasıl bir kağıt içeren

  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 yararlı olabilir Birkaç başka şeyler.
+0

Ah, zaten parametreleri kullanıyorum (kamera intrinsikleri, çarpıtmalar ve Diğer kullanıcılar zaten üzerinde kalibrasyon yapmışlardır. Benim asıl problemim hizalanmış gibi gözüküyor, ki bu benim özlediğim bir adım olabilir, ya da öyle. –

0

Çözümünüzde her iki kamera arasındaki ekstrinsikleri düşünmüyor gibi görünüyor.

0

Evet, RGB ve Derinlik arasındaki dönüşümü dikkate almadınız. Ancak bu matrisi, hem RGB hem de Derinlik'in görüntü sekanslarını dama tahtası köşelerinden geçiren cvStereoCalibrate() yöntemini kullanarak hesaplayabilirsiniz.Eğer OpecvCV belgelerinde bulabilirsiniz detay: 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, Boyut imagesize, outputArray R, outputArray T outputArray E outputArray F, TermCriteria kriterler, int bayraklar)

Ve bunun arkasında bütün yöntem fikirdir:

renk uv < - renk alanı < - - DTOC dönüşümü < - derinlik alanı < - derinlik normalize renk < normalleştirmek < - derinliği UV (UC, vc) <-< - ExtrCol * (PC) < - Stereo kalibre MAT < - ExtrDep^-1 * (pd) <-< (ud - cx) x d/fx, (vd- cy) * d/fy, d> < - (ud, vd)

RGB moduna bozulmasını eklemek isterseniz, sadece adımı takip etmek gerekir: http://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html

İlgili konular