[#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

One thought on “[#KINECTSDK] HowTo: Use Kinect as a green screen (II)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s