我正在尝试使用WPF应用程序显示Kinect传感器检测到的玩家数量。除了显示玩家数量之外,我还根据他们与Kinect的距离对像素进行了着色。最初的目标是测量像素的距离并显示距离,但我还想显示帧中有多少人。这是我现在使用的代码片段。
PS我从THIS
教程中借用了这个想法,我使用SDK 1.8和XBOX 360 Kinect(1414)
private void _sensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
{
using (DepthImageFrame depthFrame = e.OpenDepthImageFrame())
{
if (depthFrame==null)
{
return;
}
byte[] pixels = GenerateColoredBytes(depthFrame);
int stride = depthFrame.Width * 4;
image.Source = BitmapSource.Create(depthFrame.Width, depthFrame.Height,
96, 96, PixelFormats.Bgr32, null, pixels, stride);
}
}
private byte[] GenerateColoredBytes(DepthImageFrame depthFrame)
{
//get the raw data from kinect with the depth for every pixel
short[] rawDepthData = new short[depthFrame.PixelDataLength];
depthFrame.CopyPixelDataTo(rawDepthData);
/*
Use depthFrame to create the image to display on screen
depthFrame contains color information for all pixels in image
*/
//Height * Width *4 (Red, Green, Blue, Empty byte)
Byte[] pixels = new byte[depthFrame.Height * depthFrame.Width * 4];
//Hardcoded loactions for Blue, Green, Red (BGR) index positions
const int BlueIndex = 0;
const int GreenIndex = 1;
const int RedIndex = 2;
//Looping through all distances and picking a RGB colour based on distance
for (int depthIndex = 0, colorIndex = 0;
depthIndex < rawDepthData.Length &&
colorIndex<pixels.Length; depthIndex++, colorIndex+=4)
{
//Getting player
int player = rawDepthData[depthIndex] & DepthImageFrame.PlayerIndexBitmask;
//Getting depth value
int depth =rawDepthData[depthIndex]>>DepthImageFrame.PlayerIndexBitmaskWidth;
//.9M or 2.95'
if (depth <=900 )
{
//Close distance
pixels[colorIndex + BlueIndex] = 0;
pixels[colorIndex + GreenIndex] = 0;
pixels[colorIndex + RedIndex] = 255;
//textBox.Text = "Close Object";
}
//.9M - 2M OR 2.95' - 6.56'
else if (depth >900 && depth<2000)
{
//Bit further away
pixels[colorIndex + BlueIndex] = 255;
pixels[colorIndex + GreenIndex] = 0;
pixels[colorIndex + RedIndex] = 0;
}
else if (depth > 2000)
{
//Far away
pixels[colorIndex + BlueIndex] = 0;
pixels[colorIndex + GreenIndex] = 255;
pixels[colorIndex + RedIndex] = 0;
}
//Coloring all people in Gold
if (player > 0)
{
pixels[colorIndex + BlueIndex] = Colors.Gold.B;
pixels[colorIndex + GreenIndex] = Colors.Gold.G;
pixels[colorIndex + RedIndex] = Colors.Gold.R;
playersValue.Text = player.ToString();
}
}
return pixels;
}
目前的目标是 -
textBox
depth <=900 is red
。使用当前代码,我可以检测到玩家并用Gold为它们着色,但是一旦检测到玩家image
冻结,当玩家离开时,image
解冻并且正常行动。是因为循环吗?
欢迎提出想法,指导,推荐和批评。
谢谢!
截图:
答案 0 :(得分:0)
在表单代码中获取一个静态变量
然后使用您的视频帧例程设置此变量(不要在那里定义)。
然后在_sensor_AllFramesReady中快速更新文本框视图 随着新帧的到来在不同的线程中运行 我没有看到所有代码可能更新调用textbox.show
主循环看起来有点奇怪,但太复杂了。 基本上你用它来为图像中的每个像素着色。 由于kinect360具有320x240像素,因此可以生成76800的深度数组 您可能只为X和Y创建2个下一个循环循环,然后在此循环内部有一个变量增加以选择适当的深度值。