2012-06-29 13 views
9

Estoy luchando con Kinect para Windows SDK para crear una aplicación para realizar (con C#).Calcular BPM a partir de los datos del sensor Kinect

Básicamente necesito rastrear una mano (normalmente la correcta) de un conductor y reconocer su velocidad en la dirección (BPM) para enviar este valor a otra aplicación a través de MIDI.

lo que empecé con la SkeletonFramesReadyEvent es la adición de la JointType.HandRight con una marca de tiempo DateTime.Now.Ticks a una historia List que se actualiza y elimina la primera entrada. Mantengo el historial de 60 fotogramas (2 segundos).

Calculo el BPM buscando la última baja y alta del Joint.Position.Y y luego calculo la diferencia y divido bpm = 60*ticksPerSecond/diff. Sin embargo, el resultado es incorrecto. ¿Hay otra manera de hacer esto? ¿Qué me estoy perdiendo?

Esto es lo que estoy utilizando hasta el momento:

public int DetectBPM(JointType type) 
{ 
    // we have not history yet 
    if (!HasHistory()) return 0; 

    // only calculate every second 
    var detectTime = DateTime.Now.Second; 
    if (_lastBPM != 0 && _lastBPMDectect == detectTime) return _lastBPM; 

    // search last high/low boundaries 
    var index = (int) type; 
    var list = History[index]; 
    var i = list.Count - 1; 

    var lastHigh = list[i]; 
    var lastLow = list[i]; 

    // shift to last peak first 
    while (i > 0 && list[i].Joint.Position.Y >= list[i - 1].Joint.Position.Y) i--; 

    // find last low 
    while (i >= 0 && lastLow.Joint.Position.Y >= list[i].Joint.Position.Y) lastLow = list[i--]; 

    // find last high 
    while (i >= 0 && lastHigh.Joint.Position.Y <= list[i].Joint.Position.Y) lastHigh = list[i--]; 

    var ticks = lastLow.Timestamp - lastHigh.Timestamp; 
    var elapsedTime = new TimeSpan(ticks); 

    var bpm = (int) (60000/elapsedTime.TotalMilliseconds); 

    Console.WriteLine("DEBUG: BPM = " + _lastBPM + ", elapsedMS: " + elapsedTime.TotalMilliseconds); 

    _lastBPMDectect = detectTime; 
    _lastBPM = bpm; 

    return _lastBPM; 
} 
+3

¿Qué resultado obtiene y qué resultado espera? – mlorbetske

+0

DEBUG: BPM = 512, ElapsedMS: 328 DEBUG: BPM = 182, ElapsedMS: -322 de depuración: BPM = -186, ElapsedMS: -337 de depuración: BPM = -178, ElapsedMS: 299 de depuración: BPM = 200 , transcurridosMS: 683 DEBUG: BPM = 87, transcurridoMS: -378 DEBUG: BPM = -158, transcurridoMS: 92 – fdomig

+1

Primero, probablemente debería estar usando 'Math.Abs ​​()' alrededor de la diferencia en el cálculo de 'ticks '(Eso explicará los valores negativos). De acuerdo con la documentación 'Timestamp' está en milisegundos, no en tics, así que use' TimeSpan.FromMilliseconds (ticks) 'en lugar de' new TimeSpan (ticks) 'también (probablemente renombre' ticks' también) – mlorbetske

Respuesta

2

me di cuenta de cómo hacerlo. Me faltaba un punto y calculé el BPM entre un pico y una posición baja de la mano que está mal. Tengo que calcular la diferencia de tiempo entre los dos últimos puntos bajos para obtener el resultado correcto.

La forma correcta de hacerlo es encontrar el punto de referencia que es el último pico. Desde allí, muévete al último punto bajo, este es el primer punto para calcular la diferencia. Pase al siguiente pico y baje al siguiente bajo nuevamente, que es el segundo punto para calcular la diferencia.

El principio se muestra en la siguiente figura

BPM calucaltion schema

y que resulta en un muy bien BPM calcula de este modo:

var ticks = Math.Abs(firstLow.Ticks - secondLow.Ticks); 
var elapsedTime = new TimeSpan(ticks); 

var bpm = (int) (60000/elapsedTime.TotalMilliseconds); 

Gracias por participar de todos modos.

+0

Si sus datos son ruidosos, la detección de un mínimo será sospechosa. Puede obtener mínimos locales solo una marca aparte. Esta es la razón por la que estoy diciendo que es probable que necesite suavizar sus datos (es posible que Kinect lo suavice, pero sin ver un gráfico de los datos es difícil de decir). También es bastante probable que con un ruido leve eso veras funcionará la mayor parte del tiempo, luego fallará. –

+0

Los datos ya están suavizados por una configuración de Kinect específica. – fdomig

Cuestiones relacionadas