domingo, 11 de mayo de 2014

Solución a problema de sensibilidad Kinect xbox 360 en PC

En esta publicación hablare sobre la solución que se utilizó en el proyecto de piano con la Kinect que estoy realizando, solución sobre el problema de sensibilidad de la Kinect que he comentado en una publicación anterior.

Para explicar la solución a este problema explicare en que consiste una tecla del piano con la Kinect:
Una tecla es un espacio en el suelo que tiene las medidas de un cerámico normal de 30 x 30 cm. Que está ubicado aproximadamente a 2,25 mts.  de la Kinect con la Kinect a una altura de 1,30 mts. Aproximadamente.


Por lo cual al poner el pie sobre una orilla de la tecla de este piano el sonido se detenía y reproducía a una velocidad de 30 veces por segundo, lo cual distorsiona el sonido y da una experiencia muy mala sobre el piano, para solucionarlo se tomaron varias posibles soluciones, las cuales todas consistían en fórmulas matemáticas básicas y lineales, las cuales dan el mismo problema ya que seleccionan un espacio dependiendo del dato numérico de entrada, el cual se toma 30 veces en un segundo. Al analizar de mejor forma el problema después de fallar tantas veces (unas 5 soluciones se probaron fallando todas) se llegó a la solución de aplicar una herramienta de inteligencia artificial, la cual es llamada Lógica difusa.

Una definición simple de internet:

La lógica difusa (también llamada lógica borrosa o lógica heurística) se basa en lo relativo de lo observado como posición diferencial. Este tipo de lógica toma dos valores aleatorios, pero contextualizados y referidos entre sí. Así, por ejemplo, una persona que mida 2 metros es claramente una persona alta, si previamente se ha tomado el valor de persona baja y se ha establecido en 1 metro. Ambos valores están contextualizados a personas y referidos a una medida métrica lineal.


La lógica difusa imita el pensamiento de decisión de un humano por lo cual puedo hacer mención de que es parte de la inteligencia artificial, aunque implementarla es muy matemático ya que se basa en funciones de distintos planos que se cruzan para escoger la alternativa correcta o más correcta dependiendo del punto de vista que se quiere imitar. Para utilizar de buena forma la lógica difusa es necesario investigar y entender bien su forma teórica, por lo cual invito a investigar sobre ella y así podrá darle un toque más de realidad a su software, claro que todo depende del problema que se tenga.


Bueno ya llegado a la solución a implementar lo siguiente fue diseñar la solución como sigue:

Nota: para no alargar la publicación se omite la explicación de algunos conceptos relacionados a la lógica difusa y su implementación, esperando que un buen lector pueda investigar sobre el tema.

Nociones a representar:


·         El pie está dentro o fuera de la tecla en cierto grado.
·         Mientras más cercano esté el pie a la frontera de la tecla, menos grado de pertenencia tiene el pie de estar dentro de la tecla.
·         Si el pie está más cercano al centro de la tecla, mayor grado de pertenencia tiene de estar dentro de la tecla.


Diseño a implementar:

·         Se propusieron 2 variables lingüísticas de entrada:

o   Eje X.
o   Eje Z
·         El eje Y se omitió ya que no presenta problemas.
·         Para las variables lingüísticas X y Z se crearon 3 conjuntos difusos con sus respectivas funciones de pertenencia:

o   Fuera 1
o   Dentro
o   Fuera 2
·         Base de reglas para tomar las decisiones, reglas que se basan en la forma de pensar humana:

o   IF (X IS Fuera1) AND (Z IS Fuera1) THEN Exito IS NoToca
o   IF (X IS Fuera1) AND (Z IS Dentro) THEN Exito IS NoToca
o   IF (X IS Fuera1) AND (Z IS Fuera2) THEN Exito IS NoToca
o   IF (X IS Dentro) AND (Z IS Fuera1) THEN Exito IS NoToca
o   IF (X IS Dentro) AND (Z IS Dentro) THEN Exito IS Toca
o   IF (X IS Dentro) AND (Z IS Fuera2) THEN Exito IS NoToca
o   IF (X IS Fuera2) AND (Z IS Fuera1) THEN Exito IS NoToca
o   IF (X IS Fuera2) AND (Z IS Dentro) THEN Exito IS NoToca
o   IF (X IS Fuera2) AND (Z IS Fuera2) THEN Exito IS NoToca


  • Gráficos de las funciones realizadas:


Conjuntos difusos.jpeg
  • Una vez inferida la conclusión utilizando la base de conocimientos, se debe determinar la salida del sistema difuso a través de la defuzificación.
Diagrama3.jpeg


  • Se utilizará el método del centroide para defuzificar y determinar la salida del sistema.
  • Si la salida es mayor a 72.14% entonces la tecla sonará (en caso de que en el frame anterior el pie estuviese fuera)

Bueno aunque lo anterior puede ser complicado es simple una vez investigado el tema, pero la idea principal es que haremos que el software tome la decisión de tocar o no la tecla dependiendo de que si cree que esta 100% adentro de la tecla, representado en el código como 72,14%, y así la variación que se tiene del error queda fuera ya que no estaría 100% dentro el pie de la tecla puesto si el valor es menor a 72,14% quiere decir que se esta dentro del rango de error que se tiene, esto se puede afinar para que se tenga un 90% o 80% de certeza o el que uno prefiera, obviamente llegar a 50% seria malo ya que seria como tirar una moneda al aire.


Para finalizar cabe mencionar que la solución funciona mucho mejor que las posibles soluciones de matemáticas lineal que habíamos tomado, obviamente nada es perfecto por lo cual todavía quedan detalles que afinar para que la experiencia en el proyecto del piano con kinect sea 100% agradable.

Como recomendación para cualquier lector: 
dada mi experiencia en este proyecto y en proyectos anteriores, no se debe tener miedo a lo que se ve complicado en primera vista, puesto que implementar lo mas complicado se hace simple una vez se investiga y se entiende.

Problemas de sensibilidad de kinect xbox 360 en PC.

Como dice el título en esta publicación hablare sobre los problemas con la sensibilidad de la Kinect, esta será una entrada informativa no basada en investigación sino que en las pruebas realizadas mediante la detección de extremidades con el SDK1.7 de la Kinect para Windows 7.

Para realizar las pruebas se utilizó el código que se explico en una entrada anterior de este blog donde explico como reconocer las extremidades con la Kinect en C#.


Las pruebas que se realizaron fueron para los 3 ejes espaciales(x,y,z), estas se fueron visualizando en tiempo real con la interfaz que se muestra a continuación:



Las pruebas se realizaron a una distancia de 2,58 mts de la Kinect en línea recta, o sea, frente a la Kinect.
A continuación hare mención a los 3 ejes por separado, ya que cada uno tiene una variación distinta:

Eje x:


En el eje x la variación calculada es de 10 cm (+-5cm.). Por lo cual no se puede realizar una detección precisa de un cuadro de menos de 10 cm de ancho.

Eje y:


En el eje y el problema es menor, ya que el error calculado fue de 5 cm (+-2,5cm.) para lo cual levantar la pierna para realizar alguna acción en el caso de mi proyecto a realizar no es un problema (Proyecto: realizar un piano tocado con los pies utilizando la Kinect).

Eje z:


En este eje el problema es mayor, ya que el error es muy variable, aproximadamente el error calculado fue de 20 cm (+-10cm). El problema es que este error depende de la persona ya que cada uno puede tener pies de distinto tamaño de largo por lo cual el error varía mucho, este error fue tomado en una persona que calza 43 eur.

Conclusión:


Ya tomadas las medidas de error, podemos llegar a la conclusión de que la Kinect de Xbox 360 se puede utilizar para realizar proyectos que no requieran de una sensibilidad muy precisa, con estos datos se debe realizar un trabajo de depuración de ruido bastante exhaustivo (mirado desde el punto de vista de un único estudiante). Pero es muy posible si se da un tiempo para analizarlo.

Reproducir mp3 en C#

La reproducción de sonidos en c# está restringida ya que como este lenguaje pertenece a Microsoft este obviamente preferirá reproducir elementos multimedia en sus formatos tradicionales como WAV, por lo cual es necesario implementar librerías aparte para reproducir otros tipos de formatos de sonido, para lo cual no utilizaremos una librería externa a Microsoft sino que utilizaremos su mismo reproductor de mp3 y otros el cual es Windows media player.
A continuación mostrare el código que se necesita insertar para reproducir el sonido:

//llamada a la librería o dll de Windows media player
using WMPLib;

Para poder utilizar la librería antes hay que agregarla a las referencias, lo cual se puede hacer fácilmente haciendo clic derecho en las referencias, agregar la referencia buscándola en el buscador que posee o buscarla con examinar, esta dll esta en Windows/system32.
Ahora para cargar y reproducir un sonido en los formatos que reproduce wmp este sería el código:

  WindowsMediaPlayer wplayer = new WindowsMediaPlayer();
  wplayer.URL ="ubicación/sonido.mp3";
//para reproducir 
wplayer.controls.play();
//para detener la reproducción
  wplayer.controls.stop();


Y esto sería todo para agregar un sonido a nuestro programa, si se desea reproducir sonidos simultáneamente, con WMP no hay problema ya que reproduce los sonidos asíncronamente por lo cual solo sería crear varios objetos WindowsMediaPlayer y reproducirlos.