Windows应用程序窗体中的Kinect深度 [英] Kinect depth in windows application form

查看:71
本文介绍了Windows应用程序窗体中的Kinect深度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好



我是kinect的新手,我知道如何在WPF中做到这一点但我在Windows应用程序中捕获深度有问题。



我找到了一些代码如下:



Hello

I am new with kinect, I know how to do it in WPF but I have problem for capturing depth in windows application.

I found some code as below:

private void Kinect_DepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
{
   using (DepthImageFrame depthFrame = e.OpenDepthImageFrame())
   {
      if (depthFrame != null)
      {
         Bitmap DepthBitmap = new Bitmap(depthFrame.Width, depthFrame.Height,     PixelFormat.Format32bppRgb);
         if (_depthPixels.Length != depthFrame.PixelDataLength)
         {
            _depthPixels = new DepthImagePixel[depthFrame.PixelDataLength];
            _mappedDepthLocations = new ColorImagePoint[depthFrame.PixelDataLength];
         }
         
         //Copy the depth frame data onto the bitmap  
         var _pixelData = new short[depthFrame.PixelDataLength];
         depthFrame.CopyPixelDataTo(_pixelData);
         BitmapData bmapdata = DepthBitmap.LockBits(new Rectangle(0, 0, depthFrame.Width,
            depthFrame.Height), ImageLockMode.WriteOnly, DepthBitmap.PixelFormat);
         IntPtr ptr = bmapdata.Scan0;
         Marshal.Copy(_pixelData, 0, ptr, depthFrame.Width * depthFrame.Height);
         DepthBitmap.UnlockBits(bmapdata);                       
         pictureBox.Image = DepthBitmap;
      }              
      // sensor.CoordinateMapper.MapDepthFrameToColorFrame(DepthImageFormat.Resolution640x480Fps30,_depthPixels,ColorImageFormat.RgbResolution640x480Fps30,_mappedDepthLocations);
   }
}



但这并没有给我greyScale深度而且它是紫色的。有什么改进或帮助吗?



提前谢谢:)


but this is not giving me the greyScale depth and it's purple. Any improvement or help?

Thanks in advance :)

推荐答案

我找到了解决方案:



void Kinect_DepthFrameReady(object sender,DepthImageFrameReadyEventArgs e)

{

using(DepthImageFrame depthFrame = e.OpenDepthImageFrame() )

{

if(depthFrame!= null)

{

this.depthFrame32 = new byte [depthFrame .Width * depthFrame.Height * 4];

//将图像更新为新格式

this.depthPixelData = new short [depthFrame.PixelDataLength];

depthFrame.CopyPixelDataTo(this.depthPixelData);

byte [] convertedDepthBits = this.ConvertDepthFrame(this.depthPixelData,((KinectSensor)sender).DepthS tream);

位图bmap =新位图(depthFrame.Width,depthFrame.Height,PixelFormat.Format32bppRgb);

BitmapData bmapdata = bmap.LockBits(new Rectangle(0, 0,depthFrame.Width,depthFrame.Height),ImageLockMode.WriteOnly,bmap.PixelFormat);

IntPtr ptr = bmapdata.Scan0;

Marshal.Copy(convertedDepthBits,0 ,ptr,4 * depthFrame.PixelDataLength);

bmap.UnlockBits(bmapdata);

pictureBox2.Image = bmap;





}

}

}



私有字节[] ConvertDepthFrame(short [] depthFrame,DepthImageStream depthStream)

{

//贯穿深度框架,使两个阵列之间产生相关性

for(int i16 = 0,i32 = 0; i16< depthFrame.Length && i32< this.depthFrame32.Length; i16 ++,i32 + = 4)

{

// Console.WriteLine(i16 +,+ i32);

//我们这里不关心玩家的信息,所以我们只是通过改变价值来排除它。

int realDepth = depthFrame [i16]>> DepthImageFrame.PlayerIndexBitmaskWidth;

//我们留下13位深度信息,我们需要为每个像素转换成8位数。

//有数百个的方法来做到这一点。这只是最简单的一个。

//让我们创建一个名为Distance的字节变量。

//我们将为这个变量分配一个来自转换的数字13位。

字节距离= 0;

// XBox Kinects(默认)限制在800mm到4096mm之间。

int MinimumDistance = 800 ;

int MaximumDistance = 4096;

// XBox Kinects(默认)在接近800mm时不可靠,所以让我们把这些无用的测量结果拿出来。

//如果此像素的距离大于800mm,我们将以等效的灰色绘制它

if(realDepth> MinimumDistance)

{

//将realDepth转换为我们实际距离的0到255范围。

//仅使用以下距离分配之一

//白色=远/>
//黑色=关闭

//距离=(字节)(((realDepth - MinimumDistance)* 255 /(MaximumDistance-MinimumDistance)));

//白色=关闭

//黑色=远

距离=(字节)(255 - ((realDepth - MinimumDistance)* 255 /(MaximumDistance - MinimumDistance) ));

//使用距离绘制每一层(RG和当前像素。

//用相同的颜色绘制R,G和B会使它从黑色变为灰色

this.depthFrame32 [i32 + RedIndex] =(byte)(距离);

this.depthFrame32 [i32 + GreenIndex] =(byte) (距离);

this.depthFrame32 [i32 + BlueIndex] =(字节)(距离);

}

//如果我们是接近800毫米,只是把它漆成红色所以我们知道这个像素没有给出好的价值

el se $>
{

this.depthFrame32 [i32 + RedIndex] = 0;

this.depthFrame32 [i32 + GreenIndex] = 0;

this.depthFrame32 [i32 + BlueIndex] = 0;

}

}
I found the solution:

void Kinect_DepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
{
using (DepthImageFrame depthFrame = e.OpenDepthImageFrame())
{
if (depthFrame != null)
{
this.depthFrame32 = new byte[depthFrame.Width * depthFrame.Height * 4];
//Update the image to the new format
this.depthPixelData = new short[depthFrame.PixelDataLength];
depthFrame.CopyPixelDataTo(this.depthPixelData);
byte[] convertedDepthBits = this.ConvertDepthFrame(this.depthPixelData, ((KinectSensor)sender).DepthStream);
Bitmap bmap = new Bitmap(depthFrame.Width, depthFrame.Height, PixelFormat.Format32bppRgb);
BitmapData bmapdata = bmap.LockBits(new Rectangle(0, 0, depthFrame.Width, depthFrame.Height), ImageLockMode.WriteOnly, bmap.PixelFormat);
IntPtr ptr = bmapdata.Scan0;
Marshal.Copy(convertedDepthBits, 0, ptr, 4 * depthFrame.PixelDataLength);
bmap.UnlockBits(bmapdata);
pictureBox2.Image = bmap;


}
}
}

private byte[] ConvertDepthFrame(short[] depthFrame, DepthImageStream depthStream)
{
//Run through the depth frame making the correlation between the two arrays
for (int i16 = 0, i32 = 0; i16 < depthFrame.Length && i32 < this.depthFrame32.Length; i16++, i32 += 4)
{
// Console.WriteLine(i16 + "," + i32);
//We don’t care about player’s information here, so we are just going to rule it out by shifting the value.
int realDepth = depthFrame[i16] >> DepthImageFrame.PlayerIndexBitmaskWidth;
//We are left with 13 bits of depth information that we need to convert into an 8 bit number for each pixel.
//There are hundreds of ways to do this. This is just the simplest one.
//Lets create a byte variable called Distance.
//We will assign this variable a number that will come from the conversion of those 13 bits.
byte Distance = 0;
//XBox Kinects (default) are limited between 800mm and 4096mm.
int MinimumDistance = 800;
int MaximumDistance = 4096;
//XBox Kinects (default) are not reliable closer to 800mm, so let’s take those useless measurements out.
//If the distance on this pixel is bigger than 800mm, we will paint it in its equivalent gray
if (realDepth > MinimumDistance)
{
//Convert the realDepth into the 0 to 255 range for our actual distance.
//Use only one of the following Distance assignments
//White = Far
//Black = Close
//Distance = (byte)(((realDepth – MinimumDistance) * 255 / (MaximumDistance-MinimumDistance)));
//White = Close
//Black = Far
Distance = (byte)(255 - ((realDepth - MinimumDistance) * 255 / (MaximumDistance - MinimumDistance)));
//Use the distance to paint each layer (R G & of the current pixel.
//Painting R, G and B with the same color will make it go from black to gray
this.depthFrame32[i32 + RedIndex] = (byte)(Distance);
this.depthFrame32[i32 + GreenIndex] = (byte)(Distance);
this.depthFrame32[i32 + BlueIndex] = (byte)(Distance);
}
//If we are closer than 800mm, the just paint it red so we know this pixel is not giving a good value
else
{
this.depthFrame32[i32 + RedIndex] = 0;
this.depthFrame32[i32 + GreenIndex] = 0;
this.depthFrame32[i32 + BlueIndex] = 0;
}
}


这篇关于Windows应用程序窗体中的Kinect深度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆