fablabcb / CitRad-SensorUnit

Citizen Science Traffic Radar
GNU General Public License v3.0
7 stars 1 forks source link

smoothing #11

Open nFrechen opened 2 months ago

nFrechen commented 2 months ago

Ich muss hier nochmal was meine Gedanken sortieren:

In der Auswertung werden wir an mehreren Stellen eine Glättung der Messwerte brauchen. Ein laufendes Mittel können wir mit drei verschiedenen Komplexitätsstufen umsetzen:

1. vereinfachtes Mittel

runmean[i] = ((n-1) * runmean[i-1] + x[i])/n

Hier braucht man keinen Array mit Werten vorhalten, sondern nur das letzte Mittel runmean[i-1]. Der neue Messwert x[i] wird auf das letzte Mittel drauf gerechnet mit einer Gewichtung (z.B. 1) während das vorige Mittel mit Gewichtung 99 eingeht. Zum Schluss wird alles durch n=100 geteilt.

Diese Berechnung ist mathematisch nicht 100% korrekt, da der Einfluss früher Werte nie ganz aus dem Mittelwert verschwindet. Allerdings funktioniert es ausreichend gut. Nachteil ist aber, dass die Methode nicht symmetrisch arbeitet.

2. echtes laufendes Mittel aber ohne bzw. mit Rechteck-Kernel

Hier muss ein Array aus Werten mitgeführt werden (z.B. die letzen 100 Werte). Jeder neue Messwert wird dem Array hinzugefügt während der älteste Wert aus dem Array gelöscht wird. Anschließend wird der Mittelwert über das Array berechnet. Da die Werte im Array nicht gewichtet werden (ohne Kernel), kann das Array als Ringspeicher geführt werden. Es wird also immer der älteste Wert mit dem neuesten überschrieben ohne die anderen Werte anzufassen.

Alle Werte mit gleicher Wichtung in das gleitende Mittel eingehen zu lassen entspricht einem Rechteck-Kernel. Durch den Rechteck-Kernel kann das Ergebnis immer noch scharfe Sprünge aufweisen, auch wenn die Amplitude abgeschwächt wird. Der Rechteck-Kernel bewirkt auch dass Peaks zu Plateaus ohne definierte Spitze werden. Das ist ungünstig wenn man die Spitze finden möchte. Daher die dritte Methode:

3. laufendes Mittel mit Gauß-Kernel

Wenn man die Mittelwert-Berechnung noch mit einer Gewichtung machen möchte (z.B. ein Gauß-Kernel), ist die Reihenfolge der Werte im Array relevant. Hier könnte man trotzdem noch mit einem Ringspeicher arbeiten, wenn man den Kernel entsprechend verschiebt. Ansonsten muss man mit jedem neuen Eintrag die anderen Werte im Array in ihrer Position nach vorne schieben.

Der Gauß-Kernel bewirkt dass Werte am Rande des Glättungsfensters weniger Einfluss auf den Mittelwert haben. Dadurch bekommt alles einen smoothen Übergang. Der Gauß-Kernel erhält aber trotzdem größere Peaks die in den Daten enthalten sind.

thorondev commented 3 weeks ago

Wir haben uns jetzt auf ein Hann-Fenster verständigt und das ist implementiert. Damit kann das hier geschlossen werden