Kinect for Windows SDKを使用して、(C#を使用して)実行するためのアプリケーションを作成するのに苦労しています。
基本的に、私は指揮者の片方の手(通常は正しい方)を追跡し、MIDIを介してこの値を別のアプリケーションに送信するために指揮の速度(BPM)を認識する必要があります。
私が始めたのは、更新されて最初のエントリを削除する履歴にタイムスタンプ付きのSkeletonFramesReadyEvent
を追加することです。60フレーム(2秒)の履歴を保持しています。JointType.HandRight
DateTime.Now.Ticks
List
の最後の安値と高値を検索してBPMを計算し、Joint.Position.Y
次に差を計算して除算しbpm = 60*ticksPerSecond/diff
ます。しかし、結果は間違っています。これを行う別の方法はありますか?私は何が欠けていますか?
これは私が今まで使っているものです:
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;
}