2012-01-11 19 views
3

Kinectの深さマップを距離でメートルに変換しようとしています。問題は、分母の項が '0'に非常に近くなるため、デプスマップ値 '1080'とその周りの距離が大きすぎることです。 '1090'を超える値の場合、距離は負です。Kinect生の深さからメートルまでの距離

if (depthValue < 2047) 
{ 
    depthM = 1.0/(depthValue*-0.0030711016 + 3.3309495161); 
} 
+3

であるあなたがのKinect SDKを使用していますか?深さマップはミリメートル単位であり、変換する必要はありません。あなたの質問にもう少し詳しくお聞かせください。 –

+0

私は「mm」で直接深さを知ることができると知っていますが、私はKinectによって提供された生の深度値を持つ古い深度画像をいくつか持っています(0から8000以上の範囲)。私はKinectまたはOpenNi SDKを使用していません。私はちょうどそれらの生の値を 'm'のそれぞれの深さの値に変換する必要があります。多くのサイトでは、この変換で上記の関数が説明されていますが、この式は確かに値が正しくないため1080 – Saad

答えて

5

正解は実際にはあなたの質問に対するコメントです。与えられた数は実際にはミリメートル単位の距離です。この数値を取得するには、スケルトンジョイントを使用し、DepthImageFrameのMapFromSkeletonPointを呼び出すか、生のshort値をDepthImageFrame.PlayerIndexBitmaskWidthで右にシフトする必要があります。

など。スケルトン

using (var skeletonFrame= e.OpenSkeletonFrame()) 
using (var depthFrame = e.OpenDepthImageFrame()) 
{ 
    skeletonFrame.CopySkeletonDataTo(skeletons); 
    var skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength]; 

    foreach (var skeleton in skeletons) 
    { 
      if (skeleton.TrackingState != SkeletonTrackingState.Tracked) continue; 

      var head = skeleton.Joints[JointType.Head]; 
      if (head.TrackingState == JointTrackingState.NotTracked) continue; 

      var depthImagePoint = depthFrame.MapFromSkeletonPoint(head.Position); 

      int depthInMillimeters = depthImagePoint.Depth; // TADA! 
    } 
} 

などです。古い非アクティブな質問

if (depthValue <= 2047) { 
    depthM = 0.1236 * Math.Tan(depthValue/2842.5 + 1.1863); 
} 
3

とにかく、ここのために働いたものです:http://openkinect.org/wiki/Imaging_Information - この記事の内容に基づいて

:以下、オリジナルソリューションは、もはや正しいです

using (var depthFrame = e.OpenDepthImageFrame()) 
{ 
    var depthArray = new short[depthFrame.PixelDataLength]; 
    depthFrame.CopyPixelDataTo(depthArray); 

    for (int i = 0; i < depthArray.Length; i++) { 
     int depthInMillimeters = 
      depthArray[i] >> DepthImageFrame.PlayerIndexBitmaskWidth; 
     // TADAx2! 
} 

をシフトしていません私はkinectの古いモデル(XBOX360 + PCの削減のための1414)を持っていて、最近いくつかのコードと測定をする時間がありました:

  1. 私の生データは16ビットではありません10/11/12/13ビット!!!

    おそらくあなたのデータは非常に似ています。測定された最小距離は、~0.95mであり、最大距離は不明であり(テストに十分な大きさではない)、センサからの最小有効値は6408 ... ~0.95mである。私はその後、私は直線性をチェックし、それがより正確になりますより多くの時間を持つことになりますときには、別の有効な値は、補間

  2. メートル

    float z,m=(2.5-0.9)/(15800.0-6408.0); 
    WORD raw; 
    
    raw=... raw depth form camera/image; 
    z=0.0; 
    if ((raw>=6408)&&(raw< 0xFFF0)) 
    z=0.9+(float(raw-6408)*m); 
    // here z is range in [m] or 0 for invalid depth 
    
  3. にナイーブ(リニア)の形質転換のために、センサから15800 ... ~2.5mある

    私は、より正確な距離測定のためのより良い測定とセットアップのために、いくつかのプログラミングを行う必要があります。より正確な定数は、必要であれば余弦補正を加えることができる。私はデバイス/ドライバがそれ自体を作るか、それを測定する必要がないかどうかはわかりません。私はそれを取得すると私の答えを更新しますが、それはしばらくことができるので、私は非常に怠惰なよ...

[編集1]いくつかの幾何学的測定のセットアップとコードを作ったので、ここで
を変更新しく追加されましたより正確な結論:

if (raw==0x0000) z=0.0; 
else if (p.raw>=0x8000) p.z=4.0; 
else p.z=0.8+(float(p.raw-6576)*0.00012115165336374002280501710376283); 

rawデータが既に自身がそうrawドライバまたはオンラインショップにより補正余弦され、センサからの垂直距離を表します。 rawデータは直線から垂直までの距離です(少なくとも0.8-2。0mの範囲)、より正確な測定の後には、深さの範囲は<0.8 - 4.0> [m]である。以前の測定値が不正確でした。


raw = 0
raw >= 32768近すぎる値である遠すぎる/未知の値、あるいは何か他のもの(より多くの可能性がある)

+0

@shshadiポイントのリストとしてkinectデータを格納していますstruct pnt3d {float x、y、z; WORD raw; DWORD * rgb; } p;ここで、x、y、zはkinectに対するピクセルの位置、rawはRAW Depth-frameからの対応値、* rgbはRGBフレーム内の対応するピクセルへのポインタ... zはkinectからの垂直距離 – Spektre

関連する問題