Hello!
Today I will show how you can use the new KinectSDK v2 to consume and display depth sensor data. For this example, we will work in a WPF application with a view with an image, and it has associated with an ImageSensor property which is the sample feed sensor.
The following code example shows the initialization of the Window. In it we can see that you as in the examples of Body and camera, we initialize a READER object for the feed of the Depth, also initialize a Frame with the depth sensor information, and finally the bitmap we use to display the information.
1: public ImageSource ImageSource
2: {
3: get
4: {
5: return _bitmap;
6: }
7: }
8:
9: public MainWindow()
10: {
11: _kinectSensor = KinectSensor.Default;
12:
13: if (_kinectSensor != null)
14: {
15: _kinectSensor.Open();
16:
17: var frameDescription = _kinectSensor.DepthFrameSource.FrameDescription;
18: _reader = _kinectSensor.DepthFrameSource.OpenReader();
19: _frameData = new ushort[frameDescription.Width * frameDescription.Height];
20: _pixels = new byte[frameDescription.Width * frameDescription.Height * _cbytesPerPixel];
21: _bitmap = new WriteableBitmap(frameDescription.Width, frameDescription.Height, 96.0, 96.0, PixelFormats.Bgr32, null);
22: StatusText = "Kinect Started";
23: }
24: else
25: {
26: StatusText = "error initializing the kinect sensor";
27: }
28:
29: DataContext = this;
30: InitializeComponent();
31: Loaded += MainWindow_Loaded;
32: Closing += MainWindow_Closing;
33: }
In the Window Load Event, we subscribe to the event FrameArrived of the reader. And now we see a little what we do when we process a frame of the DepthSensor.
- Like the other examples, a couple of validations for null objects
- We also validate that the size of the information us the sensor returns is the same frame that we initialized at the beginning of the app
- We get the minimum and maximum values of depth (this is very cool!)
- In a ForEach statement we go through bytes and calculate the intensity of them based on the minimum and maximum distances
- Then we create the array RGB and finally create the Bitmap with the information
1: void MainWindow_Loaded(object sender, RoutedEventArgs e)
2: {
3: if (_reader != null)
4: {
5: _reader.FrameArrived += DepthReaderFrameArrived;
6: }
7: }
8:
9: void DepthReaderFrameArrived(object sender, DepthFrameArrivedEventArgs e)
10: {
11: var frameReference = e.FrameReference;
12: try
13: {
14: var frame = frameReference.AcquireFrame();
15:
16: if (frame != null)
17: {
18: using (frame)
19: {
20: var frameDescription = frame.FrameDescription;
21: if (((frameDescription.Width*frameDescription.Height) != _frameData.Length) ||
22: (frameDescription.Width != _bitmap.PixelWidth) ||
23: (frameDescription.Height != _bitmap.PixelHeight)) return;
24: frame.CopyFrameDataToArray(_frameData);
25:
26: var minDepth = frame.DepthMinReliableDistance;
27: var maxDepth = frame.DepthMaxReliableDistance;
28: var colorPixelIndex = 0;
29: foreach (var depth in _frameData)
30: {
31: var intensity = (byte)(depth >= minDepth && depth <= maxDepth ? depth : 0);
32:
33: // Write out blue byte
34: _pixels[colorPixelIndex++] = intensity;
35: // Write out green byte
36: _pixels[colorPixelIndex++] = intensity;
37: // Write out red byte
38: _pixels[colorPixelIndex++] = intensity;
39: ++colorPixelIndex;
40: }
41:
42: _bitmap.WritePixels(
43: new Int32Rect(0, 0, frameDescription.Width, frameDescription.Height),
44: _pixels, frameDescription.Width * _cbytesPerPixel,
45: 0);
46: }
47: }
48: }
49: catch (Exception)
50: {
51: // ignore if the frame is no longer available
52: }
53: }
Personally I think that this way of working with the DepthSensor is much more SIMPLE than that it had in the V1 version.X in addition to be consistent with the rest of the data (body and Chamber) sources is enough to understand ![]()
Disclaimer:
“This is preliminary software and/or hardware and APIs are preliminary and subject to change“
Saludos @ Home
El Bruno
Leave a comment