2013-06-26 118 views
0

我試圖將我的OpenNI(1.5.4.0)Kinect 4 Windows深度圖映射到OpenCV RGB圖像。三維映射深度到RGB(Kinect OpenNI深度圖到OpenCV RGB凸輪)

我有深度圖640×480,在毫米深度的試圖做這樣巴瑞斯的映射: http://burrus.name/index.php/Research/KinectCalibration

我跳過了失真的一部分,但否則我所做的一切,我認爲:

//with depth camera intrinsics, each pixel (x_d,y_d) of depth camera can be projected 
//to metric 3D space. with fx_d, fy_d, cx_d and cy_d the intrinsics of the depth camera. 

P3D.at<Vec3f>(y,x)[0] = (x - cx_ir) * depth/fx_ir; 
P3D.at<Vec3f>(y,x)[1] = (y - cy_ir) * depth/fy_ir; 
P3D.at<Vec3f>(y,x)[2] = depth; 


//P3D' = R.P3D + T: 
RTMat = (Mat_<float>(4,4) << 0.999388, -0.00796202, -0.0480646, -3.96963, 
0.00612322, 0.9993536, 0.0337474, -22.8512, 
0.0244427, -0.03635059, 0.999173, -15.6307, 
0,0,0,1); 

perspectiveTransform(P3D, P3DS, RTMat); 

//reproject each 3D point on the color image and get its color: 
depth = P3DS.at<Vec3f>(y,x)[2]; 
x_rgb = (P3DS.at<Vec3f>(y,x)[0] * fx_rgb/ depth + cx_rgb; 
y_rgb = (P3DS.at<Vec3f>(y,x)[1] * fy_rgb/ depth + cy_rgb; 

但我的估計的RGB攝像機和Kinect的紅外攝像機的校準值,我的結果在每個方向都失敗了,不能僅僅通過改變外部T參數來固定。

我有幾個suspisions:

  • 沒有OpenNi已經紅外深度圖映射到 的Kinect的RGB攝像頭?
  • 我應該使用深度以米爲單位還是將像素轉換爲 毫米? (我試圖乘以pixel_size * 0.001但我得到了 相同的結果)

真的希望有人能幫助我。 Thx提前。

回答

1

AFAIK OpenNI是否自己註冊(出廠設置),您也可以切換註冊。如果你已經建立的OpenCV與OpenNI支持它是如此簡單:

capture.set(CV_CAP_PROP_OPENNI_REGISTRATION,1); 

作爲解釋here,有一個最小的OpenNI/OpenCV的例子here。 所以最小工作樣品看起來像這樣:

#include "opencv2/core/core.hpp" 
#include "opencv2/highgui/highgui.hpp" 

#include <iostream> 

using namespace cv; 
using namespace std; 

int main(){ 
    VideoCapture capture; 
    capture.open(CV_CAP_OPENNI); 
    //registration 
    if(capture.get(CV_CAP_PROP_OPENNI_REGISTRATION) == 0) capture.set(CV_CAP_PROP_OPENNI_REGISTRATION,1); 

    if(!capture.isOpened()){ 
     cout << "Can not open a capture object." << endl; 
     return -1; 
    } 
    cout << "ready" << endl; 

    for(;;){ 
     Mat depthMap,depthShow; 
     if(!capture.grab()){ 
      cout << "Can not grab images." << endl; 
      return -1; 
     }else{ 
      if(capture.retrieve(depthMap, CV_CAP_OPENNI_DEPTH_MAP)){ 
       const float scaleFactor = 0.05f; 
       depthMap.convertTo(depthShow, CV_8UC1, scaleFactor); 
       imshow("depth",depthShow); 
      } 
     } 
     if(waitKey(30) == 27) break;//esc to exit 
    } 

} 

如果你沒有跟OpenCV的支持OpenNI建,你應該能夠使用GetAlternativeViewPointCap()

+0

您好.. THX你的答案。它看起來像深度圖自動映射到RGB Kinect相機。如果我正確地理解了你,那你也是這麼說的。 我沒有使用opencv來獲得我的深度圖,我試圖用GetAlternativeViewPointCap()(它支持)來改變它,但是當我嘗試將它設置爲紅外攝像機時,我得到:「該值無效!」 代碼:IRGenerator ir; context.FindExistingNode(XN_NODE_TYPE_IR,ir); depth.GetAlternativeViewPointCap()。SetViewPoint(ir); – ddd

+0

通常你會使用深度圖和rgb圖。您如何計劃使用IR映射? –

+0

不,我使用深度圖..但因爲它是用紅外攝像機(深度圖)拍攝的,所以我用紅外攝像機內在函數和外部參數來映射我的第二個非運動相機的RGB圖像上的深度圖。 – ddd