2013-08-05 10 views
5

私はかなり長い間この問題に取り組んできましたが、私の創造性が終わったので、他の誰かが私に正しい方向を教えてくれることを願っています。私はKinectと協力し、MATLABにデータをキャプチャしようとしています。幸いにも、これを行う方法はかなりあります(私は現在http://www.mathworks.com/matlabcentral/fileexchange/30242-kinect-matlabを使用しています)。キャプチャしたデータを3Dに投影しようとすると、私の伝統的な方法では再構成結果が悪くなりました。なぜキンクの色と深度が正しく整列しないのですか?

短いストーリーを短縮するために、私は、再構成とアライメントを実行するmatlab用のKinect SDKラッパーを作成しました。復興はあなたがここに見ることができるように私は、アライメントとのトラブルのトンを持っています

を夢のように動作しますが、...:

enter image description here

モデルであまりよく見ないでください。 (あなたが見ることができるように。

、アライメントが正しくありません。それが事実だ、なぜ私はよく分からない。私は他の人が同じ方法で私よりも多くの成功を収めているフォーラムをたくさん読んだ。

現在のパイプラインでKiを使用していますMatlab(Openniを使用)を使用してデータをキャプチャし、Kinect SDKを使用して再構築した後、Kinect SDKを使用して整列します(NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolutionによる)。私はそれがおそらくOpenniに起因すると思っていましたが、Kinect SDKを使用してキャプチャするmex関数呼び出しの作成にほとんど成功しませんでした。

誰かが私をより深く掘り下げるべき方向に向けることができれば、非常に感謝しています。

編集:

図はコードを投稿する必要があります。これは私が、アライメントに使用するコードです:

/* The matlab mex function */ 
    void mexFunction(int nlhs, mxArray *plhs[], int nrhs, 
      const mxArray *prhs[]){ 

     if(nrhs < 2) 
     { 
      printf("No depth input or color image specified!\n"); 
      mexErrMsgTxt("Input Error"); 
     } 

     int width = 640, height = 480; 

     // get input depth data 

     unsigned short *pDepthRow = (unsigned short*) mxGetData(prhs[0]); 
     unsigned char *pColorRow = (unsigned char*) mxGetData(prhs[1]); 

     // compute the warping 

     INuiSensor *sensor = CreateFirstConnected(); 
     long colorCoords[ 640*480*2 ]; 
     sensor->NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution(
       NUI_IMAGE_RESOLUTION_640x480, NUI_IMAGE_RESOLUTION_640x480, 
       640*480, pDepthRow, 640*480*2, colorCoords); 
     sensor->NuiShutdown(); 
     sensor->Release(); 

     // create matlab output; it's a column ordered matrix ;_; 

     int Jdimsc[3]; 
     Jdimsc[0]=height; 
     Jdimsc[1]=width; 
     Jdimsc[2]=3; 

     plhs[0] = mxCreateNumericArray(3, Jdimsc, mxUINT8_CLASS, mxREAL); 
     unsigned char *Iout = (unsigned char*)mxGetData(plhs[0]); 

     for(int x = 0; x < width; x++) 
      for(int y = 0; y < height; y++){ 

       int idx = (y*width + x)*2; 
       long c_x = colorCoords[ idx + 0 ]; 
       long c_y = colorCoords[ idx + 1 ]; 

       bool correct = (c_x >= 0 && c_x < width 
         && c_y >= 0 && c_y < height); 
       c_x = correct ? c_x : x; 
       c_y = correct ? c_y : y; 

       Iout[ 0*height*width + x*height + y ] = 
         pColorRow[ 0*height*width + c_x*height + c_y ]; 
       Iout[ 1*height*width + x*height + y ] = 
         pColorRow[ 1*height*width + c_x*height + c_y ]; 
       Iout[ 2*height*width + x*height + y ] = 
         pColorRow[ 2*height*width + c_x*height + c_y ]; 

      } 

    } 
+0

あなたの質問に対する回答が関連していて、自分の問題を解決したかどうかを他人に知らせるべきです。そうでない場合はなぜですか?それがこのコミュニティの仕組みです。 – masad

+0

masadに:はい、あなたの返事に感謝します。あなたの答えがまだ働いているかどうかを確認する機会はありませんでしたが、今私はそうしています。あなたはちょっとだけ教えてくれます。 – vsector

答えて

5

これは、ステレオビジョンシステムのためのよく知られた問題です。私は同じ問題を抱えていました。投稿した最初の質問はhereです。私がしようとしていたのは、これと似たようなものでした。しかし、多くの研究の後、捕捉されたデータセットを容易に整列させることができないという結論に至りました。

一方、データセットを記録する際に、関数呼び出しを使用してRGBデータと深さデータの両方を簡単に整列させることができます。このメソッドは、OpenNIとKinect SDKの両方で使用できます(機能は同じですが、関数呼び出しの名前はそれぞれ異なります)

Kinect SDKを使用してデータセットをキャプチャし、Kinect SDK MapDepthFrameToColorFrameを使用できます。

OpenNIを使用して説明したので、AlternativeViewPointCapabilityをご覧ください。

depth.GetAlternativeViewPointCap().SetViewPoint(image); 

imageは、画像生成ノードは次のとおりです。

しかし私は、OpenNI V1.5でこの全体の問題は、レコーダーのノードを登録する前に、次の関数呼び出しを行うことによって解決された、のKinect SDKとの経験がありませんdepthは深さジェネレータノードです。これはOpenNI 2.0 SDKに置き換えられた古いSDKで行われました。したがって、最新のSDKを使用している場合、関数呼び出しは異なる可能性がありますが、全体の手順は似ている可能性があります。私はまた、いくつかの例のイメージを追加してい

:そこ(深度エッジを完全に整列されます関数呼び出しを使用する場合

RGB上の深度エッジを呼び出す上記アライメント機能を使用しないが Without Alignment

に整列されていませんでしたいくつかの縁を示すいくつかの赤外線影領域があるが、それらは単に無効な深さ領域である)

With Alignment
+0

ありがとうございます。私はすでに整列を試みたが、失敗した。結局のところ、私は適切なコールを使用していましたが、Kinectには余分な "つかの間"があります。 「一般的なNUIの問題とよくある質問」(http://social.msdn.microsoft.com/Forums/en-US/4da8c75e-9aad-4dc3-bd83-d77ab4cd2f82/common-nui-problems-and-faq)プレーヤーのインデックスもデプス値に格納されているため、Kinectから取得したデプス値を3ビットシフトする必要があることを示しています。調整後、私の元のコードを使用して整列が正常に動作します。私はあなたのリンクなしでこれを見つけられませんでした:)。 – vsector

+1

私はあなたの応答を答えとして設定するつもりです。それは、重要な背景、例、および整列の問題に対するコードも提供するからです。 – vsector

1

enter image description here depth.GetAlternativeViewPointCap()SetViewPoint(画像)。

でも問題はありませんが、問題は、(FOCAL_rgb/FOCAL_kinectによって)奥行き画像をダウンスケーリングし、奥行きピクセルを視差d = focal * B/zでシフトすることです。工場出荷時の設定によってはわずかに回転することもあります。

このように、これらの変換を元に戻すことなく、3つのリアルワールド座標をすべて復元することはできません。これは、正確なx、yに依存せず、zのみを考慮する(セグメンテーションなど)メソッドは、シフトされたシフトされたマップでもうまく機能すると言われています。さらに、より優れたセグメンテーションを実行するために、色と深さを利用することができます。

1

Kinect SDKを使用してU、Vテクスチャマッピングパラメータを読み取ることで、奥行きフレームとカラーフレームを簡単に揃えることができます。デプスフレームD(i、j)の各ピクセル座標(i、j)について、カラーフレームの対応するピクセル座標は(U(i、j)、V(i、j))によって与えられ、 C(U(i、j)、V(i、j))によって表される。

U、V機能は、各Kinectのハードウェアに含まれています。工場でハードウェアボードに接着したときの僅かな差異のため、デプスカメラとビデオカメラの位置が異なるため、KinectとKinectは異なります。しかし、Kinect SDKからU、Vを読んでも心配する必要はありません。

public class Kinect extends J4KSDK{ 

    VideoFrame videoTexture; 

public Kinect() { 
    super(); 
    videoTexture=new VideoFrame(); 
} 

@Override 
public void onDepthFrameEvent(short[] packed_depth, int[] U, int V[]) { 
    DepthMap map=new DepthMap(depthWidth(),depthHeight(),packed_depth); 
    if(U!=null && V!=null) map.setUV(U,V,videoWidth(),videoHeight()); 
} 

@Override 
public void onVideoFrameEvent(byte[] data) {  
    videoTexture.update(videoWidth(), videoHeight(), data); 
} } 

同じ深さ-Videoの整列フレームの異なる3つの視点を示す画像例: 私はあなたのイメージの一例とJ4K open source libraryとJavaでのKinect SDKを使用して実際のソースコードの例を与える以下

enter image description here

私はこれがあなたを助けてくれることを願っています!

関連する問題