所以我決定出發來計算我從加速度計獲取的使用數據的用戶拍攝的步數即X,ÿ和ž座標。尋找局部最大點設定
我想實現this算法,但我目前卡在當地的最大值部分。 Matlab有一個內置的findpeaks()
方法,它定位給定數據集的所有局部最大值。
下面是我嘗試實現算法,但我仍然從它得到非常巨大的結果。 首先,使用由實際步驟組成的數據集,該算法計算所採取步驟的數量爲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:數據表格式爲X,Ÿ,ž,RMS(均方根)
因爲我想實現Matlab的內置'findpeaks()'方法的iOS – eshirima
在你的'findPeaks'方法中,你爲什麼要這樣做:'peaks.append(max(magnitude [i],magnitude [i-1],magnitude [i + 1]))'?如果最大值是[幅度] [i]',你不應該只是追加值嗎? – jjatie
*「他們是笨拙地丟失還是愚蠢地加入?」*兩者。當然,兩個不相關的峯值可能具有相同的值,在這種情況下,您將丟棄有效的峯值。另一方面,如果數據有微小的振盪,你會計算太多的峯值。例如,這個數據在36點有一個峯值,但你會計算出3個峯值:33,34,33,34,35,34,35,36,35,34,35,34,33,34,33。 – user3386109