私はKinect for Windows SDKを使って(C#で)アプリケーションを作成するのに苦労しています。KinectセンサーデータからBPMを計算する
基本的には、指揮者の片手(通常は右手)をトラッキングし、MIDIを介してこの値を他のアプリケーションに送るために指揮(BPM)のスピードを認識する必要があります。私が始めた何
が更新され、最初のエントリを削除している歴史List
へDateTime.Now.Ticks
タイムスタンプとともにJointType.HandRight
を追加SkeletonFramesReadyEvent
です。私は60フレーム(2秒)の履歴を保持します。
Joint.Position.Y
の最後の低および高を検索してBPMを計算し、その差を計算して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;
}
どのような結果が得られていますか、どのような結果が期待されていますか? – mlorbetske
DEBUG:BPM = 512、elapsedMS:328 DEBUG:BPM = 182、elapsedMS:-322 DEBUG:BPM = -186、elapsedMS:-337 DEBUG:BPM = -178、elapsedMS:299 DEBUG:BPM = 200 、elapsedMS:683 DEBUG:BPM = 87、elapsedMS:-378 DEBUG:BPM = -158、elapsedMS:92 – fdomig
まず、 'ticks 'の計算の違いの周りに' Math.Abs() 'を使用しているはずです'(それは負の値を考慮に入れます)。 'Timestamp'はティックではなく、ミリ秒単位なので、' new TimeSpan(ticks) 'の代わりに' TimeSpan.FromMilliseconds(ticks) 'を使います(おそらく' ticks'の名前を変更します)。 – mlorbetske