Hola!
Hoy voy a mostrar como se puede utilizar el nuevo KinectSDK v2 para consumir y mostrar los datos del sensor de profundidad. Para este ejempo, trabajaremos en una aplicación WPF con una vista con una imagen, y la misma tiene asociada una propiedad ImageSensor que es la muestra el feed del sensor.
El siguiente ejemplo de código muestra la inicializacion de la Window. En la misma podemos ver que como en los ejemplos de Body y Camara, inicializamos un objeto READER para el feed del Depth, también inicializamos un Frame con la información del sensor de profundidad, y finalmente el bitmap que utilizaremos para mostrar la información.
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: }
- Como en los demás ejemplos, un par de validaciones para no trabajar con objetos nulos
- Validamos además que el tamaño de la información que nos retorna el sensor sea el mismo del frame que inicializamos al principio de la app
- Obtenemos los valores mínimos y máximos de profundidad (esto es muy cool!)
- En un ciclo ForEach recorremos los bytes y calculamos la intensidad de los mismos en base a las distancias mínimas y máximas
- Luego creamos el array RGB y finalmente creamos el Bitmap con toda esta información
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: }
Disclaimer:
“This is preliminary software and/or hardware and APIs are preliminary and subject to change“
Saludos @ Córdoba
El Bruno
Leave a comment