Forum: Digitale Signalverarbeitung / DSP / Machine Learning Filterung eines gestörten Signals


von Toben A. (toben_a)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe vorliegendes (habe ich angehängt) Signal gemessen. Man sieht 
einen leicht nach oben wandernden Sinus mit ziemlich vielen 
unerwünschten Peaks nach oben und unten. Der wandernde Sinus ist mein 
Nutzsignal und hat eine ziemlich konstante Amplitude und Frequenz bzw. 
wie man sieht ändern sich beide nur sehr langsam. Das Störsignal jedoch 
ist wie ersichtlich meistens sehr hochfrequent mit großer amplitude.

Kann mir jemand hinweise geben mit was für einem Filter ich die 
unerwünschten Störsignale herausfiltern kann? Klar, man könnte einen 
Tiefpassfilter nehmen, ich finde bei diesem Fall nur interessant, dass 
Amplitude -und- Frequenz des Nutzsignales annähernd konstant sind. 
Machen sich dies komplexere Filter zu nutze? hier bräuchte ich Hinweise 
und Schlagworte, wonach ich suchen muss.

In Schritt 1 verwende ich Ipython bzw. Matlab um einen Filter zu 
implementieren und die Daten zu analysieren, hier kann ich also leicht 
komplexere filter realisieren. Für Schritt 2 verwende ich TwinCat, hier 
bin ich nach meinem Verständnis auf simple Mittelwertfilter o.ä. 
beschränkt. Hinweise hierzu sind ebenfalls willkommen

Ich danke vielmals

Toben

von A. F. (chefdesigner)


Lesenswert?

Ich könnte Dir eine SW anbieten, die das löst. Wäre in C und prozessiert 
Amplitude und Phase des Sinus mit einer Latenz von 2 Perioden. Ist nach 
etwa 4-6 Perioden stabil.

Permanent appliziert (also auf immer eine ausreichende Anzahl von 
Samples, damit auch wirklich 2 volle Perioden der Frequenz drin sind) 
ist das gegen jede Form von Störung iummun. Ist ein diskretes 
Filtermodell.

Den echten Sinus kann man daraus auch regenerieren, wenn man möchte. Er 
passt sich den Ergebnissen an und geht dynamisch mit Frequenzänderungen 
mit, wenn sie nicht zu sprunghaft sind.

So ca 5Hz/s sind kein Problem.

von Joe F. (easylife)


Lesenswert?

Zunächst würde ich es mit einem Medianfilter (Rangordnungsfilter) 
versuchen.
Tiefpass höherer Ordnung könnte auch sehr vielversprechend sein.

Ich hätte schon längst ein paar Filter ausprobiert und mir das Resultat 
angeguckt. Ist ja in der Regel eine Sache von ein paar wenigen Minuten.

Eine weitere Frage wäre natürlich, warum sieht das Signal überhaupt so 
aus?
Evtl. könnte man da bereits auf Hardwareebene die Störungen 
beseitigen...

: Bearbeitet durch User
von Toben A. (toben_a)


Lesenswert?

erstmal danke für euren Input.

@An Fi: ja das klingt doch interessant. An soetwas hatte ich auch schon 
gedacht: einen Sinus zB per Least-Squares über das echte signal legen 
und alles was zuweit abweicht rauslöschen bzw. der langsamen 
Signaländerung folgen. Könntest du mir dienen Code zukommenlassen? PN ? 
gibt es einen gesonderten Begriff für diesen Filter, mit dem ich 
weiterrecherchieren kann?

@Joe: wir tun schon unser möglichstes, die Störungen gar nicht erst auf 
das Signal kommen zu lassen, ganz unterdrücken lassen wird es sich aber 
nicht. Ich habe bereits die von dir angesprochenen Filter verwendet und 
es funktioniert soweit ok. einen Medianfilter könnte man auch mit 
TwinCat gut implementieren.

Wie gesagt interessiert mich vor allem, ob sich aus den meiner Meinung 
nach besonderen Eigenschaften des Nutzsignales noch Vorteile ziehen 
lassen bzw. ob es Ansätze gibt, diese zu nutzen.

von Joe F. (easylife)


Lesenswert?

Toben A. schrieb:
> Wie gesagt interessiert mich vor allem, ob sich aus den meiner Meinung
> nach besonderen Eigenschaften des Nutzsignales noch Vorteile ziehen
> lassen

Das kommt halt darauf an, wie diese Eigenschaften genau sind, und welche 
Daten/Eigenschaften du aus dem Nutzsignal herausziehen möchtest.

Wenn du sagst, Amplitude und Freqzenz ist immer annähernd gleich, worin 
besteht dann überhaupt die Information, die dieses Signal in sich trägt?

von Toben A. (toben_a)


Lesenswert?

man sieht das der Mittelwert des "Sinus" sich langsam nach oben bewegt. 
diese Änderung des Mittelwertes sowie die Amplitude mit der der Sinus 
schwingt sind meine Informationen. Wie man im Plot sieht ändert sich 
beides, langsam.

von Joe F. (easylife)


Angehängte Dateien:

Lesenswert?

Ich würde es mal klassisch aus einer Kombination aus Medianfilter und 
steilem Tiefpass/Bandpass versuchen.

Der Aussetzer, bzw. zeitlich längerer Offset des Messwertes am Ende 
deiner Messreihe könnte allerdings zum Problem werden (siehe roter 
Pfeil).
Lade doch mal die Rohdaten einer Messung hoch, dann könnte man sich das 
im Detail genauer angucken.

von Toben A. (toben_a)


Angehängte Dateien:

Lesenswert?

voila.

ich bekomme nun für folgendes sehr schöne Ergebnisse:

1)Signal fenstern und Mittelwert bilden
1.1)Wenn das delta zwischen Laser(i) und Laser(i+1) größer als 0.009 
ist, überschreibe Laser(i+1) mit diesem Mittelwert

Hier nutze ich ganz gezielt, dass Amplitude und Frequenz des 
Nutzsignales bekannt sind. Diese Lösung passt mir sehr gut, weil ich sie 
auch einfach mit TwinCat umsetzen kann.

Weitere (komplexere :) ) Vorschläge sind gern willkommen.

von Joe F. (easylife)


Lesenswert?

Au weia sieht das Signal schlimm aus.
Die Amplitude der Störungen übersteigt die Amplitude des Nutzsignals ja 
mindestens um Faktor 10, und die Periodendauer ist recht nahe an der des 
Nutzsignals (ca. Faktor 2).
Bin ehrlich gesagt etwas ratlos, wie man das anständig filtern könnte.
Bist du sicher, dass alle hardwareseitigen Möglichkeiten (Schirmung, 
symmetrisches Messignal, Pegelerhöhung (aktive Verstärkung am Sensor)) 
ausgeschöpft wurden?

von Raymund H. (raymund_h753)


Lesenswert?

Es sind also der DC und die Amplitude eines Sinus mit konstanter 
Frequenz gefragt.

Der DC kann wohl am besten über Median/Tiefpass extrahiert werden.

Dann könnte man eine PLL mit sehr kleiner Schleifenbandbreite auf die 
konstante Signalfrequenz locken und damit das Signal synchron IQ 
(Quadratur) demodulieren.

Auf DC des IQ liegt dann die Amplitude des Signals.

Tiefpass + Median Filterung, Absolutwertbildung des IQ gibt die 
Amplitude.

: Bearbeitet durch User
von Raymund H. (raymund_h753)


Angehängte Dateien:

Lesenswert?

Ich wollte etwas mit Jupyter Notebook und Scipy/Numpy arbeiten und habe 
mich an der Datenauswertung versucht:

An den Daten ist auffällig das sie auf 1/3 dezimiert werden können ohne 
Informationsverlust.

Die Frequenz zu Synchrondemodulation habe ich von Hand ermittelt, wenn 
diese leicht abweicht/driftet ist das bei hier ein vernachlässigbarer 
Amplitudenfehler.
1
%matplotlib nbagg
2
import numpy
3
import scipy.signal
4
import matplotlib.pyplot as plt
5
my_data = numpy.genfromtxt('/cygdrive/c/Users/Visitor/Downloads/out.csv', delimiter=',')
6
data=(my_data[:,3])[1:]
7
decimate=3
8
freqest=797/len(data)*decimate
9
10
ilog=[]
11
qlog=[]
12
13
# decimate data
14
data=data[numpy.arange(0,len(data)-1,decimate, dtype='int32')]
15
# differentiate and clip
16
data=numpy.clip(0.01,-0.01,numpy.diff(data))
17
18
#synchronous IQ demodulation
19
vcophase=0
20
for sample in data:
21
    ilog.append(scipy.cos(vcophase*2*scipy.pi)*sample)
22
    qlog.append(scipy.sin(vcophase*2*scipy.pi)*sample)
23
    vcophase+=freqest
24
25
# gaussian low pass
26
ilog=scipy.signal.convolve(ilog,scipy.signal.gaussian(51,51/scipy.pi/2))
27
qlog=scipy.signal.convolve(qlog,scipy.signal.gaussian(51,51/scipy.pi/2))
28
# median filter
29
ilog=scipy.signal.medfilt(ilog,333)
30
qlog=scipy.signal.medfilt(qlog,333)
31
#plt.plot (scipy.signal.convolve(ilog,scipy.ones(1)))
32
#plt.plot (scipy.signal.convolve(qlog,scipy.ones(1)))
33
#plot demodulated amplitude
34
plt.plot (scipy.sqrt(ilog**2+qlog**2))
35
plt.grid()
36
plt.show()

von Toben A. (toben_a)


Lesenswert?

Hi,

sorry, ich komme da nicht hinterher. Könntest du etwas klarer formuliert 
erläutern was dein Vorschlag ist?

Vielen Dank!

Beste Grüße und guten Rutsch :)

von Raymund H. (raymund_h753)


Angehängte Dateien:

Lesenswert?

Hier noch mal ein schönerer Python Script, mit Kommentaren.

Ich lasse den in Ipython Jupyter Notebook laufen:

https://ipython.org/notebook.html

Scheint brauchbar zu sein, bin von GNU Octave abgekommen.
1
%matplotlib nbagg
2
import numpy
3
import math
4
import scipy.signal as signal
5
import matplotlib.pyplot as plt
6
7
# read data
8
my_data = numpy.genfromtxt('/cygdrive/c/Users/Visitor/Downloads/out.csv', delimiter=',')
9
10
# extract data column
11
data=(my_data[:,3])[1:]
12
13
# decimate data, looks like 3x sample replication
14
decimate=3
15
data=data[numpy.arange(0,len(data)-1,decimate, dtype='int32')]
16
17
# differentiate and clip, plot data
18
data=numpy.clip(0.012,-0.012,numpy.diff(data))
19
plt.plot(data)
20
plt.grid()
21
plt.savefig("data.svg")
22
plt.show()
23
24
# plot fft of windowed data
25
plt.figure()
26
plt.grid()
27
plt.plot(20*numpy.log10(numpy.absolute(scipy.fft(data*signal.blackman(len(data)))))[0:int(len(data)/2)])
28
plt.savefig("freq.svg")
29
plt.show()
30
31
#synchronous IQ demodulation
32
periods=797 # frequency in periods in the samples looked up from fft plot
33
lastphase=periods*(len(data)-1)/len(data)*2*math.pi
34
35
ilog=scipy.cos(numpy.linspace(0,lastphase, len(data)))*data
36
qlog=scipy.sin(numpy.linspace(0,lastphase, len(data)))*data
37
38
# gaussian low pass of IQ
39
ilog=scipy.signal.convolve(ilog,signal.gaussian(51,51/scipy.pi/2))
40
qlog=scipy.signal.convolve(qlog,signal.gaussian(51,51/scipy.pi/2))
41
42
# median filter of IQ
43
ilog=scipy.signal.medfilt(ilog,333)
44
qlog=scipy.signal.medfilt(qlog,333)
45
46
#plot demodulated amplitude
47
plt.figure()
48
plt.plot (scipy.sqrt(ilog**2+qlog**2))
49
50
#plot DC
51
plt.plot(100*scipy.signal.medfilt(scipy.convolve(data,scipy.signal.gaussian(101,101/scipy.pi/2)),2001))
52
53
plt.grid()
54
plt.savefig("rslt.svg")
55
plt.show()

von Kritiker (Gast)


Lesenswert?

yeah, Python rulez!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.