[#KINECTSDK] HowTo: Use Kinect as a green screen (II)

image

Buenas,

esta es la 2da parte del post donde muestro como utilizar a la cámara de Kinect como una pantalla verde para plantar la imagen de nuestro cuerpo … pues donde queramos.

En el post anterior quedaba una parte importante de analizar que era el proceso de cada frame del skeleton, cámara y sensor de profundidad.

   1: void SensorAllFramesReady(object sender, AllFramesReadyEventArgs e)

   2: {

   3:     if (_sensor == null) return;

   4:     var hasDepth = false;

   5:     var hasColor = false;

   6:     hasDepth = GetDepthFrame(e);

   7:     hasColor = GetColorFrame(e);

   8:     ProcessDepthFrame(hasDepth);

   9:     ProcessColorFrame(hasColor);

  10: }

Como veremos en el siguiente código, las funciones GetDepthFrame y GetColorFrame validan que poseamos información correcta de la cámara y del sensor de profundidad, antes de dar como válido el proceso.

A continuación la función ProcessDepthFrame se encarga de realizar un mapeo de los puntos del array de la cámara y del array del sensor de profundidad que nos da como resultado un array donde en cada punto sabemos, la información de la cámara, la distancia de la misma al sensor, si está relacionada con un player y además podremos relacionarla también con un joint del skeleton.

Con toda esta información, en la 2da función ProcessColorFrame ya podremos pintar sobre el mapa de bits de la imagen de fondo, solo el cuerpo de cada player y dejar los otros bits en modo transparente.

   1: private void ProcessColorFrame(bool hasColor)

   2: {

   3:     if (!hasColor) return;

   4:     // Write the pixel data into our bitmap

   5:     _colorBitmap.WritePixels(new Int32Rect(0, 0, _colorBitmap.PixelWidth, _colorBitmap.PixelHeight), _colorPixels,

   6:                              _colorBitmap.PixelWidth*sizeof (int), 0);

   7:  

   8:     if (_playerOpacityMaskImage == null)

   9:     {

  10:         _playerOpacityMaskImage = new WriteableBitmap(_depthWidth, _depthHeight, 96, 96, PixelFormats.Bgra32, null);

  11:         imgMask.OpacityMask = new ImageBrush

  12:                                   {

  13:                                       ImageSource = _playerOpacityMaskImage

  14:                                   };

  15:     }

  16:  

  17:     _playerOpacityMaskImage.WritePixels(new Int32Rect(0, 0, _depthWidth, _depthHeight), _greenScreenPixelData,

  18:                                         _depthWidth*((_playerOpacityMaskImage.Format.BitsPerPixel + 7)/8), 0);

  19: }

  20:  

  21: private void ProcessDepthFrame(bool hasDepth)

  22: {

  23:     if (hasDepth)

  24:     {

  25:         _sensor.MapDepthFrameToColorFrame(DepthImageFormat.Resolution320x240Fps30, _depthPixels,

  26:                                           ColorImageFormat.RgbResolution640x480Fps30, _colorCoordinates);

  27:  

  28:         Array.Clear(_greenScreenPixelData, 0, _greenScreenPixelData.Length);

  29:  

  30:         for (var y = 0; y < _depthHeight; ++y)

  31:         {

  32:             for (var x = 0; x < _depthWidth; ++x)

  33:             {

  34:                 var depthIndex = x + (y*_depthWidth);

  35:                 var depthPixel = _depthPixels[depthIndex];

  36:                 var player = depthPixel & DepthImageFrame.PlayerIndexBitmask;

  37:                 if (player <= 0) continue;

  38:  

  39:                 var colorImagePoint = _colorCoordinates[depthIndex];

  40:                 var colorInDepthX = colorImagePoint.X/_colorToDepthDivisor;

  41:                 var colorInDepthY = colorImagePoint.Y/_colorToDepthDivisor;

  42:                 if (colorInDepthX <= 0 || colorInDepthX >= _depthWidth || colorInDepthY < 0 ||

  43:                     colorInDepthY >= _depthHeight) continue;

  44:                 var greenScreenIndex = colorInDepthX + (colorInDepthY*_depthWidth);

  45:                 _greenScreenPixelData[greenScreenIndex] = OpaquePixelValue;

  46:                 _greenScreenPixelData[greenScreenIndex - 1] = OpaquePixelValue;

  47:             }

  48:         }

  49:     }

  50: }

  51:  

  52: private bool GetColorFrame(AllFramesReadyEventArgs e)

  53: {

  54:     bool hasColor;

  55:     using (var colorFrame = e.OpenColorImageFrame())

  56:     {

  57:         if (colorFrame != null)

  58:         {

  59:             colorFrame.CopyPixelDataTo(_colorPixels);

  60:             hasColor = true;

  61:         }

  62:     }

  63:     return hasColor;

  64: }

  65:  

  66: private bool GetDepthFrame(AllFramesReadyEventArgs e)

  67: {

  68:     bool hasDepth;

  69:     using (var depthFrame = e.OpenDepthImageFrame())

  70:     {

  71:         if (depthFrame != null)

  72:         {

  73:             depthFrame.CopyPixelDataTo(_depthPixels);

  74:             hasDepth = true;

  75:         }

  76:     }

  77:     return hasDepth;

  78: }

Ahora si que lo han simplificado Risa

 

Saludos @ Home

El Bruno

image image image
About these ads

Un pensamiento en “[#KINECTSDK] HowTo: Use Kinect as a green screen (II)

  1. Pingback: [#KINECTSDK] HowTo: Use Kinect as a green screen (III) Source Code « El Bruno

Deja un comentario

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s