Automatización de toma de fotografías con Kinect

Parte 2 Toma de fotografías con la detección de la mano derecha

Hola amigos, el día de hoy completaremos la publicación de automatización de fotografías con Kinect.

Resultados del tutorial

El resultado de este tutorial vamos a obtener que Kinect tome la fotografía al momento de que detecte la mano izquierda o derecha.

Pre Requisitos

Cómo pre requisito para este tutorial ocuparemos el código que utilizamos en el video tutorial anterior (descárgalo aquí)

Un poco de teoría:

Para este tutorial ocuparemos el Skeletal tracking:

  • Skeletal tracking significa seguimiento de esqueleto, este esta basado en un algoritmo que logra identificar partes del cuerpo, gestos y/o posturas de quienes están en el campo de visión del sensor.

Kinect es capaz de detectar dos tipos de Esqueletos, el default y el seated

  1. Default: Es el esqueleto predeterminado en el cual Kinect identifica las 20 partes del cuerpo fundamentales en las extremidades y en el rostro del cuerpo humano.
  2. Seated: Es el esqueleto que Kinect detecta si el usuario está sentado, solo cuenta con 10 puntos de identificación, se utiliza comúnmente cuando el usuario está cerca del sensor.

automatización1

Ahora bien, cada punto de los esqueletos recibe un nombre, nombre con el cuál podrás indicarle a Kinect que si es detectada tal parte tome la fotografía.

automatización2

Inicio de tutorial

Una vez que tengas ya todo listo lo primero que tenemos que hacer es agregar un arreglo de tipo esqueleto con una dimensión de 6 (el número 6 significa el máximo de personas que Kinect puede identificar)

automatización3

Enseguida debemos poner en el Window_Loaded una condición if para verificar si Kinect detecta a una persona o a un “esqueleto”, esta condición va justo debajo de this.sensor.ColorFrameReady += this.sensor_ColorFrameReady;

if (!this.sensor.SkeletonStream.IsEnabled)

{

}

A continuación viene lo divertido, para esto debemos saber qué tipo de esqueleto queremos que Kinect detecte, es decir ¿sentado o de pie?, en mi caso estará sentado, pero te enseñare como puedes cambiarlo según sean tus necesidades, es muy simple.

Dentro del if agrega la siguiente línea de código para activar el esqueleto.

this.sensor.SkeletonStream.Enable();

Sí deseas que Kinect solo detecte los 10 puntos superiores del cuerpo agrega.

this.sensor.SkeletonStream.TrackingMode = SkeletonTrackingMode.Seated;

Sí deseas que este de pie cambia Seated por Default.

this.sensor.SkeletonStream.TrackingMode = SkeletonTrackingMode.Default;

Por último agregamos el evento SkeletonFrameReady

this.sensor.SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(sensor_SkeletonFrameReady);

Al final obtendremos algo como esto:

automatización5

Método sensor_SkeletonFrameReady

Para crear el método de manera automática damos clic en el icono que aparece justo debajo del error sensor_SkeletonFrameReady  y damos clic en Generar método

automatización4

Este método es el que nos permitirá detectar el esqueleto y la mano para tomar la fotografía.

  1. Lo primero que tenemos que hacer es verificar que información nos está detectando Kinect con respecto al esqueleto y si realmente nos está detectando algo, para ello agregamos las siguientes líneas de código:

using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())

{

// Verifica que se encontró un esqueleto.

if (skeletonFrame == null)

{

return;

}

  1. A continuación vamos a copiar la información del frame a la colección, obtenemos la información del primer esqueleto y verificamos que este sea detectado por el sentor.

//copia la información del frame en la colección

skeletonFrame.CopySkeletonDataTo(totalSkeleton);

//Obtiene el primer esqueleto

Skeleton firstSkeleton = (from trackskeleton in totalSkeleton

where trackskeleton.TrackingState == SkeletonTrackingState.Tracked

select trackskeleton).FirstOrDefault();

//Aqui verificamos si el primer esqueleto regresa nulo, es decir no encontrado

if (firstSkeleton == null)

{

return;

}

  1. Ahora sigue lo divertido, debemos detectar la mano con la que si Kinect detecta automáticamente tome la foto, para ello agregamos una condición.

if (firstSkeleton.Joints[JointType.HandRight].TrackingState == JointTrackingState.Tracked)

{

}

  1. Dentro de la condición vamos a decirle que si es detectada la mano derecha que me tome la fotografía, esto solo agregando:

this.saveImage();

Nota: En mi caso e decidido pausar a Kinect después de que me tome la fotografía para tener un mejor control de las fotografías que este tomará.

Una vez agregado todo el código tendremos algo similar a esto.

if (firstSkeleton.Joints[JointType.HandRight].TrackingState == JointTrackingState.Tracked)

                {

                    this.saveImage();

                    this.sensor.Stop();

                 }

Y listo solo guardamos y corremos nuestro proyecto y hemos terminado.

Descarga el código completo de este tutorial aquí.

Presentación utilizada en el video descargala  aqui

Proximidad de Objetos

 

 

~ GLOSARIO ~

  • DepthStream:  Cada marco de la corriente de datos de profundidad se compone de píxeles que contienen la distancia (en milímetros) desde el plano de la cámara al objeto más cercano.
  • DepthImageFrame: Contiene un  bufferpor-marco para los datos de profundidad que se transmiten del sensor. También proporciona acceso a las dimensiones y formato de los datos, además de correspondencia entre el esqueleto y el color los espacios de coordenadas.
  • DepthRange: Determina la distancia del sensor para los que se reciben los valores de profundidad.

 

Tutorial Anterior

Glosario:GA

Usando la cámara del Kinect como cámara fotográfica.

Hola y bienvenidos a este primer tutorial de Kinect del 2014 está vez vamos a convertir nuestro Kinect en una cámara fotográfica.

  • Crea un nuevo proyecto en Visual Studio 2012 o 2010 de C# tipo Aplicación WPF con el nombre de tu preferencia.
  • Agrega la referencia Windows.Kinect.dll
  • En la ventana agrega los siguientes controles:

– Image: VideoControl

– Button Inicio: BtnBgn

– Button Guardar Imagen: BtnSave

– Button Detener: BtnStop

– Button Salir: BtnExit

*A todos los button agrega el evento Clic.

Ahora es tiempo de programar, nos vamos al MainWindows.xaml.cs

  • Agrega las siguientes librería:  Using Microsoft.Kinect;
  • Antes del MainWindows() agrega lo siguiente: private KinectSensor sensor;  private byte[] pixelData;

 

Una vez que tengamos todo listo es hora de iniciar con nuestro ejercicio.

  • Da clic en la ventana y agrega el evento Loaded y en el MainWindow agrega  this.Loaded += this.MainWindow_Loaded;
  • Y en el evento Loaded agregaremosKinectCam1
  1. Nos permitirá saber si hay uno o más sensores conectados a nuestro computador.
  2. Esta línea de código encuentra el objeto KinectSensor en la colección junto con su estatus, estatus que será asignado a la propiedad sensor.
  3. Iniciamos el Sensor
  4. Deshabilitamos el ColorStream [Obtiene la secuencia de colores para el Kinect.]
  5. Con esto, el control de su aplicación se traslada a la sensor_ColorFrameReady controlador de eventos donde el proceso marco de imagen tiene que ser hecho.
  6. Con este en caso de que no encuentre ningún sensor conectado al ordenador lanza un mensaje de notificación y cierra la ventana automáticamente.

Creación de Imagen

KinectCam2

  1. OpenColorImageFrame() que devuelve un marco de imagen del tipo ColorImageFrame. Ahora pudemos utilizar este mismo código exacto para trabajar marcos de imagen.
  2. Compruebaa si el marco entrante no es null.
  3. Obtiene los datos de los píxeles en la matriz/arreglo de bytes.
  4. Copia los datos de píxeles.
  5. Calcular la stride.
  6. Asignamos el mapa de bits en VideoControl image. Utilizando las dimensiones del image y utilizando el PixelFormats Bgr32 que es el formato del pixel de 32 bits por pixel.Cada canal de color (azul, verde y rojo) se le asignan 8 bits por píxel (BPP).

Inclusive nosotros podemos jugar con esta parte es decir si cambiamos de Bgr32 a Cmyk32 obtendríamos los siguientes resultados. Dentro de las opciones que te da PixelFormats puedes escoger la que más te guste y tomar las fotografías que quieras y divertirte un buen rato con tu aplicación.

Hasta aquí ya tenemos lo principal, si corremos nuestra aplicación en este momento obtendremos lo siguientes resultados.

KinectCam4

Eventos Clic

Antes de encender y/o apagar el dispositivo hay que cerciorarse de que esté conectado y que nos indique si es posible interactuar con el sensor y para ello agregamos en todos los eventos lo siguiente.

if (this.sensor != null && !this.sensor.IsRunning)

Encender/Iniciar el sensor.

this.sensor.Start();

Detener el sensor.

this.sensor.Stop();

Para salir de la ventana primero detenemos el sensor y después ahora si cerramos la ventana.

this.sensor.Stop();

this.Close();

Guardar imagen.

Para ser un poco más ordenados y que no se vea el código todo amontonado crearemos un método llamado SaveImage donde nos permitirá guardar las imágenes.

KinectCam3

  1. Como es un ejemplo simple le daremos un nombre estático a nuestra imagen a guardar en mi caso será: “Mi primer foto con Kinect.jpg” y de daré el formato de .jpg
  2. Para verificar que no marque error al guardar la segunda imagen y se me detenga la aplicación le estoy diciendo que si encuentra una imagen con el mismo nombre sobre escriba o elimine para sustituirla por la nueva.
  3. Aquí es donde guardamos la imagen, creamos un FileStream con el nombre de la imagen y le decimos que el contenido de la imagen es la que contiene nuestra image, en mi caso la guardare en formato .jpg y es por eso que utilizo JpegBitmapEncoder para definir un codificador que se usa para codificar imágenes a ese formato y finalmente la guardo.

Y ya terminamos ahora si podemos correr nuestra aplicación y al guardar una imagen nos dará el siguiente resultado.

*Las dimensiones de la imagen resultante son de 640 x 480.

*La imagen se guardará en la carpeta del paquete de la aplicación en la carpeta  Bin > Debug.

KinectCam5

 Vídeo Tutorial

https://www.youtube.com/watch?v=NCG-wm04mJ8&feature=youtu.be

~ Hasta la próxima 🙂 ~ 

Tip’s para desarrollar una aplicación para Kinect

Ten en cuenta que la interpretación de un usuario de un gesto podría ser completamente diferente al siguiente usuario.

La intención de predicción es un desafío considerable ya que no hay un medio físico para detectar la intención como una pantalla táctil o el ratón. Una vez que el usuario ha iniciado con el sistema que Kinect siempre está supervisando, buscando patrones que coinciden con un gesto.

Es importante distinguir las interacciones intencionales e ignorar otros movimientos. Por ejemplo: tocar la cara, gafas, beber.

Para aumentar la confianza, siempre ofrece una retroalimentación de como personas están utilizando el gesto.

Incluyen una fase de “atraer”, una fase de “comprometida” y una fase “completada”. También debe haber retroalimentación cuando un gesto ha sido cancelado o no.

Todo el mundo sabe lo que es una onda, pero la  forma  de una onda en la gente varía mucho. Algunas personas la onda la forman con su muñeca, algunos con su codo y algunos con su antebrazo. Algunos con la mano abierta moviendo de izquierda a derecha, mientras que algunas personas mueven  sus dedos juntos arriba y abajo. Simplemente pidiendo a un usuario una onda no garantiza el mismo movimiento.

Estas imágenes muestran dos movimientos diferentes que la mayoría de la gente reconocería como ondas.

Diseño para la confiabilidad

La confiabilidad debe ser tu prioridad número uno. Sin ella se sentirá tu aplicación deja de responder y difícil de usar y los usuarios se verán frustrados.

Mejores prácticas para el diseño de interacción Kinect – Usuario

Gesto y voz son dos entradas nuevas y emocionantes que Kinect pone a su disposición. Las secciones siguientes describen cómo trabajan, cómo mejor utilizarlas, desafíos para esperar y cómo retroalimentar con sus usuarios que entiendan.

Gesto

Gesto es un divertido método de interacción para explorar, pero también presenta retos difíciles que deben abordarse con el fin de hacer una interfaz natural, utilizable y adecuadas para todos los usuarios de su aplicación. Esta sección cubre algunos tipos básicos de gesto, cómo dar a los usuarios ver los comentarios acerca de lo que el Kinect y algunas consideraciones de diseño de interacción de gesto importante.

Tipos básicos de gesto

Gestos pueden tomar muchas formas, uso de la mano al destino algo en la pantalla, concretas, aprendido patrones de movimiento, para largos recorridos de movimiento continuo. A continuación se presentan algunos ejemplos de tipos de gestos comúnmente utilizados y las descripciones que le ayudará a entienden los gestos que se está diseñando.

Gestos estáticos, continuos y dinámicos

Gestos estáticos, también llamados poses o posturas, son para que el usuario mantiene una cierta posición todavía hasta que es reconocido. Desconfíe de elegir como gestos simbólicos de estáticas “thumbs up” que pueden llevar diferentes significados a través de culturas. Gestos dinámicos retroalimentar al usuario ya sea durante o después hacen un movimiento definido. Gestos continuas rastrear usuarios como se mueven delante del Kinect.

Gestos innatos y aprendidos

Gestos innatos son los el usuario sabe intuitivamente o eso tiene sentido basado en la comprensión de los usuarios del mundo.

Gestos aprendidos son los que se les debe enseñar al usuario con el fin de saber cómo utilizarlos para interactuar con el sistema.