Detecting and displaying number of players detected using Kinect

206 views Asked by At

I'm trying to display number of players detected by Kinect sensor using an WPF application. In addition to displaying number of player I have also coloured the pixels based on their distance from the Kinect. Original goal was to measure the distance of the pixels and display the distance but I would also like to display how many people are in the frame. Here is the code snippets that I'm using now.

PS I have borrowed the idea from THIS tutorial and I'm using SDK 1.8 with 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;
    }

Current goal is to--

  • Detect total number of players detected and display them in a textBox
  • Colour them according to the distance logic i.e depth <=900 is red.

With current code I can detect player and color them in Gold but as soon as a player is detected the image freezes and when the player is out of the frame the image unfreezes and acts normal. Is it because of the loop? Ideas, guidance, recommendation and criticism all are welcome.

Thanks!

Screenshots:

enter image description here

enter image description here

1

There are 1 answers

0
Peter On

Get a static variable inside your form code

Then set this variable using your video frame routine (dont define it there).

And then update the textbox view, probaply in your _sensor_AllFramesReady As the arrival of new frames runs in a different thread I dont see all code maybe to update call textbox.show

the main loop looks a bit strange though, too complex. basicly you use it to color every pixel in your image. as the kinect360 has 320x240 pixels so that makes a depth array of size 76800 You might simply create 2 for next loops loops for X and Y and then inside this loop have a variable increase to pick the proper depth value.