2012-06-29 13 views
9

मैं विंडोज एसडीके के लिए किनेक्ट के साथ स्ट्रिंगिंग कर रहा हूं ताकि (सी # के साथ) के लिए आवेदन तैयार किया जा सके।किनेक्ट सेंसर डेटा से बीपीएम की गणना करें

मूल रूप से मुझे एक कंडक्टर के एक हाथ (आमतौर पर सही एक) को ट्रैक करने की आवश्यकता होती है और MIDI के माध्यम से इस मान को किसी अन्य एप्लिकेशन को भेजने के लिए निर्देश (बीपीएम) में अपनी गति को पहचानने की आवश्यकता होती है।

मैं के साथ क्या करना शुरू कर दिया SkeletonFramesReadyEvent एक इतिहास List जो अद्यतन और पहली प्रविष्टि को हटा रहा है करने के लिए एक DateTime.Now.Ticks टाइमस्टैम्प के साथ JointType.HandRight जोड़ने है। मैं 60 फ्रेम (2 सेकंड) का इतिहास रखता हूं।

मैं 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; 
} 
+3

आपको क्या परिणाम मिल रहे हैं और आप किस नतीजे की उम्मीद कर रहे हैं? – mlorbetske

+0

डीबग: बीपीएम = 512, elapsedMS: 328 डीबग: बीपीएम = 182, elapsedMS: -322 डीबग: बीपीएम = -186, elapsedMS: -337 डीबग: बीपीएम = -178, elapsedMS: 299 डीबग: बीपीएम = 200 , elapsedMS: 683 DEBUG: बीपीएम = 87, elapsedMS: -378 DEBUG: बीपीएम = -158, elapsedMS: 92 – fdomig

+1

सबसे पहले, आपको शायद 'ticks की गणना में अंतर के आसपास 'Math.Abs ​​()' का उपयोग करना चाहिए '(जो नकारात्मक मानों के लिए खाता होगा)। प्रलेखन के अनुसार 'टाइमस्टैम्प' मिलीसेकंड में है, टिक नहीं है, इसलिए 'टाइम टाइमपैन (टिक्स) 'के बजाय' टाइमस्पेन। फ्रॉममिलिसकंड्स (टिक्स) 'का उपयोग करें (शायद' टिक्स 'का नाम बदलें) – mlorbetske

उत्तर

2

मैं पता लगा है कि यह कैसे करना है:

यह मैं अब तक क्या उपयोग कर रहा हूँ है। मैं एक बिंदु खो रहा था और बीपीएम की गणना एक चोटी और हाथ की एक कम स्थिति के बीच की है जो गलत है। सही परिणाम प्राप्त करने के लिए मुझे पिछले दो निम्न बिंदुओं के बीच समय अंतर को कम करना होगा।

जाने का सही तरीका है, अंतिम बिंदु है जो बताते हुए बिंदु ढूंढें। वहां से आखिरी कम तक पहुंचें, इससे अंतर की गणना करने वाला पहला बिंदु है। अगले चोटी पर कदम और अगले कम फिर से नीचे जाना जो अंतर की गणना करने के लिए दूसरा बिंदु है। वैसे भी भाग लेने के लिए

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

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

धन्यवाद:

सिद्धांत एक अच्छी तरह से बीपीएम इस तरह की गणना में

BPM calucaltion schema

नीचे और वह परिणाम चित्र में दिखाया गया है।

+0

यदि आपका डेटा शोर है कि मिनीमा का पता लगाना संदिग्ध होगा। आप स्थानीय मिनीमा को अच्छी तरह से एक तरफ अलग कर सकते हैं। यही कारण है कि मैं आपको बता रहा हूं कि _probably_ को आपके डेटा को सुचारू बनाने की आवश्यकता है, (इसकी संभावित किनेक्ट आपके लिए इसे चिकनाई कर रही है - लेकिन डेटा के ग्राफ को बिना कड़ी मेहनत के देखे।) यह भी काफी हल्का शोर के साथ कि आप ' वे ज्यादातर समय काम करेंगे - फिर असफल हो जाते हैं। –

+0

डेटा पहले से ही एक विशिष्ट किनेक्ट सेटिंग द्वारा चिकना हुआ है। – fdomig

संबंधित मुद्दे