Ich möchte per Programm die Bursts im oberen Signal zählen.
Zunächst habe ich die Signalwerte gleichgerichtet und dann einen
gleitenden Mittelwert über 128 Werte gebildet, nach dem Prinzip
1
accu += wert
2
accu -= accu / 128
3
wert2 = accu / 128
Das Ergebnis (wert2) ist das mittlere Signal.
Das untere Signal ist aus dem mittleren entstanden, indem der
Algorithmus mit 1/256 wiederholt wurde.
Das neue Signal ist zwar weniger zittrig, als das mittlere, aber der
erste, schwach ausgebildete Puls im Originalsignal hat gelitten.
Nun suche ich nach einer halbwegs robusten Methode, um aus einem der
abgeleiteten Signale die Anzahl Pulse im Original auszuzählen.
Gibt es was besseres, als durch zwei Y-Werte mit delta-Y > 1 eine Gerade
zu legen und Vorzeichenwechsel der Steigung von + nach - zu suchen?
Bin schon zu lange raus aus dem Geschäft aber ich versuchs mal.
Dein Signel verschleift, weil du kein echtes gleitendes Fenster hast
sondern die Historie immer mitschleppst.
Du brauchst einen Ringpuffer und musst die Summe der neuesten X Werte
nehmen.
Dazu musst du nicht bei jedem Step den gesamten Ringpuffer addieren, es
reicht wenn du den ältesten Wert von der gespeicherten Summe abziehst,
ihn dann mit dem neuen Wert überschreibst und den neuesten zur Summe
dazuaddierst. Dann die Summe wie gehabt durch die Anzahl der Elemente im
Ringpuffer.
Udo Schmitt schrieb:> Du brauchst einen Ringpuffer und musst die Summe der neuesten X Werte> nehmen.
Für die Geradenberechnug, wie oben kurz angerissen, ist das klar. Für
die Signalaufbereitung ist der Tiefpass schon der richtige Ansatz.
Uhu Uhuhu schrieb:> Für> die Signalaufbereitung ist der Tiefpass schon der richtige Ansatz.
Als reiner Tiefpass ja. Aber willst du das?
Beispiel du hast Werte (Fenster n = 4):
4 4 4 4 4 4 4 0 0 0 0 0 4 4 4 4 4
Ein gleitendes Fenster ist nach dem 4. '0' Wert auch bei 0 angelangt,
dein Tiefpass krebst noch irgendwo um die 1 rum, das gleiche bei den auf
0 folgenden Vierern, da ist das gleitende Fenster nach 4 Werten wieder
auf '4', dein Tiefpass irgendwo um die 3.
Du hast also im Endeffekt statt Werten zwischen 0 und 4 welche zwischen
1 und 3. Das ist ein großer Unterschied.
Probiers doch mal aus.
Udo Schmitt schrieb:> Als reiner Tiefpass ja. Aber willst du das?
Es scheint vorteilhaft zu sein, denn es macht aus dem Gezitter im oberen
Oszillogramm schon mal was deutlich ruhigeres, ohne die Bursts
wegzuglätten.
Die Frage ist, wie man es am besten anstellt, in einem der gefilterten
Signale die Bursts zu finden - das Original dürfte sehr viel
ungeeigneter dafür zu sein.
Jetzt habe ich eine Lösung, die zumindest für mein Testsignal ganz gut
funktioniert:
Im zweimal gefilterte Signal aus dem Eingangsposting wird durch zwei
Messwerte - hier mit 80 Samples Abstand - eine Gerade gelegt und die
Steigung berechnet.
Wenn das Signal > 800 ist und die Steigung von + nach - wechselt, wird
der Puls erkannt.
Uhu Uhuhu schrieb:> Es scheint vorteilhaft zu sein, denn es macht aus dem Gezitter im oberen> Oszillogramm schon mal was deutlich ruhigeres, ohne die Bursts> wegzuglätten.
Das macht das gleitende Mittelwertfilter auch. Aber gerade bei so
starken Änderungen von Signalen zu Pausen reagiert es schneller, das
heisst dein mittleres Signal wird ausgeprägter.
Aber wenn es so jetzt klappt ists ja auch gut.
Viel Erfolg noch
Udo
Uhu Uhuhu schrieb:> Im zweimal gefilterte Signal aus dem Eingangsposting wird durch zwei> Messwerte - hier mit 80 Samples Abstand - eine Gerade gelegt und die> Steigung berechnet.
wenn du Pech hast liegt dein Maximum aber genau zwischen zwei
"Sample-Punkten"
Beispiel:
Alle 3 ein Sample
p1 p2
2 2 3 4 5 6 4 3 4 5 6 6 7 6 5 3 2
| | | | | |
2 4 4 5 7 3
p1 wird hier übersehen.
ein Einfacher Kantenfilter würde es doch auch tun, oder nicht?
[-1 0 1] oder vielleicht [-1 -2 0 2 1]
Und deine ersten beiden Faltungen kannst du auch zu einer
zusammenfassen.
Uhu Uhuhu schrieb:> Udo Schmitt schrieb:>> Du brauchst einen Ringpuffer und musst die Summe der>> neuesten X Werte nehmen.>> Für die Geradenberechnug, wie oben kurz angerissen, ist> das klar. Für die Signalaufbereitung ist der Tiefpass> schon der richtige Ansatz.
Udos Vorschlag ist ein Tiefpass - allerdings ein FIR-Tiefpass
("nicht-rekursives Filter"), das einen besseren Phasengang hat
als Dein IIR-Filter ("rekursives Digitalfilter"), das i.d.R.
weniger Rechnerei erfordert.
Davon abgesehen: Der erste Puls ist bei Dir so klein, weil
beim Start der "Kondensator" in Deinem Tiefpass völlig
"entladen" ist. Das ist, wie Du durch genaues Hinsehen
prüfen kannst, zwischen den anderen Pulsen nicht der Fall.
Das kannst Du leicht korrigieren, indem Du nicht mit einem
"accu = 0" startest, sondern statt dessen mit einemm
"typischen Tal-Wert". Den kannst Du vor Beginn der Rechnung
schätzen; eleganter ist es natürlich, erstmal loszurechnen,
dabei einen Tal-Wert zu bestimmen, und anschließend den
Kopfblock mit ... was weiß ich ... 1000 Werten nochmal mit
dem korrigierten Startwert neu zu rechnen.
Vlad Tepesch schrieb:> wenn du Pech hast liegt dein Maximum aber genau> zwischen zwei "Sample-Punkten">> Beispiel:>> Alle 3 ein Sample
Nein... ich habe das so verstanden, dass er die Anstiegs-
berechnung gleitend macht, also
Wert[1] zu Wert[81]
Wert[2] zu Wert[82]
Wert[3] zu Wert[83]
... usw.
Vlad Tepesch schrieb:> wenn du Pech hast liegt dein Maximum aber genau zwischen zwei> "Sample-Punkten"
Die Daten stammen aus .wav-Files - was zwischen den dort aufgezeichneten
Samples los war, kann man sich zwar denken, wissen tut man es aber
nicht...
Der Ruf des Vogels, um den es geht, ist zwar den in Feinheiten sehr
variabel, aber im Großen und Ganzen doch nach einem ziemlich festen
Schema aufgebaut. Die Intervalle variieren von Ruf zu Ruf, aber in
gewissen, bekannten Grenzen. An diese Grenzen muss die Parametrisierung
des Algorithmus angepasst sein.
Es geht darum, die Anzahl von Pulsen im Ruf zu zählen - ob man da genau
das Maximum erwischt, oder nicht, ist so lange egal, wie man das alles
nicht so verschmiert, dass zwei Pulse nicht mehr auseinanderzuhalten
sind.
Zudem wird die ganze Chose für alle Werte sukzessive durchgerechnet.
Insofern verstehe ich deinen Einwand nicht.
> Und deine ersten beiden Faltungen kannst du auch zu einer> zusammenfassen.
Wie müsste das aussehen?
Uhu Uhuhu schrieb:> Insofern verstehe ich deinen Einwand nicht.
der Einwand bezog sich nicht auf das original Signal, sondern auf dein
künstlich (1/80) unterabgetastetes:
Uhu Uhuhu schrieb:> Im zweimal gefilterte Signal aus dem Eingangsposting wird durch zwei> Messwerte - hier mit 80 Samples Abstand - eine Gerade gelegt und die> Steigung berechnet.Uhu Uhuhu schrieb:>> Und deine ersten beiden Faltungen kannst du auch zu einer>> zusammenfassen.>> Wie müsste das aussehen?
Deine Gleitender Mittelwert ist ja nix als eine Faltung des Signals mit
einem Rechteck (ein Kernel mit allen Elementen 1/n).
du machst also (Stern ist der Faltunsoperator)
das ist das selbe wie:
oder
Da R1 und R2 konstant sind, kann man das vorher ausrechnen.
deine 2 Rechteckfaltungen ergeben also eine Trapezförmige
Den Kantenflter kann man dann auch noch da rein falten.
prinzipiell ist dein im Abstand von 80 den Anstieg berechnen ja das
gleiche.
Nur würde ich das für jedes Fenster machen (also überlappend - falten
ebend - und nicht nur alle 80 Schritte) und die Zwischenwerte mit
Berücksichtigen.
Statt deinem [-1 (78 x 0) 1] Kernel, würde ich eher sowas wie [(35 x
-1) 0 0 0 0 0 (35 x 1)] nehmen.
Die Länge des Gesamtkernels addiert sich allerdings aus den Kernels der
Einzelkernels. Bei Rechteckkernels ist es möglicherweise effizienter die
separat zu rechnen.
Wendet man diesen Kernal an, fällt dann eine Kurve raus, die die Extrema
als 0-Durchgänge beinhaltet (wie bei dir).
in Matlab/octave könnte das ganze so aussehen:
Vlad Tepesch schrieb:> Deine Gleitender Mittelwert [...]
Der Uhu hat KEINEN gleitenden Mittelwert. Das war Udos
Vorschlag, den er abgelehnt hat.
Der Uhu hat ein IIR-Filter .
Für ein FIR-Filter ist Dein Vorschlag meiner Meinung nach
wesentlich rechenaufwändiger als zwei gleitende Mittelwerte,
ohne einen Zusatznutzen zu bringen.
Vlad Tepesch schrieb:> Nur würde ich das für jedes Fenster machen (also überlappend - falten> ebend - und nicht nur alle 80 Schritte) und die Zwischenwerte mit> Berücksichtigen.
Das mach ich doch. Mein Programm bekommt die einzelnen Rufe nicht auf
dem Silbertablett serviert, sondern soll sie aus dem Datenstrom im .wav
rausfischen und rechnet das für jedes einzelne Sample.
Ich habe zwar im Moment nur eine Testdatei mit ca 20 Rufen, aber die
wird gut genug ausgewertet. Wie es dann mit "echten" Daten aussieht,
wird sich zeigen.
Possetitjel schrieb:> Der Uhu hat KEINEN gleitenden Mittelwert. Das war Udos> Vorschlag, den er abgelehnt hat.
Was heißt da abgelehnt?
Offensichtlich ist doch der "schlechtere" Phasengang meines rekursiven
Tiefpasses schlicht wurscht - wenn ich das Dingens zweimal
hintereinander anwende, kommt ein Signal heraus, das "glatt" genug ist,
damit der 80-er-Kantenfilter - der natürlich auf einem Zirkularpuffer
läuft - ein brauchbares Ergebnis liefert.
Wenn ein Filter, der die Funktionen in einem Schritt realisiert, weniger
Rechenaufwand erfordert, als die 3 Einzelschritte, dann ist er für die
Produktionsversion natürlich interessant.
Allerdings ist der Aufwand für beiden IIR-Filter winzig:
1
lpAccu += sample
2
lpAccu -= lpAccu / l1
3
4
lpAccu2 += lpAccu
5
lpAccu2 -= lpAccu2 / l2
Im Moment bastel ich mit ruby - Octave ist sicherlich besser geeignet
und schneller.
Possetitjel schrieb:> Für ein FIR-Filter ist Dein Vorschlag meiner Meinung nach> wesentlich rechenaufwändiger als zwei gleitende Mittelwerte,> ohne einen Zusatznutzen zu bringen.
Da gebe ich dir recht. mit den aktuell gewählten Parameter ja, wie ich
ja auch geschrieben habe.
Die Unterabtastung halte ich für fragwürdig.
Ich weiß natürlich nicht, wie viele Samples ein Burst in etwa hat. Wenn
der mindestens 300-400 Samples breit ist und nicht stört, dass die
Maxima nicht direkt getroffen werden, mag das kein Problem sein.
Vlad Tepesch schrieb:> Ich weiß natürlich nicht, wie viele Samples ein Burst in etwa hat.
Die gesamte Kette aus Bursts ist ca 150 ms. Das Signal ist mit 44,1 kHz
abgetastet.
> Die Unterabtastung halte ich für fragwürdig.
Eher nicht. Das ist eine Aufnahme von einer Vogelstimmen-CD.
Uhu Uhuhu schrieb:> Das mach ich doch
Ach so. Ich dachte, du schaust Dir nur vielfache von 80 an.
Dann ist es ja fast das gleiche, nur das ich die Werte dazwischen auch
berücksichtigen würde.
Uhu Uhuhu schrieb:> Mein Programm bekommt die einzelnen Rufe nicht auf dem Silbertablett> serviert, sondern soll sie aus dem Datenstrom im .wav rausfischen und> rechnet das für jedes einzelne Sample.
also was jetzt? Hast du das komplette File dada, oder trudeln einzelne
Samples in Echtzeit ein?
Im ersten Fall brauchst Du ja keinen Ringpuffer.
wenn du bei den rechteckigen filtern bleibst, kommst du vielleicht
besser, wenn du in einem Puffer dass integral des Signals mitführst.
Dann lassen sich beliebige gleitende Mittelwerte ohne weiteren Aufwand
berechnen.
Vlad Tepesch schrieb:> also was jetzt? Hast du das komplette File dada, oder trudeln einzelne> Samples in Echtzeit ein?
Es ist ein .wav-File, aber ich behandle ihn Pufferweise¹, womit er im
Prinzip wie ein Echtzeitsignal aussieht. Nur für Echtzeit ist das
Ruby-Programm definitiv zu langsam; das ist auch nicht gefragt.
Sinn der Übung ist die Extraktion individueller Rufermerkmale, z.B. die
Anzahl Bursts pro Ruf und das Timing dazu.
Ob man dabei Fehler macht, ist erst mal nicht so wichtig, so lange man
überall dieselben macht und keine störenden Artefakte dabei entstehen.
-----
¹) das bietet das verwendete .wav-Gem so an. Man könnte zwar den Puffer
so groß machen, dass die ganze Datei hinein passt, aber dann müsste man
sich um die Größe kümmern.
Uhu Uhuhu schrieb:> Was heißt da abgelehnt?
Na eben: Abgelehnt. Das hast Du doch.
> Offensichtlich ist doch der "schlechtere" Phasengang> meines rekursiven Tiefpasses schlicht wurscht [...]
Jein.
Du hast ursprünglich beklagt, dass ein Filter, das die kleinen
Schwankungen hinreichend unterdrückt, auch die Bursts selbst
so stark einebnet.
Das liegt einfach daran, dass Du extrem einfache Filter
verwendest und die "Stärke" des Filters nur über seine
Grenzfrequenz einstellen kannst.
Für das Ergebnis besser wäre aber, wenn Du die Ordnung des
Filters erhöhen würdest, weil Du dann die hochfrequenten
Anteile unterdrücken kannst, ohne die niederfrequenten
zu verfälschen.
Je höher die Filterordnung wird, desto stärker sind aber
die Auswirkungen eines schlechten Phasenganges auf das
Impulsverhalten. Hier sind FIR-Filter im Vorteil.
Bei Udos ersten Antworten war ja noch gar nicht klar, dass
Dein einfaches Verfahren für Dich funktioniert (sonst hättest
Du ja nicht zu fragen brauchen).
Possetitjel schrieb:> Du hast ursprünglich beklagt
Ich habe garnichts beklagt, sondern gefragt, ob es was besseres gibt als
das, was ich mir überlegt hatte.
Und wie die Debatte gezeigt hat, ist dieses Besser mit viel höherem
Rechenaufwand verbunden, dem hier offenbar kein Nutzen gegenüber steht.
Das ist auch eine Erkenntnis und eine, die nicht gerade beklagenswert
ist...
Jetzt streitet euch mal nicht.
Vlad hat mehr Ahnung von Filtern als ich je hatte :-)
Uhu Uhuhu schrieb:> Und wie die Debatte gezeigt hat, ist dieses Besser mit viel höherem> Rechenaufwand verbunden, dem hier offenbar kein Nutzen gegenüber steht.
Der Rechenaufwand des gleitenden Mittelwert ist nicht unbedingt höher.
Du musst halt nur ein dem Fenster entsprechend großen Ringpuffer haben
und die letzte berechnete Summe speichern. Dann reicht es bei jedem
neuen Wert von der alten Summe den ältesten Wert abzuziehen, den neuen
dazuzuaddieren, und den ältesten Wert mit dem neuen überschreiben.
Das sind 1 Leseoperation, eine Schreiboperation, eine Subtraktion und
eine Addition, sowie das Lesen und Überschreiben des Summenwertes.
Gut dann noch den Mittelwert aus der Summe, also eine Division, aber die
brauchst du bei deinem IIR Ansatz genauso.
Viel Erfolg