Also habe ich auf der Suche begonnen, die Anzahl der Schritte, die von einem Benutzer unter Verwendung der Daten, die ich von dem Beschleunigungsmesser erhalten genommen zu berechnen, dh x, y und z Koordinaten .Finding lokale Maximalpunkte eines gegebener Datensatz
Ich versuche, this Algorithmus zu implementieren, aber ich bin derzeit bei den lokalen Maxima Teil stecken. Matlab hat eine eingebaute findpeaks()
Methode, die alle lokalen Maxima eines gegebenen Datensatzes lokalisiert.
Unten ist mein Versuch, den Algorithmus zu implementieren, aber ich bekomme immer noch extrem enorme Ergebnisse daraus. Zuerst, mit einem Datensatz, der aus 20
tatsächlichen Schritten bestand, berechnete der Algorithmus, dass die Anzahl der Schritte 990+
war. Ich zwickte und debuggte und es gelang mir, diese Nummer auf 660
.. dann 110
schließlich zu einem aktuellen 45
zu bringen. Momentan stecke ich einfach fest und habe das Gefühl, dass meine findpeaks()
Methode falsch ist.
Dies ist meine Klasse Implementierung
import Foundation
class StepCounter
{
private var xAxes: [Double] = [Double]()
private var yAxes: [Double] = [Double]()
private var zAxes: [Double] = [Double]()
private var rmsValues: [Double] = [Double]()
init(graphPoints: GraphPoints)
{
xAxes = graphPoints.xAxes
yAxes = graphPoints.yAxes
zAxes = graphPoints.zAxes
rmsValues = graphPoints.rmsValues
}
func numberOfSteps()-> Int
{
var pointMagnitudes: [Double] = rmsValues
removeGravityEffectsFrom(&pointMagnitudes)
let minimumPeakHeight: Double = standardDeviationOf(pointMagnitudes)
let peaks = findPeaks(&pointMagnitudes)
var totalNumberOfSteps: Int = Int()
for thisPeak in peaks
{
if thisPeak > minimumPeakHeight
{
totalNumberOfSteps += 1
}
}
return totalNumberOfSteps
}
// TODO: dummy method for the time being. replaced with RMS values from controller itself
private func calculateMagnitude()-> [Double]
{
var pointMagnitudes: [Double] = [Double]()
for i in 0..<xAxes.count
{
let sumOfAxesSquare: Double = pow(xAxes[i], 2) + pow(yAxes[i], 2) + pow(zAxes[i], 2)
pointMagnitudes.append(sqrt(sumOfAxesSquare))
}
return pointMagnitudes
}
private func removeGravityEffectsFrom(inout magnitudesWithGravityEffect: [Double])
{
let mean: Double = calculateMeanOf(rmsValues)
for i in 0..<magnitudesWithGravityEffect.count
{
magnitudesWithGravityEffect[i] -= mean
}
}
// Reference: https://en.wikipedia.org/wiki/Standard_deviation
private func standardDeviationOf(magnitudes: [Double])-> Double
{
var sumOfElements: Double = Double()
var mutableMagnitudes: [Double] = magnitudes
// calculates the numerator of the equation
/* no need to do (mutableMagnitudes[i] = mutableMagnitudes[i] - mean)
* because it has already been done when the gravity effect was removed
* from the dataset
*/
for i in 0..<mutableMagnitudes.count
{
mutableMagnitudes[i] = pow(mutableMagnitudes[i], 2)
}
// sum the elements
for thisElement in mutableMagnitudes
{
sumOfElements += thisElement
}
let sampleVariance: Double = sumOfElements/Double(mutableMagnitudes.count)
return sqrt(sampleVariance)
}
// Reference: http://www.mathworks.com/help/signal/ref/findpeaks.html#examples
private func findPeaks(inout magnitudes: [Double])-> [Double]
{
var peaks: [Double] = [Double]()
// ignore the first element
peaks.append(max(magnitudes[1], magnitudes[2]))
for i in 2..<magnitudes.count
{
if i != magnitudes.count - 1
{
peaks.append(max(magnitudes[i], magnitudes[i - 1], magnitudes[i + 1]))
}
else
{
break
}
}
// TODO:Does this affect the number of steps? Are they clumsly lost or foolishly added?
peaks = Array(Set(peaks)) // removing duplicates.
return peaks
}
private func calculateMeanOf(magnitudes: [Double])-> Double
{
var sumOfElements: Double = Double()
for thisElement in magnitudes
{
sumOfElements += thisElement
}
return sumOfElements/Double(magnitudes.count)
}
} `
Mit diesem datasheet, die tatsächliche Anzahl der Schritte war genommen 20
aber ich bekomme immer wieder um 45
. Selbst wenn ich es mit einem Datensatz versucht, die von 30
tatsächlichen Schritten besteht, wurde die berechnete Anzahl Annäherung der 100s.
Jede mögliche Unterstützung/Beratung sehr geschätzt
PS sein wird: Datenblatt Format ist X, Y, Z , RMS (root mean square)
zu verwenden, weil ich versuche, die Matlab eingebaute in 'findpeaks()' Methode in iOS – eshirima
zu implementieren Warum machst du das in deiner "findPeaks" -Methode: 'peaks.append (max (Größen [i], Größen [i - 1], Größen [i + 1]))'? Sollten Sie nicht nur den Wert anhängen, wenn das Maximum "Magnituden [i]" ist? – jjatie
* "Sind sie plump verloren oder dummerweise hinzugefügt?" * Beide. Es ist durchaus möglich, dass zwei nicht verwandte Peaks den gleichen Wert haben. In diesem Fall werden Sie gültige Peaks wegwerfen. Auf der anderen Seite, wenn die Daten winzige Schwingungen haben, zählen Sie zu viele Spitzen. Zum Beispiel haben diese Daten eine Spitze bei 36, aber Sie werden 3 Spitzen zählen: 33,34,33,34,35,34,35,36,35,34,35,34,33,34,33. – user3386109