Так что я начал на поиски, чтобы подсчитать количество шагов, предпринятых пользователем с помощью данных, я получаю от акселерометра т.е. х, у и Z координаты ,Нахождение локальных максимумов точек данного набора данных
Я пытаюсь реализовать алгоритм this, но в настоящее время я застрял в локальной части максимума. Matlab имеет встроенный метод findpeaks()
, который определяет все локальные максимумы заданного набора данных.
Ниже приведена моя попытка реализовать алгоритм, но я по-прежнему получаю от него чрезвычайно большие результаты. Сначала, используя набор данных, который состоял из действительных шагов 20
, алгоритм рассчитал, что количество выполненных шагов было 990+
. Я настраивал и отлаживал его, и мне удалось довести это число до 660
... затем 110
, наконец, до текущего 45
. В настоящее время я просто застрял и чувствую, что мой метод findpeaks()
ошибочен.
Это мой класс реализации
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)
}
} `
С этим datasheet, фактическое число шагов, предпринятых было 20
, но я получаю около 45
. Даже когда я попробовал его с набором данных, который состоит из 30
реальных шагов, рассчитанное число приближается к 100s.
Любая помощь/руководство будет весьма признателен
PS: формат Datasheet является X, Y, Z, RMS (среднеквадратичное)
Потому что я пытаюсь реализации этой MatLab встроенного в 'findpeaks()' метод в прошивкой – eshirima
В вашем методе 'findPeaks', почему вы это делаете:' peaks.append (max (величины [i], величины [i-1], величины [i + 1])) '? Не следует ли добавлять только значение, если max является «величинами [i]»? – jjatie
* «Они неуклюжие потеряны или глупо добавлены?» * Оба. Несомненно, что два несвязанных пика будут иметь одинаковое значение, и в этом случае вы будете выбрасывать действительные пики. С другой стороны, если данные имеют незначительные колебания, вы будете считать слишком много пиков. Например, эти данные имеют пик в 36, но вы будете считать 3 пика: 33,34,33,34,35,34,35,36,35,34,35,34,33,34,33. – user3386109