donc je me suis embarqué dans une quête pour calculer le nombre de mesures prises par un utilisateur en utilisant les données que je reçois de l'accéléromètre par exemple x, y et z coordonnées .Trouver un maximum de points locaux d'une donnée ensemble donné
J'essaie d'implémenter l'algorithme this mais je suis actuellement bloqué à la partie locale des maxima. Matlab a une méthode intégrée findpeaks()
qui localise tous les maxima locaux d'un ensemble de données donné. Ci-dessous est ma tentative de mettre en œuvre l'algorithme, mais je reçois encore des résultats extrêmement énormes de celui-ci. Dans un premier temps, en utilisant un ensemble de données constitué de 20
étapes réelles, l'algorithme a calculé que le nombre de pas effectués était 990+
. J'ai tordu et débogué et j'ai réussi à ramener ce nombre à environ 660
.. ensuite 110
finalement à un courant 45
. Actuellement, je suis juste coincé et j'ai le sentiment que ma méthode findpeaks()
est erronée.
Ceci est mon implémentation de la classe
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)
}
} `
Avec cette datasheet, le nombre réel des mesures prises a été 20
mais je continue à se déplacer 45
. Même quand je l'ai essayé avec un ensemble de données qui consiste en 30
étapes réelles, le nombre calculé approchait de la 100s.
Toute assistance/conseils seront grandement appréciés
PS: Format fiche technique X, Y, Z, RMS (root Mean square)
Parce que je suis en train de mettre en œuvre le Matlab intégrés 'findpeaks()' méthode dans iOS – eshirima
Dans votre méthode 'findPeaks', pourquoi faites-vous ceci:' peaks.append (max (magnitudes [i], grandeurs [i-1], grandeurs [i + 1])) '? Ne devriez-vous pas ajouter la valeur si le maximum est 'magnitudes [i]'? – jjatie
* "Sont-ils maladroitement perdus ou bêtement ajoutés?" * Les deux. Il est certainement possible que deux pics indépendants aient la même valeur, auquel cas vous rejetterez des pics valides. D'un autre côté, si les données ont de minuscules oscillations, vous compterez trop de pics. Par exemple, cette donnée a un pic à 36, mais vous comptez 3 pics: 33,34,33,34,35,34,35,36,35,34,35,34,33,34,33. – user3386109