Estoy trabajando para implementar el reconocimiento de gestos en mi aplicación, usando Gestures Builder para crear una biblioteca de gestos. Me pregunto si tener múltiples variaciones de un gesto ayudará u obstaculizará el reconocimiento (o el rendimiento). Por ejemplo, quiero reconocer un gesto circular. Voy a tener al menos dos variaciones, una para un círculo en el sentido de las agujas del reloj y otra para el sentido contrario a las agujas del reloj, con el mismo significado semántico para que el usuario no tenga que pensar en ello. Sin embargo, me pregunto si sería deseable guardar varios gestos para cada dirección, por ejemplo, de varios radios, o con diferentes formas que estén "lo suficientemente cerca", como formas de huevo, elipses, etc., incluyendo diferentes rotaciones angulares. de cada. Alguien tiene experiencia con esto?¿Las variaciones de gestos en la biblioteca de gestos mejoran el reconocimiento?
Respuesta
OK, después de experimentar y leer la fuente de Android, he aprendido un poco ... En primer lugar, parece que no necesariamente tengo que preocuparme por crear diferentes gestos en mi biblioteca de gestos para cubrir diferentes ángulos rotaciones o direcciones (en sentido horario/antihorario) de mi gesto circular. De forma predeterminada, GestureStore utiliza un tipo de secuencia de SEQUENCE_SENSITIVE (lo que significa que el punto de inicio y los puntos finales son importantes), y un estilo de orientación de ORIENTATION_SENSITIVE (lo que significa que el ángulo de rotación importa). Sin embargo, estos valores predeterminados pueden anularse con 'setOrientationStyle (ORIENTATION_INVARIANT)' y setSequenceType (SEQUENCE_INVARIANT).
Además, para citar los comentarios en la fuente ... "cuando se usa SEQUENCE_SENSITIVE, actualmente solo se permiten gestos de un solo trazo" y "ORIENTATION_SENSITIVE y ORIENTATION_INVARIANT son solo para gestos SEQUENCE_SENSITIVE".
Curiosamente, ORIENTATION_SENSITIVE parece significar más que solo "la orientación importa". Su valor es 2, y los comentarios asociados con él y algunas constantes relacionadas (no documentadas) implican que puede solicitar diferentes niveles de sensibilidad.
// at most 2 directions can be recognized
public static final int ORIENTATION_SENSITIVE = 2;
// at most 4 directions can be recognized
static final int ORIENTATION_SENSITIVE_4 = 4;
// at most 8 directions can be recognized
static final int ORIENTATION_SENSITIVE_8 = 8;
Durante una llamada a GestureLibary.recognize(), el valor de tipo de orientación (1, 2, 4, u 8) se pasa a través de GestureUtils.minimumCosineDistance() como los numOrientations de parámetros, con lo cual se llevan a cabo algunos cálculos que están por encima de mi grado de pago (ver a continuación). Si alguien puede explicar esto, estoy interesado. Entiendo que está calculando la diferencia angular entre dos gestos, pero no entiendo cómo se usa el parámetro numOrientations. Mi expectativa es que si especifico un valor de 2, encuentre la distancia mínima entre el gesto A y dos variaciones del gesto B - una variación es "normal B", y la otra es B girada alrededor de 180 grados. Por lo tanto, esperaría que un valor de 8 considere 8 variaciones de B, separadas por 45 grados. Sin embargo, aunque no entiendo completamente los cálculos a continuación, no me parece que un valor numOrientations de 4 u 8 se use directamente en cualquier cálculo, aunque los valores superiores a 2 dan como resultado una ruta de código distinta. Quizás es por eso que esos otros valores no están documentados.
/**
* Calculates the "minimum" cosine distance between two instances.
*
* @param vector1
* @param vector2
* @param numOrientations the maximum number of orientation allowed
* @return the distance between the two instances (between 0 and Math.PI)
*/
static float minimumCosineDistance(float[] vector1, float[] vector2, int numOrientations) {
final int len = vector1.length;
float a = 0;
float b = 0;
for (int i = 0; i < len; i += 2) {
a += vector1[i] * vector2[i] + vector1[i + 1] * vector2[i + 1];
b += vector1[i] * vector2[i + 1] - vector1[i + 1] * vector2[i];
}
if (a != 0) {
final float tan = b/a;
final double angle = Math.atan(tan);
if (numOrientations > 2 && Math.abs(angle) >= Math.PI/numOrientations) {
return (float) Math.acos(a);
} else {
final double cosine = Math.cos(angle);
final double sine = cosine * tan;
return (float) Math.acos(a * cosine + b * sine);
}
} else {
return (float) Math.PI/2;
}
}
Basado en mi lectura, que la teoría de que el método más sencillo y lo mejor sería tener un gesto circular almacenado, estableciendo el tipo de secuencia y orientación a invariante. De esta forma, cualquier cosa circular debería coincidir bastante bien, independientemente de la dirección u orientación. Así que lo intenté, y devolvió puntajes altos (en el rango de aproximadamente 25 a 70) para prácticamente cualquier cosa remotamente parecida a un círculo. Sin embargo, también devolvió puntajes de 20 o más para gestos que ni siquiera estaban cerca de la circular (líneas horizontales, formas en V, etc.). Por lo tanto, no me sentía bien acerca de la separación entre lo que debería coincidir y lo que no debería ser. Lo que parece funcionar mejor es tener dos gestos almacenados, uno en cada dirección, y usar SEQUENCE_SENSITIVE junto con ORIENTATION_INVARIANT. Eso me da puntajes de 2.5 o más altos para cualquier cosa vagamente circular, pero puntajes por debajo de 1 (o ninguna coincidencia) para los gestos que no son circulares.
- 1. Reconocimiento de gestos Biblioteca de JavaScript
- 2. Reconocimiento de gestos en Android
- 3. ¿Cómo funciona el reconocimiento de gestos?
- 4. Reconocimiento de gestos de Kinect para Windows
- 5. Cómo hacer reconocimiento de gestos usando acelerómetros
- 6. Reconocimiento de gestos basado en acelerómetro
- 7. ¿Existe un marco Java puro para el reconocimiento de gestos?
- 8. iOS Reconocimiento de gestos utilizando acelerómetro (y giroscopio)
- 9. Reconocimiento de gestos OpenCV (para reproductor de medios)
- 10. Biblioteca de reconocimiento de gestos de video de código abierto en C#
- 11. Gestos y cadena de respuesta
- 12. Reconocer números usando gestos
- 13. Android Score de predicción de gestos Rango
- 14. Detección simple de gestos circulares
- 15. Análisis de gestos de Kinect
- 16. ¿Cómo limitar el reconocimiento de gestos de toque de iPhone dentro de una imagen circular?
- 17. ¿Estado actual del reconocimiento de gestos de la mano de OpenCV?
- 18. acelerómetro Smartphone gestos algoritmos
- 19. Problema de gestos: UISwipeGestureRecognizer + UISlider
- 20. Android: detección de gestos arrojadizos
- 21. Reconocedores de gestos y TableView
- 22. Detectar gestos táctiles simples
- 23. Manejo de reconocedores de gestos en iOS6
- 24. Perdiendo Reconocedores de Gestos en UIPopoverController
- 25. recarga Tableview y tocar gestos
- 26. Escuchar gestos en un widget de aplicación
- 27. Android, gestos sobre widgets clicables
- 28. Identificador de gestos de barrido adecuado iOS
- 29. Gestos multitáctiles en la aplicación web en el escritorio
- 30. Android TextView Enlace las interceptaciones con gestos de vista padre
Además, en mis experimentos, encontré que no era necesario almacenar gestos circulares de diferentes radios en la biblioteca de gestos para obtener coincidencias buenas con gestos dibujados de diferentes radios: los gestos circulares que dibujaba en la pantalla de diferentes radios coinciden igualmente bien (es decir, tenían puntajes comparables) con el mismo gesto almacenado. En cuanto al rendimiento, no he hecho los tiempos, pero basándome en un vistazo al código, sospecho que el rendimiento sería más o menos lineal con respecto a la cantidad de gestos en la biblioteca. –
he aquí un consejo: si llama a setSequenceType (GestureStore.SEQUENCE_INVARIANT), asegúrese de hacerlo antes de la llamada a load(), de lo contrario encontrará que no obtiene ninguna coincidencia. –
Gracias por esto. El uso de los niveles de sensibilidad de orientación adicionales solucionó los problemas que estaba teniendo con gestos con golpes similares pero con diferentes rotaciones. Los gestos como "más" y "igual" colisionaban antes de usar esta configuración. – Ehz