2013-04-10 73 views
18

我正在使用Kinect傳感器,我試圖對齊深度和顏色框架,以便我可以將它們保存爲適合彼此的圖像。我已經花了很多時間去了msdn論壇和Kinect SDK的適度文檔,我完全沒有辦法。Kinect SDK:對齊深度和顏色框架

基於此答案:Kinect: Converting from RGB Coordinates to Depth Coordinates

我有以下功能,其中depthDatacolorDataNUI_LOCKED_RECT.pBitsmappedData得到一種包含新彩色幀的輸出,映射到深度座標:

bool mapColorFrameToDepthFrame(unsigned char *depthData, unsigned char* colorData, unsigned char* mappedData) 
{ 
    INuiCoordinateMapper* coordMapper; 

    // Get coordinate mapper 
    m_pSensor->NuiGetCoordinateMapper(&coordMapper); 

    NUI_DEPTH_IMAGE_POINT* depthPoints = new NUI_DEPTH_IMAGE_POINT[640 * 480]; 

    HRESULT result = coordMapper->MapColorFrameToDepthFrame(NUI_IMAGE_TYPE_COLOR, NUI_IMAGE_RESOLUTION_640x480, NUI_IMAGE_RESOLUTION_640x480, 640 * 480, reinterpret_cast<NUI_DEPTH_IMAGE_PIXEL*>(depthData), 640 * 480, depthPoints); 
    if (FAILED(result)) 
    { 
     return false; 
    }  

    int pos = 0; 
    int* colorRun = reinterpret_cast<int*>(colorData); 
    int* mappedRun = reinterpret_cast<int*>(mappedData); 

    // For each pixel of new color frame 
    for (int i = 0; i < 640 * 480; ++i) 
    { 
     // Find the corresponding pixel in original color frame from depthPoints 
     pos = (depthPoints[i].y * 640) + depthPoints[i].x; 

     // Set pixel value if it's within frame boundaries 
     if (pos < 640 * 480) 
     { 
      mappedRun[i] = colorRun[pos]; 
     } 
    } 

    return true; 
} 

我運行此代碼時得到的所有像素都是未更改的顏色框,其中depthFrame沒有任何信息,所有像素均已去除(白色)。

+0

有你的Kinect的檢查了綠屏例如用於Windows編碼的例子嗎? http://kinectforwindows.codeplex.com/。它對齊顏色和深度。 – 2013-04-15 13:44:38

+0

是的,我有。它不使用新的'INuiCoordinateMapper',而是使用舊的方法'INuiSensor :: NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution'。我試過了,它也不適用於我(我得到所有白色圖像)。不知何故,他們得到的深度值數組是USHORT(16位),而我的數據是32位,可能的原因是我用不同的參數(深度只有沒有玩家指數)初始化我的Kinect傳感器。即使我從32位創建了一個16位深度值的數組,該函數也不適用於我。 – jaho 2013-04-15 14:30:00

+0

類似的東西在這裏得到了解決:http://stackoverflow.com/a/19905805/2521214 Kinect的SDK有圖像allign功能,但他們根本沒有爲我工作(有一個非常老版本的kinect),所以我做到了我自己...在這個鏈接是我的你的kinect校準數據,你必須自己測量它 – Spektre 2014-02-26 08:19:06

回答

2

隨着OpenNI框架有一個選項呼叫註冊。

IMAGE_REGISTRATION_DEPTH_TO_IMAGE - 深度圖像被轉換爲​​與RGB圖像具有相同的明顯有利位置。

OpenNI 2.0和Nite 2.0非常適合捕獲Kinect信息並且有很多教程。

你可以看看這個:

Kinect with OpenNI

而且OpenNi在SimplerViewer一個例子合併深度和色彩也許你可以只看對和嘗試。

0

這可能不是您希望的快速回答,但是此轉換已在ofxKinectNui插件中爲openFrameworks (see here)成功完成。

它看起來像ofxKinectNui代表GetColorPixelCoordinatesFromDepthPixel函數定義here

0

我認爲問題在於你調用MapColorFrameToDepthFrame時,實際上應該調用MapDepthFrameToColorFrame。

的吸菸槍是這行代碼:

mappedRun[i] = colorRun[pos]; 

pos讀取和寫入到i是向後的,因爲pos = depthPoints[i]表示深度座標對應於所述顏色在i座標。您實際上想要迭代遍歷所有深度座標並從輸入彩色圖像中讀取對應的顏色座標。

+0

這些功能是否可以這種方式互換? – 2013-12-10 01:54:11

0

我認爲在你的代碼中有不同的不正確的行。

首先,你傳遞給你的函數是哪種深度圖?

深度數據使用每個值的兩個字節storred,這意味着正確的類型,你應該爲你的深度數據 使用指針的是無符號短

第二點是,從我所瞭解,要映射深度幀彩色幀,讓你有 從Kinect的SDK調用正確的函數是MapDepthFrameToColorFrame代替MapColorFrameToDepthFrame。

最後,函數將返回一個點的映射,其中對於位置[i]處的每個深度數據,您都有位置x和位置y,其中該點應映射到 。
要做到這一點,你不需要colorData指針

所以你的函數應修改如下:

/** Method used to build a depth map aligned to color frame 
    @param [in] depthData : pointer to your data; 
    @param [out] mappedData : pointer to your aligned depth map; 
    @return true if is all ok : false whene something wrong 
*/ 

bool DeviceManager::mapColorFrameToDepthFrame(unsigned short *depthData, unsigned short* mappedData){ 
    INuiCoordinateMapper* coordMapper; 
    NUI_COLOR_IMAGE_POINT* colorPoints = new NUI_COLOR_IMAGE_POINT[640 * 480]; //color points 
    NUI_DEPTH_IMAGE_PIXEL* depthPoints = new NUI_DEPTH_IMAGE_PIXEL[640 * 480]; // depth pixel 

    /** BE sURE THAT YOU ARE WORKING WITH THE RIGHT HEIGHT AND WIDTH*/ 
    unsigned long refWidth = 0; 
    unsigned long refHeight = 0; 
    NuiImageResolutionToSize(NUI_IMAGE_RESOLUTION_640x480, refWidth, refHeight); 
    int width = static_cast<int>(refWidth ); //get the image width in a right way 
    int height = static_cast<int>(refHeight); //get the image height in a right way 

    m_pSensor>NuiGetCoordinateMapper(&coordMapper); // get the coord mapper 
    //Map your frame; 
    HRESULT result = coordMapper->MapDepthFrameToColorFrame(NUI_IMAGE_RESOLUTION_640x480, width * height, depthPoints, NUI_IMAGE_TYPE_COLOR, NUI_IMAGE_RESOLUTION_640x480, width * height, colorPoints); 
    if (FAILED(result)) 
     return false; 

    // apply map in terms of x and y (image coordinates); 
    for (int i = 0; i < width * height; i++) 
     if (colorPoints[i].x >0 && colorPoints[i].x < width && colorPoints[i].y>0 && colorPoints[i].y < height) 
      *(mappedData + colorPoints[i].x + colorPoints[i].y*width) = *(depthData + i); 

    // free your memory!!! 
    delete colorPoints; 
    delete depthPoints; 
    return true; 
} 



確保您mappedData已經正確的方式被初始化,例如如下。

mappedData = (USHORT*)calloc(width*height, sizeof(ushort)); 


記住kinect的SDK不提供顏色和深度數據之間的精確對準功能。

如果您想在兩幅圖像之間進行精確對準,則應使用校準模型。 在這種情況下,我建議您使用基於Heikkilä校準模型的Kinect校準工具箱。您可以在以下鏈接中找到它:

-1

首先,您必須校準您的設備。這意味着,你應該校準RGB和IR傳感器,然後找到RGB和IR之間的轉換。 一旦你知道這個信息,你可以應用功能:

RGBPoint = RotationMatrix * DepthPoint + TranslationVector 

檢查OpenCV的或ROS項目上的進一步細節。

Extrinsic Calibration

Intrinsic Calibration

+0

我可以在哪裏找到有關轉化的信息? – ThunderWiring 2016-09-29 09:33:15

+0

@ThunderWiring這裏你可以找到更多的細節:http://wiki.ros.org/openni_launch/Tutorials/IntrinsicCalibration這裏:http://wiki.ros.org/openni_launch/Tutorials/ExtrinsicCalibration – madduci 2016-09-29 12:53:59