2013-04-10 15 views
18

私はKinectセンサーで作業しています。奥行きとカラーフレームを整列させて、お互いに「収まる」イメージとして保存できるようにしています。私はmsdnフォーラムやKinect SDKの控えめなドキュメンテーションを通して多くの時間を費やしてきました。私は絶対にどこにも行きません。Kinect SDK:奥行きとカラーフレームを整列する

この回答に基づいて:Kinect: Converting from RGB Coordinates to Depth Coordinates

Iは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

は、Windowsの例を符号化するためのKinectでグリーンスクリーンの例をチェックアウトしたことがありますか? http://kinectforwindows.codeplex.com/。それは色と深さを揃えます。 –

+0

はい私は持っています。新しい 'INuiCoordinateMapper'を使用するのではなく、古いメソッド' INuiSensor :: NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution'を使用します。私はそれを試してみたと私のいずれか(私はすべての白いイメージを取得)のために動作しません。どういうわけか、得られる深度値の配列はUSHORT(16ビット)であり、私のものは32ビットです。私はKinectセンサーを異なるパラメーター(深度のみプレーヤーインデックスなし)で初期化するという考えられる理由があります。私が32ビットから16ビット深度の値の配列を作成したとしても、関数は私のためには機能しません。 – jaho

+0

似たようなことがここで解決されました:http://stackoverflow.com/a/19905805/2521214 Kinect SDKには画像を整列させる機能がありますが、私にとってはうまく機能しませんでした(非常に古いバージョンのkinectを持っています)。自分自身...私のキネクト校正データです。自分で測定する必要があります。 – Spektre

答えて

2

OpenNIフレームワークでは、オプション呼び出し登録があります。

IMAGE_REGISTRATION_DEPTH_TO_IMAGE - 奥行き画像は、RGB画像と同じ見掛けの視点を持つように変換されます。

OpenNI 2.0とNite 2.0は、Kinect情報をキャプチャするのに非常にうまく機能し、多くのチュートリアルがあります。

あなたはこれを見持つことができます。

Kinect with OpenNI

そしてOpenNiは深さと色の多分あなたはちょうどその上で見て、それを試すことができますマージSimplerViewerの例を持っています。

0

これはあなたの望む迅速な回答ではないかもしれませんが、この変換はopenFrameworks (see here)ofxKinectNuiアドオン内で正常に実行されます。

GetColorPixelCoordinatesFromDepthPixel関数へのofxKinectNui代理人の定義はhereです。

0

MapDepthFrameToColorFrameを実際に呼び出す必要がある場合は、MapColorFrameToDepthFrameを呼び出すことが問題だと思います。

喫煙ガンのコード行される:pos = depthPoints[i]は深さがiに色座標に対応する座標を表すので

mappedRun[i] = colorRun[pos]; 

posから読み取り、iへの書き込みは、逆方向です。実際にはすべての奥行きの座標を書き込んで反復し、対応するの色座標の入力カラー画像から読み取りたいとします。

+0

これらの機能はこのように交換可能ですか? –

0

あなたのコードには正しい行が異なると思います。

まず、あなたの関数にどの深度マップを渡していますか?

深度データは、各値に2バイトを使用して格納されます。つまり、深度データ に使用する正しいポインタのタイプはです。符号なしshortです。

2点目は、私が理解しているものから、あなたは色のフレームに奥行きフレームをマッピングしたいということですので、あなたがのKinect SDKから呼び出すこと を持って正しい関数ではなくMapColorFrameToDepthFrameのMapDepthFrameToColorFrameです。

最後に、関数は位置[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が色及び深さデータとの間の正確な整列機能を提供しないことに注意してください。

2つの画像を正確にアライメントするには、較正モデルを使用する必要があります。 その場合は、Heikkilä校正モデルに基づいてKinectキャリブレーションツールボックスを使用することをお勧めします。

次のリンクからご覧いただけます。
http://www.ee.oulu.fi/~dherrera/kinect/

-1

まず、デバイスをキャリブレーションする必要があります。 つまり、RGBセンサーとIRセンサーを較正し、RGBとIRの間の変換を見つける必要があります。それの更なる詳細については

RGBPoint = RotationMatrix * DepthPoint + TranslationVector 

チェックOpenCVのか、ROSのプロジェクト:あなたは、この情報を知っている たら、関数を適用することができます。

Extrinsic Calibration

Intrinsic Calibration

+0

変換に関する情報はどこにありますか? – ThunderWiring

+0

@ThunderWiring詳細はこちらhttp://wiki.ros.org/openni_launch/Tutorials/IntrinsicCalibrationここをクリック:http://wiki.ros.org/openni_launch/Tutorials/ExtrinsicCalibration – madduci

関連する問題