Automatische Detektion von Meteor Scatter Spektrogrammen

Wilm-52

Aktives Mitglied
In diesem Thread wurde angedacht, ob man Spektrogramme mit künstlicher Intelligenz (KI, AI) detektieren kann. Das ist eine interessante Sache, die sich aber nicht mal so einfach lösen lässt. Außerdem gibt es noch weitere Aufgaben zu programmieren, zB das Zählen der vorbei wandernden Signale.
Vielleicht kommt man für den Anfang ohne KI aus. Im Grunde sind es immer sehr ähnliche Gebilde. Sie sind prinzipiell einfarbig und lassen sich eventuell mit normalen Algorithmen von Störungen unterscheiden.

Für den Anfang habe ich nun etwas in Python3 und Opencv programmiert. Eine Einführung zu den beiden Themen gibt es im Link. Daraus habe ich auch Teile des Codes entnommen, aber natürlich auch aus Python und Opencv Dokumentationen.
Zunächst wird das Spektrogramm bzw werden die Spektrogramme in Schwarz-Weiß umgewandelt.
Wichtig ist zu wissen, dass die Farberkennung im HSV Farbraum erfolgt. Das ist eine Skala von 0 bis 180°, manchmal findet man auch 360°. Hier wurden 10° - 35° eingestellt, was orange-gelb entspricht. (Siehe zB Wikipedia HSV Farbraum.)
Im 2. Bild erkennt man auch schon das Hauptproblem: einmal werden aus einem Signal zwei, einmal verschmelzen zwei Signale. Das wird KI bestimmt besser können.
Vielleicht finden sich hier ja einige Leute, die daran mit oder weiter basteln möchten.
Viele Grüße,
Wilhelm

Code:
import numpy as np
import cv2
import time

def Mdetect():
    cap = cv2.VideoCapture(0)      # Jetson Nano /dev/video0
    cap.set(3,1280)                # HD
    cap.set(4,720)
    counter = 0
    if cap.isOpened():
        cv2.namedWindow("willi", cv2.WINDOW_AUTOSIZE)
        while cv2.getWindowProperty("willi", 0) >= 0:
            ret, streamin = cap.read()                                        # Einlesen der Frames in streamin, ret ist ein dummy
            streamout = streamin                                              # das sind Arrays
            hsv = cv2.cvtColor(streamin, cv2.COLOR_BGR2HSV)                   # RGB zu HSV
            maske = cv2.inRange(hsv, (10,100,100), (35,255,255))              # Farbauswahl, siehe Text
 
            contours, hierarchy = cv2.findContours(maske, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
            cv2.drawContours(streamout, contours, -1, (10,255,10), 2)         # alle mit Farbrahmen versehen
 
            cv2.imshow("Original + Kontur", streamout)
            cv2.imshow("SW-Maske", maske)
            keyCode = cv2.waitKey(30) & 0xFF

            counter += 1
            print("Sekunde: ", time.strftime("%S"),"Count:",counter)

            if keyCode == 27:    # Stop the program on the ESC key
                break

        cap.release()
        cv2.destroyAllWindows()
    else:
        print("Unable to open camera")

if __name__ == "__main__":
    Mdetect()
 

Anhänge

  • Screenshot from 2021-01-13 18-37-30.png
    Screenshot from 2021-01-13 18-37-30.png
    915,2 KB · Aufrufe: 251
  • Screenshot from 2021-01-13 18-50-20.png
    Screenshot from 2021-01-13 18-50-20.png
    1,2 MB · Aufrufe: 227
Opencv liefert von den detektierten Objekten einige nützliche Infos zurück.
Hier nutze ich die Flächen der Konturen und die Flächen der umschließenden Rechtecke zum Unterscheiden der Signale.

Drei Beispiele sind unten abgebildet:
11:49 Störung, Kontur = 8800 Pixel, Rechteck = 151000 Pixel
11:25 Signal, Kontur = 4400 Pixel, Rechteck = 7800 Pixel
9:38 Signal, Kontur = 7200 Pixel, Rechteck = 23800 Pixel

Beim Signal ist der Unterschied Rechteck / Kontur etwa Faktor 2 bis 3, während er bei dem Knackimpuls wesentlich größer ist. Hier ist der Unterschied 17-fach. Das ist natürlich von der verwendeten Darstellung abhängig.

Links im Screenshot (11_49) sind die Größen der Rechtecke und die Größen der Konturen als einfaches Korrelationsdiagramm dargestellt. Die steilere Linie / Ansammlung sind die Guten…

Nun wird eine Tracking Routine benötigt, die die Signale aufzeichnet, wenn sie über eine virtuelle Ziellinie laufen. Das ist aber nicht trivial.
Viele Grüße,
Wilhelm
 

Anhänge

  • 9_38UTC_16_1_2021.jpg
    9_38UTC_16_1_2021.jpg
    60,5 KB · Aufrufe: 199
  • 11_25UTC_16_1_2021.jpg
    11_25UTC_16_1_2021.jpg
    60,1 KB · Aufrufe: 188
  • 11_49UTC_16_1_2021.png
    11_49UTC_16_1_2021.png
    1,1 MB · Aufrufe: 222
Hallo Wilhelm,

danke für das Teilen Deiner ersten Eindrücke und das Code Snippet! Kurze Frage zum Verständnis: Werden die Daten in deine Pipeline gestreamt (also in Echtzeit verarbeitet) oder nimmst du erstmal alles "auf Verdacht" auf und lässt den Algorithmus dran drüber laufen?

Viele Grüße,
Thomas
 
Dankeschön für Eure Zustimmung!
Die Bilder werden in Echtzeit verarbeitet. Spektrum Lab baut das Bild kontinuierlich auf, etwa wie es früher ein x-t-Schreiber machte. Über ein HDMI-Kabel wird das Videosignal vom PC in den Jetson Nano (oder den Xavier NX) übertragen. Dort wird es 25 x in der Sekunde analysiert und mit den Informationen versehen.
Python und Opencv behandeln das Videobild wie ein Array. Das HD-Bild ist also ein Array der Größe 1280 x 720 Pixel x 3 Byte für die 3 Farben.
Im folgenden Beispiel werden im Videostream A in den Zellen i, j die Farben manipuliert und dann in Video B eingetragen.

Code:
for i in range (200,500):
    for j in range (200,600):
        (b,g,r) = A[i,j]
        b = r - g
        g = g - r
        B[i,j] =(b,g,r)
cv2.imshow("Neu", B)   # Ausgabe auf Display

Die Videostreams oder Arrays A und B kann man in Python wie normale Variablen behandeln. Die folgende Zeile addiert 2 Videostreams und legt sie in C ab:

C = A + B

Besser sucht man sich aber die passende Opencv Routine heraus, weil sie effektiver ist, zB:

C = cv2.add(A, B)

Viele Grüße,
Wilhelm
 
Hey Wilhelm,

hast Du hierfür schon ein GitHub Repository aufgesetzt? Ich kann echt empfehlen dies zu machen. Ich glaube einige Leute würden das gerne verfolgen. Ich bin gespannt wie es sich weiterentwickelt und hoffe, dass ich im Laufe des Jahres vom "puren Softwarehobby" auch mal wieder Richtung Hardware gehen kann!

Gruß,
Thomas
 
Thomas, du kannst das Programm gerne in dein Github "Mitmach" Projekt übernehmen. Daher habe ich es hier schon etwas ausführlicher dokumentiert. (Beigefügt war und ist der gesamte Code, kein Snippet.)

Gestern habe ich einen Störaustaster (Noiseblanker) programmiert, siehe Screenshot von 1:03 Uhr.
Zum Noiseblanker:
Gelegentlich treten Störungen / Knackimpulse auf. Die Fouriertransformation eines kurzen (Knack)-Impulses enthält theoretisch alle Frequenzen und verursacht hier ein breites Spektrogramm, dass sich über den ganzen Bildschirm erstreckt.

Sobald ein gelber Kreis, also die Markierung für ein erkanntes Signal, durch den rot umrandeten Bereich läuft, wird für 30 s die Registrierung der Daten unterbrochen. An den offenen gelben Kreisen erkennt man, dass der Noiseblanker aktiv ist. Nachteil ist, dass Signale, die sich zwischen Störung und blauer Registrierzone befinden, nicht erkannt werden. Das kommt aber sehr selten vor. Die Aufnahme ist ein Glücksfall für die Dokumentation.
Die Debug Info 0 30 unten im Terminal bedeutet, dass 0 Signale erkannt wurden und der Countdown Zähler auf 30 Sekunden steht. Würde innerhalb dieser Zeit eine weitere Störung auftreten, wird der Wert wieder auf 30 gesetzt.
Zur Aufnahme:
Im Spektrum Lab Screen im Screenshot von 10:10 Uhr erkennt man 2 Signale. Das obere wurde gerade beim passieren des blauen Bereichs registriert, das untere ist auf dem Weg dorthin. Da die Frames 25 mal in der Sekunde abgefragt werden, erhält man 8-12 (n) Treffer. Mache ich den Bereich zu schmal, werden kleine Signale übersehen. Diese n Treffer werden nun ganz simpel X über Y in das linke (Korrelations)-Diagramm eingetragen. Daher sind die Kreise etwas verwischt. Ob es sich bei den 3 obersten Punkten um 3 Signale handelt, lässt sich nicht mehr nachvollziehen.
Als Nächstes steht also die Registrierung an. Aus den n Treffern muss einer geloggt und dann müssen sie alle ausgewertet werden.
Das kann aber noch etwas dauern.
Viele Grüße,
Wilhelm

Code:
# (C) WiSi-Testpilot 2021
import numpy as np
import cv2
import time

bg = np.zeros((700, 1500, 3), np.uint8)             # Result Screen
bg = cv2.line(bg,(1,1),(1,700),(0,255,0),2)
bg = cv2.line(bg,(1,699),(1500,699),(0,255,0),2)    # Skala
for j in range (1,15):
    bg = cv2.line(bg,(j * 100,699),(j * 100,685),(0,255,0),2)  # X-Ticks
for j in range (1,8):
    bg = cv2.line(bg,(0, j * 100),(15, j * 100),(0,255,0),2)   # Y- Ticks

cap = cv2.VideoCapture(0)                           # /dev/video0, Spektrum Lab live Screen Input
cap.set(3,1280)                                     # HD
cap.set(4,720)
counter = 0    # Debug Info
gesamtMet = 0  # Debug Info
NB = 0         # Noiseblanker aus
altsek = 0

xo = 500   # blauer Bereich und Rahmen für Datenerfassung
xu = 950
yo = 150
yu = 154

xNo = 300   # roter Bereich und Rahmen für Noise Blanker
xNu = 500
yNo = 150
yNu = 160

RED = (0, 0, 255)
YELLOW = (0, 255, 255)
light_BLUE = (200, 100, 100)

while cap.isOpened():                                              # diese Schleife wird 25 x in der Sekunde durchlaufen
    ret, streamout = cap.read()                                    # Einlesen des Frame
    hsv = cv2.cvtColor(streamout, cv2.COLOR_BGR2HSV)               # RGB zu HSV
    maske = cv2.inRange(hsv, (10,100,100), (35,255,255))           # Farbauswahl, siehe älterer Post
#  cv2.imshow("SW-Maske", maske)                                  # plottet Maske

    contours, hierarchy = cv2.findContours(maske, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)  # findet alle Konturen im Bild
    cv2.drawContours(streamout, contours, -1, (0,255,255), 1)                               # plottet alle Konturen im Bild

    streamout = cv2.rectangle(streamout, (xo, yo), (xu, yu), light_BLUE, 1) # plottet blauen Rahmen für Datenerfassung
    streamout = cv2.rectangle(streamout, (xNo, yNo), (xNu, yNu), RED, 1)    # plottet roten Rahmen für Noise Blanker

    print('  Fläche der Konturen     Fläche des Rechtecke')
    for c in contours:                                              # Schleife über alle Konturen
        flaeche = cv2.contourArea(c)
        x,y,w,h = cv2.boundingRect(c)
        cv2.rectangle(streamout, (x, y), (x + w, y + h), light_BLUE, 2)  # blaues Rechteck
        # M = cv2.moments(c)                                        # Moment wird zZt nicht gebraucht
        rechteck = w * h
        center_coordinate = (int(x), int(y))                        # gelben Kreis links oben plotten
        if NB == 0:
            fuellung = -1                                           # gefüllter Kreis
        else:
            fuellung = 1                                            # leerer Kreis bei Noise Blanker
        streamout = cv2.circle(streamout, center_coordinate, 8, YELLOW, fuellung)   # gelben Kreis plotten

        if (x > xNo) and (x < xNu) and (y > yNo) and (y < yNu):     # Noise Blanker ein
            NB = 30
        if ( NB == 0) and (counter > 10 ) and (x > xo) and (x < xu) and (y > yo) and (y < yu): # Datenerfassung im blauen Bereich
            print ('  ',round(flaeche),'                    ', round(rechteck))
            streamout = cv2.circle(streamout, center_coordinate, 8, RED, -1)       # gelber Kreis wird im blauen Bereich rot
            center_coordinate_res = ( int(rechteck/20), 700 - int(flaeche/10))     # vorläufige (1/2) Skalierung der Werte
            bg = cv2.circle(bg, center_coordinate_res, 5, YELLOW, 2)               # gelber Kreis wird ausserhalb wieder gelb
            gesamtMet += 1    
    print(gesamtMet,'   ', NB)

    if (NB > 0):                           # Noise Blanker von 30 Sekunden auf 0 runterzählen
        sek =round(time.time())
        if (sek != altsek):
            altsek = sek
            NB -= 1      

    cv2.imshow('Korrelation Rechteck / Fläche', bg)
    cv2.imshow("Auslesebildschirm", streamout)

    counter += 1   # zum messen der Framerate
    print("  Sekunde: ", time.strftime("%S"),"Count:",counter)
    keyCode = cv2.waitKey(30) & 0xFF
    if keyCode == 27:
        cap.release()
        cv2.destroyAllWindows()
        break
 

Anhänge

  • Screenshot from 2021-01-18 01-03-10.png
    Screenshot from 2021-01-18 01-03-10.png
    1,2 MB · Aufrufe: 196
  • Screenshot from 2021-01-18 10-10-03.png
    Screenshot from 2021-01-18 10-10-03.png
    1,1 MB · Aufrufe: 207
Kleines Update: hier ist der erste Log.
Der Bereich ist ungeschickt gewählt. Nullen werden noch registriert und viele Werte schlagen oben an, aber im Prinzip funktioniert es.
Die blauen Kreise sind die Flächen der Rechtecke, die roten Kreise sind die Flächen der Konturen.
Viele Grüße,
Wilhelm
 

Anhänge

  • Screenshot from 2021-01-20 11-00-33.png
    Screenshot from 2021-01-20 11-00-33.png
    911 KB · Aufrufe: 210
Danke fürs lesen, Thomas.
Der Noiseblanker schaltet zur Zeit die Aufnahme für 30 s ab und das Signal unten wird 2 x gezählt. Das gefällt mir nicht. Daher stehen jetzt größere Änderungen an.
Außerdem möchte ich Opencv mit CUDA Unterstützung von Source compilieren, was schon mal schief gehen kann.
Die Flächen der Konturen sind heute logarithmisch aufgetragen (log y * 150).
Ein Wert von 10 ergibt also einen Y-Wert von 150, entsprechend 1.5 Teilstrichen.
100 ergibt 3 Teilstriche, 1000 ergibt 4.5 Teilstriche und 10000 ergibt 6 Teilstriche.
Viele Grüße,
Wilhelm
 

Anhänge

  • Screenshot from 2021-01-21 10-16-45.png
    Screenshot from 2021-01-21 10-16-45.png
    1.001,4 KB · Aufrufe: 185
Zuletzt bearbeitet:
Moinsns,

verstehe ich das richtig: die Routine schaut den fertigen Screenshot an und bewertet diesen, also gewissermaßen "posthum"?
LG Okke
 
Nein, Okke, es ist eine Echtzeit-Bildverarbeitung.
Spektrum-Lab scrollt kontinuierlich durch. Dieser Videostream wird dann über ein HDMI Kabel in einen anderen Rechner übertragen. Es ist im Prinzip so, als würde man den Spektrum-Lab Bildschirm mit einer Videokamera abfilmen. Dieses Video wird dann 25 mal in der Sekunde untersucht. Daher ist die Sache sehr rechenintensiv.
Viele Grüße,
Wilhelm
 
Zuletzt bearbeitet:
Moin,

ah ok. Heißt, du läßt SpecLab praktisch ganz aus der Beurteilung raus, richtig?
Ist dann die perspektivische Ansicht nicht eher ungünstig? Sie schattet ja vor allem die zeitliche Komponente stark ab und enthält der BV diese Information vor. Und je intensiver das Signal, desto länger der Schatten. Wäre es für die BV nicht viel günstiger, ihr den klassischen Wasserfall zu liefern, aus der sie alle Informationen "unzensiert" erhält?
Signalstärke (farblich oder per Grauwert dargestellt), Bandbreite und Signaldauer (flächig dargestellt), keine Abschattung.

Durch Hinzunahme der perspektivischen Ansicht, freut sich zwar unsere menschliche Wahrnehmung, es sieht schöner aus, aber einer BV geht damit Information verloren. Für BV würde ich auch die Farbe rauslassen und ausschließlich mit Grauwerten arbeiten, Farbe ist nur Convenience fürs Auge, für BV eher Overhead, der erstmal reduziert werden muß (spart gewaltig Rechenaufwand).

Den rechteckigen Kasten um ein "Gebirge", welches sich ja diagonal im Kasten befindet, würde ich auch nicht nehmen, der vergrößert m.E. nur die Fehlerbalken. Oder dient der nur als AOI, innerhalb derer dann zB BLOB-Analyse gemacht wird? Oder der Visualisierung für menschliche Betrachter?

LG Okke
 
Hallo Okke,
du hast vermutlich Recht, man könnte das auch in 2-D und SW auswerten. Aber in 3-D und Farbe macht es mehr Spaß und 3-D hat auch einen Vorteil, siehe weiter unten.
Ja Spektrum-Lab liefert nur den Videofeed.

Das Rechteck dient nur zur Info. Eine Ecke löst das Wegspeichern der Konturfläche aus. Wenn der gelbe Punkt oben über die blaue Doppelline läuft, wird ausgelöst.

Durch die perspektivische Darstellung geht nur dann Information verloren, wenn sich zwei Peaks abschatten. Das ist im Moment nicht der Fall. Wenn die Signale wie am 3. Januar reinkommen, muss ich eventuell die Vorschubgeschwindigkeit in SL erhöhen, damit sie getrennt werden.

Die perspektivische Darstellung ergibt mehr Fläche zum ausmessen als in 2-D, siehe Bild. Das Signal wäre in 2-D nur eine Linie. Die kurzen Signale bieten senkrecht betrachtet wenig Fläche. Es ist so, als ob man auf eine Messerklinge schaut: in Schneiderichtung sieht man sie kaum, dreht man die Klinge zB um 45°, sieht man schon 70% der Fläche. Der GRAVES Glitch ist natürlich ein Problem, weil er das Echo artifiziell verstärkt.

Es ist egal, ob man die Konturfläche in Farbe oder SW ausmisst. Die Schwelle der isoelektrischen Linie ist ja willkürlich. Zum Schluss kommen Flächen heraus, die die Größen der Events relativ zu einander wiedergeben.
Viele Grüße,
Wilhelm
 

Anhänge

  • 2_12_22_1_2021.jpg
    2_12_22_1_2021.jpg
    495,8 KB · Aufrufe: 153
Guten Tag,
Okke, nächste Nacht werde ich mal nach deinem Vorschlag (2-D Wasserfall) loggen, so dass wir es mit meinem Log von heute vergleichen können.

Heute um 8 Uhr, 9 Uhr Ortszeit, gab wieder drei Minuten lang Störungen, aber der Noiseblanker hat sie nicht durchgelassen.
Wenn die gelben Punkte durch den rot umrandeten Bereich laufen, wird der Noiseblanker aktiviert und die Signale werden nicht registriert. Allerdings ist die Totzeit wegen der horizontalen Lage des blauen Messfensters 30 Sekunden.
In Okkes Version kann die Totzeit kürzer sein.

Das Erfassen mache ich demnächst über einen Vector parallel unten zur Grundline. Das würde die Zeit für den Noiseblanker ebenfalls verkürzen. Der Rechenaufwand ist schon groß. Vorgestern habe ich Opencv compiliert, so dass die CUDA Kerne nun mitbenutzt werden.

Im Screenshot von heute Morgen sind wieder die Größe der Konturen über die Zeit aufgetragen. Die Farbe (hier Rot und Blau, f- Wert im Log) soll mal die Dopplerverschiebung anzeigen.

Ein Logbuch Auszug und der SL-Plot von 4 Uhr sind ebenfalls beigefügt.
Viele Grüße,
Wilhelm
 

Anhänge

  • Screenshot from 2021-01-23 09-26-33.png
    Screenshot from 2021-01-23 09-26-33.png
    955,7 KB · Aufrufe: 162
  • 4_15_Ortszeit.jpg
    4_15_Ortszeit.jpg
    494,4 KB · Aufrufe: 141
  • Auszug_aus_Logfile-23-1-2021.jpg
    Auszug_aus_Logfile-23-1-2021.jpg
    254 KB · Aufrufe: 149
Hallo Wilhelm,

besten Dank für deine Updates! Kurze Frage, damit man es quantitativ einschätzen kann: Wie hoch sind die Rechenzeitne mit CUDA? Welche Settings verwendest Du, etc.?

Beste Grüße,
Thomas
 
Dankeschön Euch beiden!
Okke, ich habe den 2D-Lauf einigermaßen dokumentiert:
wie erwartet sind die Signale in der 2-D Darstellung kleiner als in der 3-D Darstellung. Viele sind durch die Lappen gegangen. In der Draufsicht gehen doch Informationen verloren. Eberhard zB zeigt zusätzlich die Signal History. Daher finde ich die 3-D Darstellung ganz optimal. Man sieht die Frequenz, Amplitude und die Zeit. Mit der 3-D Auswertung erhält man auch eine schöne Gleichverteilung, siehe #13.

Störungen gab es nicht.
Der Screenshot zeigt ein Signal mit einer Blau-Shift von über 50 Hz. Daher ist der Punkt in dem Log-Screen blau. In Zukunft sollen sie kontinuierlich gefärbt werden.

Drei Spektrum-Lab Plots sind angehängt:
7:51 Ortszeit = 6_52_24_1_2021.jpg.
Blauverschiebung von fast 100 Hz.

3:11:45/47 Ortszeit = 2_12_24_1_2021.jpg.
3:40:39/40 Ortszeit = 2_41_24_1_2021.jpg
Bei den letzten beiden Signalen wurden Teilstücke einzeln gezählt. Die zukünftige Programmversion wird sie zu einer Fläche zusammenfassen. Es ist mit ein Grund für die Umstellung.
Viele Grüße,
Wilhelm
 

Anhänge

  • Screenshot from 2021-01-24 08-40-38.png
    Screenshot from 2021-01-24 08-40-38.png
    1,2 MB · Aufrufe: 162
  • Log_24_1_2021.jpg
    Log_24_1_2021.jpg
    232,8 KB · Aufrufe: 156
  • 2_12_24_1_2021.jpg
    2_12_24_1_2021.jpg
    785,9 KB · Aufrufe: 162
  • 2_41_24_1_2021.jpg
    2_41_24_1_2021.jpg
    793,9 KB · Aufrufe: 167
  • 6_52_24_1_2021.jpg
    6_52_24_1_2021.jpg
    792,5 KB · Aufrufe: 166
Thomas, in den beiden Jtop Bildern siehst du die Auslastung. Im Moment läuft das Programm auf dem Xavier NX, aber der Nano würde auch damit klar kommen. Die GPU mit 384 CUDA Kernen ist zwischen 20% und 40% ausgelastet.
Bei Bedarf kann man noch höher takten:
sudo nvpmodel -m 0 # on Xavier NX, use -m 2 instead (15W 6-core mode)
sudo jetson_clocks

Einen schönen Sonntag wünsche ich Euch,
viele Grüße,
Wilhelm
 

Anhänge

  • jtop1.jpg
    jtop1.jpg
    187,1 KB · Aufrufe: 156
  • jtop2.jpg
    jtop2.jpg
    135,9 KB · Aufrufe: 151
Zuletzt bearbeitet:
wie erwartet sind die Signale in der 2-D Darstellung kleiner als in der 3-D Darstellung.
Moinmoin,

ja klar, die perspektivische 2d-Projektion eines 3d-Objekts verbraucht ja mehr Pixel (=Fläche), je flacher der Winkel, je länger der Schattenwurf, liefert aber deswegen nicht mehr Info. Das, was hinter einem "Bergrücken" liegt, wird nicht erfaßt, weil es im Verborgenen liegt. Hinter dem Bergrücken kann alles mögliche passieren, aber man bekommt nichts davon mit. Das Betrachten der Bergflanke liefert keine zusätzliche Information, die nicht durch eine Draufsicht von oben bereits gegeben wäre (das Helligkeitsprofil ist ja proportional zum Höhenprofil).
Ok, ich sehe das berufsbedingt zwangsläufig durch die "BV-Brille", ich kann quasi nicht anders, sieh mir das bitte nach ? Deswegen bin ich auch von der "äugisch" ansprechenden perspektivischen Darstellung wieder zur orthogonal platten Darstellung zurück. Die Z-Achse wird ja eindeutig durch Helligkeit bzw Farbzuordnung abgebildet, und das ohne einen Teil der Zeitachse abzuschatten.
Hier in SL muß man sich freilich entscheiden zwischen 2 Ansichten, ent oder weder. Für beide gleichzeitig gibts m.W. keine Möglichkeit. Will man partout die reizvollere perspektivische Darstellung haben, muß man diesen Kompromiß eben eingehen. Bei einer zB "Autopilot"-Software, die das Straßenverkehrsgeschehen aus dem flachen Blickwinkel des Fahrers erfassen muß (weil sie nicht mal eben einen langen Galgen für eine Kamera von oben aufs Autodach montieren kann), gibt es die Option "von oben" schlicht nicht. Da ist man gezwungen, aus der perspektivischen Ansicht Erkenntnisse zu gewinnen.

Viele Grüße,
Okke
 
Okke, die schmalen Signale liefern für die Bildverarbeitung wenig Information bzw Pixel, siehe Beispiel: die Zanke könnte man gut von oben auswerten. Das Geodreieck liefert in der perspektivischen Darstellung mehr Informationen.

Die Abschattung der einzelnen Spektren ergibt erst die 3-D Struktur, s. Spektrogramm von gestern Abend. Es ist praktisch eine grafische Integration über die Zeit.

Abschattung von ganzen Peaks führt natürlich zu Fehlern. Fehlerfrei sind andere Zählverfahren aber auch nicht. KI wird da noch eine Verbesserung bringen. KI könnte zwei überlappende Peaks als zwei Einzelpeaks erkennen, weil das System mit Einzelpeaks trainiert wird. Auch das Unterscheiden von Störung und Signal wäre einfacher.
Viele Grüße,
Wilhelm
 

Anhänge

  • Zange&Geodreieck.jpg
    Zange&Geodreieck.jpg
    71 KB · Aufrufe: 144
  • 22_34UTC_24_1_2021.jpg
    22_34UTC_24_1_2021.jpg
    141,5 KB · Aufrufe: 151
  • Ausschnitt_22_34UTC_24_1_2021.jpg
    Ausschnitt_22_34UTC_24_1_2021.jpg
    365,3 KB · Aufrufe: 130
Zuletzt bearbeitet:
>>Das Geodreieck liefert in der perspektivischen Darstellung mehr Informationen.

Hallo Wilhelm,

diese Aussage kann ich nicht ganz nachvollziehen.
In der 2D-Darstellung steht doch die Helligkeit/Farbe der Pixel für die Intensität des Signals. Das könnte doch so ähnlich ausgewertet werden, wie bei der Fotometrierung von Sternen. Ähnlich wie Okke verstehe ich deshalb nicht, welche Zusatzinformation die 3D-Darstellung bei der Auswertung liefern soll. :unsure:

Viele Grüße,
Ronny
 
Hallo Ronny,
danke fürs mitlesen und für deine Anmerkungen.
Was ich damit und mit dem Beispiel der Messerklinge (weiter oben) erklären wollte ist, dass man beim senkrechten Betrachten eines Spektrums im ungünstigen Fall nur eine Pixelbreite zum Auswerten hat. Das untere Spektrogramm in #18 (22_34UTC_24_1_2021.jpg) würde in der Draufsicht nur eine Linie liefern, s. auch Beispiele in #15.
Die nicht senkrechte Ansicht liefert mehr „Fleisch“ für die Bildverarbeitung.

Anbei noch ein Bildchen. Es zeigt eine neue Funktion, die ich heute kennengelernt habe: cv2.minAreaRect(c).
Sie liefert das minimal umschließende Rechteck (Rot) und ist besonders gut für die Detektion breiter Störungen geeignet.
Viele Grüße,
Wilhelm
 

Anhänge

  • minAreaRect.jpg
    minAreaRect.jpg
    112,8 KB · Aufrufe: 147
Zuletzt bearbeitet:
Hallo Wilhelm,

das Geodreieck MUSS mindestens perspektivisch betrachtet werden, weil es, im Gegensatz zum 1 Pixel breiten (worst case) Signalverlauf, eine homogene Farbgebung hat. Aus der homogenen Farbgebung ist keine Konturinformation ablesbar. Aus der Färbung des Signals hingegen schon. Das Signal hat eine intensitäts-proportionale Farbgebung, eine Höheninformation, das Geodreieck nicht, wenn man nur Blick auf die Kante hat. Das Geodreieck mit Blick auf die Kante könnte nur ein einfarbiger, flacher Strich auf dem Hintergrund sein. Es gibt keine Höheninformation (qua Farbe bzw Grauwert).


Störungen erkennen: diese haben - betrachte ich die von dir im GRAVES-Fred erwähnten Störungen - nur sehr schwache Gradienten (in x), sind extrem breitbandig und bestehen im Wesentlichen aus Rauschen, und entbehren jeglicher Kontur.

Derlei filtert bei mir SpecLab bereits aus, weswegen ich sie auch nicht auf den Screenshots finde. Am WE passierte sowas, als ich live davor saß und sehen konnte, Screenshots gibts aber trotzdem nicht, weil durch solch breites Zeug Speclab eine Anhebung des Noisefloors sieht. So steigt zwar der absolute Pegel, aber das SNR nicht (hinreichend) und löst demzufolge auch keinen Trigger aus.

Was ich nach wie vor auf den GRAVES-Screenshots habe und definitiv keine Meteörs sind, ist son Zeug:
event_20210119_142247_402_SW_fake-event_beispiel_f.jpg
Die bisherige und "hierzuforum" gängige Vermutung für diese Signale sind atmosphärische Reflexionen. Ich hab da noch ne andere Vermutung, aber ich "kaue" noch dran, zumindest sind es definitiv keine Meteörs! (atmosphärische Reflexionen aber wahrscheinlich auch nicht).
Diese machen bei mir ca 75% aller Screenshots von GRAVES aus, also nur ein viertel sind echte Meteörs, der Rest ist so ein Schrapp. Bei denen sehe ich KI als ideal geeignet, um sie rauszuschmeißen. Die wären in der perspektivischen Ansicht auch verlustfrei darstellbar, weil sie so schmalbandig sind - und damit identifizierbar.

LG Okke
 
Bei denen sehe ich KI als ideal geeignet, um sie rauszuschmeißen. Die wären in der perspektivischen Ansicht auch verlustfrei darstellbar, weil sie so schmalbandig sind - und damit identifizierbar.
LG Okke
Okke, danke für deine Anmerkungen.
KI würde auch Signale trotz Abschattung / Überlagerung erkennen, siehe die Schafe im Link.
Du kannst ja mal einen 3-D Bild mit der Störung hier zeigen. Dann würde ich es durch mein Programm schicken.
--------------------------------
Für die Auswertung verwende ich weiterhin die (gekippten) Originalspektren, weil es für die Software einfacher ist. Die KI muss ja später mit Bildern bzw Formen trainiert werden.

Der Screenshot unten stammt von der neuen Programmversion.

Von den hereinkommenden Signalen C wird mit Hilfe des Kosinussatzes der Winkel alpha berechnet. Ist der Winkel klein genug und der Abstand zu A <= dem Abstand A-B, wird aufgezeichnet. Diese Routine ist noch nicht fertig. C wurde hier zwei mal aufgezeichnet. Es gibt auch Signale, die in zwei Peaks geteilt sind. Diese müssen dann noch zusammengerechnet werden.
Die Störungsunterdrückung funktioniert soweit. Wenn ein roter Kreis durch die Falle läuft, wird für ein paar Sekunden die Aufnahme abgeschaltet.
Viele Grüße,
Wilhelm
 

Anhänge

  • Screenshot from 2021-01-26 09-23-14.png
    Screenshot from 2021-01-26 09-23-14.png
    1,2 MB · Aufrufe: 167
Ein kleines Update:
Ganz ohne Nachbearbeitung geht es doch wohl nicht. Daher habe ich mir ein Format überlegt, dass leicht zu bearbeiten ist und in dem man die Signale gut wiederfindet.
Abgespeichert werden die Konturen (Fl), die Flächen der umschließenden Rechtecke (Re), die Dopplerverschiebung (f) und Zeiten des Noiseblanker.
Heute habe ich ein Programm geschrieben, das die Daten wieder darstellt. Die Y-Achse ist logarithmisch und muss noch beschriftet werden.
Die gelben Marken zeigen an, wann der Noiseblanker aktiv war.
Um zu zeigen, wie eine Störung aussieht, ist ein Beispiel von 1:06 UTC beigefügt. Nach der Störung wurden die beiden Signale registriert. Von der Störung wird nur die Zeit geloggt.
Um 7:30 gab es viele kleine Störungen. Dabei ist das Programm wegen einer Division durch Null abgestürzt. Das ist aber kein Problem. Der Fall (Exception) kann im Programm abgefangen werden.
Viele Grüße,
Wilhelm
 

Anhänge

  • GRAVES-28_1_2021_00-7UTC.jpg
    GRAVES-28_1_2021_00-7UTC.jpg
    127,6 KB · Aufrufe: 150
  • 1UTC_Daten.jpg
    1UTC_Daten.jpg
    304 KB · Aufrufe: 141
  • Screenshot from 2021-01-28 01-06-45.png
    Screenshot from 2021-01-28 01-06-45.png
    1 MB · Aufrufe: 154
  • Screenshot from 2021-01-28 01-09-25.png
    Screenshot from 2021-01-28 01-09-25.png
    1 MB · Aufrufe: 158
Hier sind Logs von heute und gestern. Damit sie den gleichen Maßstab haben, wurde der Plot von gestern neu gemacht. Die Punkte sind je nach Dopplershift eingefärbt. Heute hatte ich schon vor Mitternacht geloggt, aber der Tageswechsel ist noch nicht programmiert, so dass sie nicht gezeigt sind. Die Linien oberhalb der X-Achse zeigen an, wann der Störaustaster aktiv war.
Viele Grüße,
Wilhelm
 

Anhänge

  • GRAVES_28_1_2021_0-7UTC.jpg
    GRAVES_28_1_2021_0-7UTC.jpg
    134,6 KB · Aufrufe: 148
  • GRAVES_29_1_2021_0-9UTC.jpg
    GRAVES_29_1_2021_0-9UTC.jpg
    172,8 KB · Aufrufe: 149
Guten Morgen.
Es ist noch ein wichtiger Programmteil hinzugekommen, der schon lange auf der ToDo-Liste stand:
Manche Signale sind von 2 (oder mehreren) Konturen erfasst, s. Screenshot. Wenn diese nun über die Ziellinie laufen, wurde bisher nur die erste Kontur geloggt, natürlich immer die kleinere.
Läuft jetzt eine Kontur über die Ziellinie, wird noch mal über alle Konturen gescannt, ob sich weitere in der unmittelbaren Nähe der Ziellinie befinden. Diese werden dann aufsummiert. Die letzte Ziffer der entsprechenden Zeile im Log zeigt an, wie oft aufintegriert wurde, hier 2 mal.
Die Lücke in der Gesamtübersicht ist dadurch entstanden, dass Windows ein Update gemacht hat…
Einen schönen Sonntag wünsche ich Euch,
viele Grüße,
Wilhelm
 

Anhänge

  • Ausschnitt-Log_31_1_2021.jpg
    Ausschnitt-Log_31_1_2021.jpg
    469,3 KB · Aufrufe: 142
  • GRAVES_31_1_2021_0-9UTC.png
    GRAVES_31_1_2021_0-9UTC.png
    289,2 KB · Aufrufe: 143
  • Screenshot from 2021-01-31 08-56-43.png
    Screenshot from 2021-01-31 08-56-43.png
    1 MB · Aufrufe: 153
Zuletzt bearbeitet:
Inzwischen klappt das Loggen ganz gut. Die Bilder wurden mit den Rohdaten erstellt.
Die mit X bezeichneten Punkte muss man sich wegdenken. Es handelt sich um automatisch erkannte Störungen. Das große hintere Signal von 8:47 UTC wurde als zwei Signale erkannt. Dafür ist in Spalte eins die 1 vorgesehen. In Zukunft soll dort von Hand die Anzahl der zusammenzufassenden Peaks eingetragen werden.
Viele Grüße,
Wilhelm
 

Anhänge

  • GRAVES-1_2_2021_0-9UTC.jpg
    GRAVES-1_2_2021_0-9UTC.jpg
    163,8 KB · Aufrufe: 134
  • GRAVES-2_2_2021_1-9UTC.jpg
    GRAVES-2_2_2021_1-9UTC.jpg
    170,8 KB · Aufrufe: 138
  • GRAVES-2_2_2021_8_47UTC.jpg
    GRAVES-2_2_2021_8_47UTC.jpg
    273 KB · Aufrufe: 143
Guten Tag,
heute Nacht war die neue 5 Element Richtantenne dran, gestern wurde noch mit der Discone Rundstrahlantenne geloggt. (Die Farben der Punkte repräsentieren die Dopplershift und müssen immer noch geeicht werden.)
In GRAVES Richtung liegt eine 17.5er Kalksandsteinmauer und eine 11.5er Ziegelsteinwand. Kennt jemand Dämpfungswerte für 2m?
Es sind noch 2 Spektrogramme beigefügt, einmal der „Schneeball“ von gestern und das stärkste Signal von heute. Man sieht auch am Grundpegel einen Unterschied zwischen den beiden Antennen. Sogenannte Raucher und Blechbüchsen sind nun auch deutlicher zu sehen.
Auf dem Dachboden liegt auch noch eine 6m HB9CV. In den nächsten Tagen werde ich dann mal wieder andere Frequenzen testen.
Viele Grüße,
Wilhelm
 

Anhänge

  • GRAVES-3_2_2021_1-8UTC.jpg
    GRAVES-3_2_2021_1-8UTC.jpg
    138 KB · Aufrufe: 146
  • GRAVES-4_2_2021_1-8UTC.jpg
    GRAVES-4_2_2021_1-8UTC.jpg
    144,7 KB · Aufrufe: 137
  • 3_2_2021_2_11UTC.jpg
    3_2_2021_2_11UTC.jpg
    573 KB · Aufrufe: 147
  • 4_2_2021_2_15UTC.jpg
    4_2_2021_2_15UTC.jpg
    577 KB · Aufrufe: 150
Hier ist ein Echo von heute Morgen, dass vom Log-Programm als Mehrfach-Signal aufgezeichnet wurde. Ursache für das Einbrechen der Intensität ist die Tatsache, dass GRAVES die Strahlrichtung periodisch umschaltet. Das gleiche Signal wurde auch hier von Eberhard aufgezeichnet. Auch dort erkennt man die Intensitätsunterschiede.
Die Signale müssen also nachträglich manuell oder automatisch wieder zusammengefügt werden.

Ich möchte hier aber auf etwas anderes hinaus:
Okke hatte (zu Recht) beanstandet, dass es durch die perspektivische Darstellung zu Abschattung kommt und dadurch Signale verloren gehen können. Hier sieht man, dass auch bei schneller Signalfolge die Echos getrennt werden (was hier natürlich eigentlich nicht erwünscht wäre).
Viele Grüße,
Wilhelm
 

Anhänge

  • 6_25UTC_21_2_2021.jpg
    6_25UTC_21_2_2021.jpg
    566,6 KB · Aufrufe: 133
  • 6_25UTC_21_2_2021_Test.jpg
    6_25UTC_21_2_2021_Test.jpg
    413,9 KB · Aufrufe: 135
Eberhards Signale waren hier im Münsterland nicht oder nur ganz schwach zu sehen. Das kräftigste Signal war hier um 5:35 UTC. Das Bild demonstriert schön, dass eine Störung vom Log-Programm erkannt und ausgeblendet wird. (Der Log-File Auszug wurde von Hand in das SL-Bild eingefügt.)
Viele Grüße,
Wilhelm
 

Anhänge

  • Signal-plus-Stoerung-5_35UTC.jpg
    Signal-plus-Stoerung-5_35UTC.jpg
    196,3 KB · Aufrufe: 142
Meine Software läuft ja, wie oben beschrieben, auf einem Jetson Nano (oder dem Xavier NX). Über ein HDMI-Kabel wird das Videosignal vom PC in den Jetson übertragen. Dort wird es in Echtzeit verarbeitet. Python und Opencv behandeln das Videobild wie ein Array.

Nun ist es mir mit Hilfe des Internets gelungen, die nötigen Programme auf meinem Windows PC zum laufen zu bringen.
Der Spectrum-Lab Bildschirm liegt schon als Python Array vor. Falls alles klappt, erspart es einiges an Hardware und die gesamte Handhabung wird komfortabler. Das Programmieren an 2 Rechnern ist etwas umständlich, so dass ich viele Dinge wie z.B. Auswertungen nach Zeit und Größe vor mir hergeschoben habe.
Viele Grüße,
Wilhelm

Code:
import cv2
import pyautogui
import numpy as np

img = pyautogui.screenshot()                   #capturing screenshot
frame = np.array(img)                          #converting the image into numpy array representation
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) #converting the BGR image into RGB image
                                               #Das wars


#Hier wwrden probeweise bunte Linien generiert
for i in range (1,1280):
    frame = cv2.line(frame,(i,1),(1280-i,720),(i/4, (1280-i)/4, i),1)

# Bildpunkte werden manipuliert
for i in range (200,500):
    for j in range (200,500):
        frame[i,j] = frame[i,j] * 0.8
# Resultat
cv2.imshow(' GRAVES, 21. Juni 2021', frame), cv2.waitKey(0)
 

Anhänge

  • Auswertung-via-Win10.jpg
    Auswertung-via-Win10.jpg
    453 KB · Aufrufe: 115
Oben