2011-07-27 11 views

答えて

8

これへの鍵はここにRuntime.NuiCamera.GetColorPixelCoordinatesFromDepthPixel "

は、ランタイムクラスの拡張メソッドでの呼び出しです。 WriteableBitmapオブジェクトを返します。新しいフレームが入ってくるように、このWriteableBitmapが自動的に更新されるので、それの使い方が本当に簡単です。ここ

kinect = new Runtime(); 
    kinect.Initialize(RuntimeOptions.UseColor | RuntimeOptions.UseSkeletalTracking | RuntimeOptions.UseDepthAndPlayerIndex); 
    kinect.DepthStream.Open(ImageStreamType.Depth, 2, ImageResolution.Resolution320x240, ImageType.DepthAndPlayerIndex); 
    kinect.VideoStream.Open(ImageStreamType.Video, 2, ImageResolution.Resolution640x480, ImageType.Color); 
    myImageControl.Source = kinect.CreateLivePlayerRenderer(); 

をし、コードそのものです。これを行うには

public static class RuntimeExtensions 
{ 
    public static WriteableBitmap CreateLivePlayerRenderer(this Runtime runtime) 
    { 
     if (runtime.DepthStream.Width == 0) 
     throw new InvalidOperationException("Either open the depth stream before calling this method or use the overload which takes in the resolution that the depth stream will later be opened with."); 
     return runtime.CreateLivePlayerRenderer(runtime.DepthStream.Width, runtime.DepthStream.Height); 
    } 
    public static WriteableBitmap CreateLivePlayerRenderer(this Runtime runtime, int depthWidth, int depthHeight) 
    { 
     PlanarImage depthImage = new PlanarImage(); 
     WriteableBitmap target = new WriteableBitmap(depthWidth, depthHeight, 96, 96, PixelFormats.Bgra32, null); 
     var depthRect = new System.Windows.Int32Rect(0, 0, depthWidth, depthHeight); 

     runtime.DepthFrameReady += (s, e) => 
      { 
       depthImage = e.ImageFrame.Image; 
       Debug.Assert(depthImage.Height == depthHeight && depthImage.Width == depthWidth); 
      }; 

     runtime.VideoFrameReady += (s, e) => 
      { 
       // don't do anything if we don't yet have a depth image 
       if (depthImage.Bits == null) return; 

       byte[] color = e.ImageFrame.Image.Bits; 

       byte[] output = new byte[depthWidth * depthHeight * 4]; 

       // loop over each pixel in the depth image 
       int outputIndex = 0; 
       for (int depthY = 0, depthIndex = 0; depthY < depthHeight; depthY++) 
       { 
        for (int depthX = 0; depthX < depthWidth; depthX++, depthIndex += 2) 
        { 
         // combine the 2 bytes of depth data representing this pixel 
         short depthValue = (short)(depthImage.Bits[depthIndex] | (depthImage.Bits[depthIndex + 1] << 8)); 

         // extract the id of a tracked player from the first bit of depth data for this pixel 
         int player = depthImage.Bits[depthIndex] & 7; 

         // find a pixel in the color image which matches this coordinate from the depth image 
         int colorX, colorY; 
         runtime.NuiCamera.GetColorPixelCoordinatesFromDepthPixel(
          e.ImageFrame.Resolution, 
          e.ImageFrame.ViewArea, 
          depthX, depthY, // depth coordinate 
          depthValue, // depth value 
          out colorX, out colorY); // color coordinate 

         // ensure that the calculated color location is within the bounds of the image 
         colorX = Math.Max(0, Math.Min(colorX, e.ImageFrame.Image.Width - 1)); 
         colorY = Math.Max(0, Math.Min(colorY, e.ImageFrame.Image.Height - 1)); 

         output[outputIndex++] = color[(4 * (colorX + (colorY * e.ImageFrame.Image.Width))) + 0]; 
         output[outputIndex++] = color[(4 * (colorX + (colorY * e.ImageFrame.Image.Width))) + 1]; 
         output[outputIndex++] = color[(4 * (colorX + (colorY * e.ImageFrame.Image.Width))) + 2]; 
         output[outputIndex++] = player > 0 ? (byte)255 : (byte)0; 
        } 
       } 
       target.WritePixels(depthRect, output, depthWidth * PixelFormats.Bgra32.BitsPerPixel/8, 0); 
      }; 
      return target; 
     } 
    } 
+0

その今私の方法死の黄色の画面を投げリンク悲しいことでオフセットを教えてくれます。しかし、あなたが言った方法を探しています –

+0

@ Mr-Bell - 私はこの記事をリンクの代わりに実際のコードで更新しました –

+0

これはうまくいくようです。 GetColorPixelCoordinatesFromDepthPixelを呼び出すのが私のフレームレートを殺しているようです。 –

2

一つの方法は、と仮定しています色および奥行き画像は、それらに類似の変化を有し、2つの画像(またはそれらのより小さなバージョン)を相互相関させる。

  • Pre-whiten the imageは、基本的なバリエーションを得ることができます。
  • Cross-correlate事前ホワイトニングされた画像またはそれらのより小さなバージョン。
  • 相互相関のピーク位置がXY
+0

Peter、それらは興味深い記事です。しかし、私はこの解決策がかなり経験的かもしれないと思います。私はそれがちょうどオフセットまたは何かのようなかもしれないと思う –

+0

:-) OK。私はおそらくそれを考えすぎている。 [私はちょうどこの種のものを読んでいます...](http://liu.diva-portal.org/smash/record.jsf?pid=diva2:420400) –

+1

工場では、各キネクトデバイスは較正されていますカメラ間のオフセットがデバイスのメモリに書き込まれます。トリックは、そのデータを利用するための適切なAPIを見つけることにあります。今は公式のkinect sdkはそのようなapiの1つしか提供しませんが、他のものは将来のリリースのために考慮されています –

関連する問題