Windows应用程序窗体中的Kinect深度 [英] Kinect depth in windows application form
本文介绍了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屋!
查看全文