Neuer Stacker & Kombinierer

Status
Es sind keine weiteren Antworten möglich.
Hier ist Release 0.1.5 mit erster Automatic Background Extraction. Der Stack von Steffens ersten zehn Bildern aus Post #17 in diesem Thread sieht damit jetzt so aus:

Arp316_RGB_FHD.jpg


Wer genau hinsieht, bemerkt noch einige Unstimmigkeiten um helle Sterne und DSOs. Der separat gespeicherte Background zeigt dies deutlicher. In einigen Gitterzellen passt der Gradient nicht zu den Nachbarzellen. Da müsste man nochmal ran. Man könnte z.B. flächige helle Objekte, die in der Sternenerkennung ausgefiltert werden, sich in einer separaten Liste merken und für die Erstellung der Sternenmaske nutzen. Oder auch von Hand gezeichnete Masken als Eingabedatei einlesen.

back00_FHD.jpg


Falls ihr es ausprobieren möchtet, die Aufrufe waren wie folgt:

Code:
nightlight -debayer R -cfa GBRG -out Arp316_R.fits stack Arp316_Lights/*.fit
nightlight -debayer G -cfa GBRG -out Arp316_G.fits stack Arp316_Lights/*.fit
nightlight -debayer B -cfa GBRG -out Arp316_B.fits stack Arp316_Lights/*.fit
nightlight -backGrid 256 -chroma 1.9 -autoScale 0.1 -ppGamma 3.0 -ppSigma 2.0 -scaleBlack 7.84 -out Arp316_RGB.fits rgb Arp316_R.fits Arp316_G.fits Arp316_B.fits

Also für die einzelnen Farbkanäle Debayering mit Maske GBRG, weil Siril beim Konvertieren nach FITS die Bilder vertikal gespiegelt hat; sonst Standardwerte. Für die RGB-Kombination dann folgende Verarbeitung: Hintergrundextraktion mit Gittergrösse 256x256 Pixel, Farbsättigung um 1.9 anheben, beim Autoskalieren einen etwas schmaleren Histogramm-Peak anstreben um das Rauschen zu mindern. Mit einer Gammakurve von 3.0 alle Werte anheben, die zwei Sigma über dem Hintergrundrauschen liegen. . Und zum Schluss den Himmelshintergrund auf 20/255=ca. 7.84% skalieren.
 
Warum es jetzt funktioniert: der Ansatz, den Hintergrund zellenweise als a*x + b*y + c zu modellieren, war grundsätzlich richtig. Das Problem war die Wahl des Koordinatensystems für x und y. Ich habe zunächst einfach mit den globalen Bildkoordinaten gearbeitet. Weil die im rechten und unteren Bildbereich im Vergleich zu den Zellen sehr groß werden können, funktionierte das nicht so recht. Erster Schritt war daher, für jede Zelle ein eigenes Koordinatensystem zu verwenden, dessen Ursprung in der Mitte der Zelle liegt. Das lief, war aber wegen des verwendeten Solvers noch sehr langsam (im Minutenbereich).

Beim Nachdenken am Badesee ist mir dann aufgefallen, dass a, b und c ja linear unabhängig sind. D.h. wir können zunächst für die Konstante c lösen. Das ist einfach der Median der Zelle, mit Ausnahme maskierter Pixel. Dann können wir für a lösen. Intuitiv ist das der Faktor, der bestimmt, wie sich die linke von der rechten Hälfte der Zellen unterscheidet. Also berechnen wir den maskierten Median der linken Zellenhälfte, und den der rechten. a ist dann die Differenz dieser Mediane, geteilt durch das halbe Gitterraster, also b=2*(medianR-medianL)/gridSize. Analog für b mit dem Median der oberen und unteren Zellenhälfte. Ergebnisse nahezu identisch, und der langsame Solver ist raus. Laufzeit jetzt vernachlässigbar, man könnte die ABE statt auf dem Stack bereits auf jedem einzelnen Subframe laufen lassen.

Bekannte verbleibene Themen mit der ABE: Umgang mit helle(re)n Objekten, die von der Sternenerkennung nicht erkannt werden (-> erkennen, oder handgemalte Maske einlesen). Umgang mit dem Sonderfall, wenn alle Pixel einer Zelle maskiert sind, weil ein ausgedehntes Objekt ganz darueber liegt (-> Gradient geeignet aus umgebenden Zellen interpolieren).
 
Zuletzt bearbeitet:
@mlnoga Das Modellieren sieht sehr vielversprechend aus. Eine dicker Gauß-Weichzeichner über das Hintergrundmodell würde schonmal helfen. Aber ich denke Du findest noch eine elegantere Lösung.
Und jetzt weiß ich auch woher die Spiegelung der Bilder kommt, danke.
 
1.) ich kann die BAYER-Maske nur durch Probieren nicht zweifelsfrei feststellen. Dazu müsste ich wissen, welche Farbe der Hintergrund der Bilder in etwa hat. Aber das ist mir viel zu aufwändig, zumal meine Versuche durch den Masterflat völlig falsche Farben hatten.
und 2.) der Masterflat hat erstens eine Spieglung, denn die Donuts entstehen verstärkt auf den gegenüberliegenden Seiten und die Bayermaske der flats scheint anders zu sein.
Es liegt an der Mischung aus Siril ? und IRIS. IRIS spiegelt die Bilder oder liest sie zumindest in anderer Folge ein.
Richtig, es liegt an Siril vs. IRIS.
Leider ist die Spezifikation des FITS Formats nicht eindeutig, in welcher Reihenfolge die Bilddaten abgelegt sein sollen. Der Text legt wohl nahe, dass der Nullpunkt wie in einem üblichen Koordinatensystem unten liegt, die Daten also von unten nach oben geschrieben werden sollen. Viele Astro-Programme schreiben aber die Daten - wie in anderen Bildformaten üblich - von oben nach unten. Leider gibt es dafür wohl auch keinen Header-Eintrag, an dem man das erkennen kann.
Ich wiederhole mich an der Stelle nochmal:
Die Bayermatrix ist RGGB, steht auch so im FITS Header.
Die RAWs wurden mit Siril konvertiert. Das schreibt die FITS wenn ich das richtig verstehe in bottom-up-order, also von unten nach oben. Das ist beim Debayern wichtig.

@mlnoga Interessante Herangehensweise mit dem Hintergrundmodell. Wenn ich das richtig verstehe, approximierst Du den Hintergrund in jeder Zelle für sich als linearen Gradienten? Damit ist aber nie gesichert, das der Übergang zwischen Zellen fließend ist. Evtl. könnte man radial mit abnehmender Deckkraft über die Zelle hinaus den Gradienten in die Nachbarzellen fortsetzen, so dass ein Überblenden passiert?
Ich fürchte aber, bei formatfüllenden Nebeln im ganzen Bild kommt man mit der statischen Einteilung in Zellen nicht mehr hin. Da hat man wirklich nur einzelne Stützpunkte für das Modell und muss dazwischen irgendwie interpolieren.
Vielleicht habe ich aber auch den Ansatz nicht verstanden ;)
Dein Programm arbeitet weiterhin nur mit monochromen Bilddaten, d.h. das Hintergrundmodell wird pro Kanal einzeln berechnet und abgezogen (oder dividiert?) und die Rekombination zum Farbbild passiert zum Schluss, richtig?
Hast Du schon ein Konzept, wie Du mit Daten von mehreren Sessions umgehen willst?

Grüße und CS,
Steffen
 
Hallo Steffen
Richtig, es liegt an Siril vs. IRIS.
Leider ist die Spezifikation des FITS Formats nicht eindeutig, in welcher Reihenfolge die Bilddaten abgelegt sein sollen. Der Text legt wohl nahe, dass der Nullpunkt wie in einem üblichen Koordinatensystem unten liegt, die Daten also von unten nach oben geschrieben werden sollen. Viele Astro-Programme schreiben aber die Daten - wie in anderen Bildformaten üblich - von oben nach unten. Leider gibt es dafür wohl auch keinen Header-Eintrag, an dem man das erkennen kann.
Ich fürchte da ist noch ein Freiheitsgrad mehr, und ein fitskey hilft nicht: Das Programm kann zwar definiert von unten links oder von unten rechts beginnen aber es kann an allen 4 Ecken anfangen, das eingelesene Bild dazustellen.
Kannst Du mir einen bias und einen flat im originalen nef Format bereitstellen? Dann kann ich sehen, wodurch Du den Bias dividiert hast. Und mit dem Flat kann ich sehen, wie die Bayermaske nach dem Export in IRIS sein muss. Ist es ein skyflat, wird der blaue Kanal und der rote Kanal zweifelsfrei erkennbar.



Da hat man wirklich nur einzelne Stützpunkte für das Modell und muss dazwischen irgendwie interpolieren.
Vielleicht habe ich aber auch den Ansatz nicht verstanden ;)
Dein Programm arbeitet weiterhin nur mit monochromen Bilddaten, d.h. das Hintergrundmodell wird pro Kanal einzeln berechnet und abgezogen (oder dividiert?) und die Rekombination zum Farbbild passiert zum Schluss, richtig?
Hast Du schon ein Konzept, wie Du mit Daten von mehreren Sessions umgehen willst?
Gegen das Anknabbern von schwachen Nebeln und Glx- streams usw., werden Stellen ausmaskiert.
 
Ich fürchte da ist noch ein Freiheitsgrad mehr, und ein fitskey hilft nicht: Das Programm kann zwar definiert von unten links oder von unten rechts beginnen aber es kann an allen 4 Ecken anfangen, das eingelesene Bild dazustellen.
In der "freien Wildbahn" kommt nur top-down und bottom-up vor. Aber von mir aus könnte ein Eintrag im FITS-Header auch die Ecke angeben, von der aus gelesen werden soll.

Kannst Du mir einen bias und einen flat im originalen nef Format bereitstellen? Dann kann ich sehen, wodurch Du den Bias dividiert hast. Und mit dem Flat kann ich sehen, wie die Bayermaske nach dem Export in IRIS sein muss. Ist es ein skyflat, wird der blaue Kanal und der rote Kanal zweifelsfrei erkennbar.
Hier verstehe ich nicht so ganz, was Du wissen möchtest.
Ein Bias könnte ich bereitstellen - ist ja schnell gemacht - aber das enthält nur relativ homogenes Rauschen um den Wert 600 herum. Das ist nicht so spannend. Meinst Du mit der Division die Umrechnung in den 32 Bit Float Wertebereich 0-1?
Ein für dieses Bild passendes Flat habe ich nicht mehr.

Warum wandelst Du die NEF-Bilder nicht einfach mit Siril in FITS? Dann passen sie auch zum Master-Flat. Siril ist kostenlos. Einfach die NEF-Bilder reinziehen und auf "Konvertieren" drücken - fertig.

Gegen das anknabbern von schwachen Nebeln und Glx- streams usw., werden Stellen ausmaskiert.
Wenn 90 Prozent des Bildes ausmaskiert sind, dann bleiben eben nur ein paar einzelne Kästchen übrig, zwischen denen interpoliert werden muss. Da sind wir dann wieder bei dem Problem der wenigen Stützpunkte und einer guten Interpolation dazwischen.

Grüße,
Steffen
 
Hier verstehe ich nicht so ganz, was Du wissen möchtest.
Ein Bias könnte ich bereitstellen - ist ja schnell gemacht - aber das enthält nur relativ homogenes Rauschen um den Wert 600 herum. Das ist nicht so spannend. Meinst Du mit der Division die Umrechnung in den 32 Bit Float Wertebereich 0-1?
Ein für dieses Bild passendes Flat habe ich nicht mehr.
Ob spannend oder nicht, woher soll ich wissen, dass der Offset in deinem originalen BIAS Dateien 600 beträgt? Du hast mir ein Bias dabei gelegt, welches nur Werte um 10 hoch minus 6 hat und die konvertierten Bilder haben Werte von 0 bis 16000. Da nützt mir ein dein Bias nichts.
Aber ich will hier nicht mehr weiter machen, diskutieren über so was bringt nix. Ich wollte Dir ein Vergleichsbild anbieten, um das Du gebeten hattest.

Warum wandelst Du die NEF-Bilder nicht einfach mit Siril in FITS? Dann passen sie auch zum Master-Flat. Siril ist kostenlos. Einfach die NEF-Bilder reinziehen und auf "Konvertieren" drücken - fertig.
dann lassen wir das auch. Mich interessiert Siril nicht.
Wenn 90 Prozent des Bildes ausmaskiert sind, dann bleiben eben nur ein paar einzelne Kästchen übrig, zwischen denen interpoliert werden muss. Da sind wir dann wieder bei dem Problem der wenigen Stützpunkte und einer guten Interpolation dazwischen.
Bei 90% ausmaskiert sprechen wir ja nicht mehr von Hintergrund.
 
Sorry, wenn ich Dir irgendwie auf die Füße getreten bin. Ich wollte wirklich nur verstehen, was Du genau möchtest.

Die Idee mit dem Vergleichsbild war eher unabhängig von dem neuen Stacker hier zu sehen, es ging darum, das jemand evtl. die Rohbilder mit seinem üblichen Workflow und seinen Tools der Wahl (z.B. PixInsight, ...) bearbeitet. Möglicherweise ist das mit den unterschiedlichen Formaten (14 Bit NEF RAW vs. 32 Bit float FITS Masters) nicht trivial, je nach verwendeter Software. Wenn das für Dich nicht funktioniert, dann quäle Dich bitte nicht damit. Es war nur so eine Idee.

Grüße,
Steffen
 
Hi Steffen, Zwischenstand: Stacking für jede deiner vier Sessions läuft zügig durch. Die jeweiligen RGB Kombinationen schauen schon deutlich besser aus als der Stack der 10 Testbilder ohne Kalibrierungsdaten.

Ein Vorgehen um mehrere Sessions zu kombinieren wäre wie folgt: einfach die vier Session-Stacks für jeden Farbkanal nochmals stacken. Dann kombinieren. Dabei müsste man mit der summierten Belichtungszeit des jeweiligen Session-Stacks gewichten. Gewichtetes Stacking funktioniert schon, nur dieses spezielle Gewicht noch nicht.

Ich plane also den Fits-Schlüssel EPOSURE (wenn von Nina erzeugt) oder EXPTIME (wenn von Siril erzeugt) der Einzelbilder auszulesen, beim Stacking als Gewicht zu nutzen, und für jeden Stack die Summe wieder abzuspeichern. Dafür habe ich Issue 9 angelegt.

Carsten und Steffen: mal schauen, welche Form der Interpolation am besten tut. Der Medianfilter, den ich für Bad Pixel verwende, ist nicht so geeignet. Er fängt die Änderungen von Zelle zu Zelle nicht ein. Ich habe überlegt, jeweils längs, quer und auf den beiden Diagonalen aus benachbarten Zellen zu interpolieren. Dann könnte man mit den gängigen Verfahren prüfen, ob der Wert je Zelle dazu passt, oder ein Outlier ist. Probleme treten jedoch auf, wenn es zusammenhängende Bereiche von Outliern gibt. Evtl ist es besser, jeweils aus den zwei Zellen links, links oben, oben, ... zu interpolieren. Oder zusammenhängende Regionen glatter Kurven zu bilden. Mal schauen.

Interpolation an den Zellrändern ist eine prima Idee, danke!

Markus
 
Hallo Markus,

ich habe mir Deine Software heruntergelanden. Bin aber beim Versuch, sie zu installieren, gescheitert. Erst habe ich das .zip File heruntergeladen und entfaltet. Aus dem README geht hervor, dass ich einfach nur:

go get -u github.com/mlnoga/nightlight

ausführen soll. Dann bekomme ich aber diese Nachricht:

"package github.com/mlnoga/nightlight: no buildable Go source files in /home/peter/Astro/Software/nightlight-master/src/github.com/mlnoga/nightlight"

Was mache ich falsch?
Neben "golang" habe ich auch noch "git" installieren müssen. Ich habe es auf Linux Debian 9 probiert,

Gruß,
Peter
 
Hallo Peter, mein Fehler, da hat sich eine falsche Pfadangabe eingeschlichen. Manchmal machen auch die Go Modules Probleme. Bitte probiere es so:

GO111MODULE=on go get -u github.com/mlnoga/nightlight/cmd/nightlight

Und melde Dich bitte, falls es weiterhin nicht klappen sollte.

Markus
 
Hallo Markus,

danke! Jetzt bin ich einen Schritt weiter. Ich benutze die tcsh und habe folglich " setenv GO111MODULE 'on' " benutzt. Außerdem mußte ich noch den "GOPATH" setzen. Dann bin ich aber mit dieser Meldung gestrandet:
go get -u github.com/mlnoga/nightlight/cmd/nightlight
package math/bits: unrecognized import path "math/bits" (import path does not begin with hostname)

Welche Berufsgruppe benutzt den "golang"? Und was ist der Vorteil gegenüber amderen Sprachen, wie Python?
Ich habe noch nie von "go" gehört, was aber nichts heißen muß. Ich habe mit FORTRAN, C/C++ angefangen, habe das aber hinter mir gelassen und programmiere jetzt nur noch in Pyhton. Es gibt sehr viele Biliotheken, was die Sache sehr einfach macht. Du hast ja auch ein paar Biliotoken gelinkt, habe ich gesehen.

Gruß,
Peter
 
Hallo Peter, ich habe Deine Fehlermeldung gegoogelt. Offenbar ist math/bits erst seit 2017 Teil der Standardbibliothek, das wusste ich gar nicht. Kannst Du Dir bitte ein aktuelles Go installieren?

Warum Go und nicht Python? Diese Frage ist eine böse Falle... jede Antwort birgt eine nicht vernachlässigbare Gefahr, dass diese Diskussion völlig entgleist ;) Als alter Übersetzerbauer wage ich trotzdem mal einen Versuch.

Als stark typisierte Sprache hilft Go, viele Arten von Fehlern von vornherein zu vermeiden, die in schwach typisierten Sprachen wie Python erst zur Laufzeit auftreten. Typinferenz hilft, den damit verbundenen Tippaufwand geringer zu halten. Die starken Modul-, Import-, Build Tag- und Testkonzepte von Go unterstützen die Arbeit an größeren Projekten besser.

Durch die Verwendung von Coroutinen und Kanälen (goroutines and channels) kann Go alles aus modernen Multicore Prozessoren herausholen, wohingegen Python durch den sogenannten Global Interpreter Lock im wesentlichen auf einen Thread eingeschränkt ist. Als übersetzte Sprache ist Go darüberhinaus auch auf einem Core deutlich schneller als das interpretierte Python, und viel ressourcenschonender. Es erzeugt auf Wunsch statisch gelenkte Binaries, die außer dem Kernel keine weiteren Abhängigkeiten haben, und so die DLL Hölle durchbrechen. In einem Container ausgeliefert, braucht ein solches Binary oft unter 10 MB, wohingegen interpretierte Sprachen wie Python mehrere 100 MB bis GB Abhänhihkeiten mitschleifen. Und damit natürlich auch eine entsprechende Angriffsoberfläche was Softwaresicherheit betrifft.

Anders als sein engster Verwandter C ist Go durch ein mit Grössen versehenes Typsystem voll portabel. Ein Go Compiler kann nur durch Auswahl entsprechender Schalter problemlos Binaries für x64 Linux, Mac und Windows sowie Arm für den RasPi erzeugen. Go hat wie Java eine Garbage Collection, die jedoch auch schwachen Echtzeitanforderungen genügt, und anders als Java nicht sofort alle Ressourcen belegt. Anders als C++ sind die Fehlermeldungen des Go Übersetzers halbwegs verständlich. Und sehr wichtig für das Web: eingebauter HTTPS Server, der leistungsmäßig mit NGINX mithalten kann.

Ästhetisch gesehen ist die Sprache minimalistisch und vermeidet die Ursünde Pythons, Leerzeichen und Tabulatoren semantisch relevant zu machen.

Downsides: unreifere Bibliotheken als in Python, etwas höherer Tippaufwand durch explizite Typumwandlungen, generische Typen wie in C++ fehlen, schlechte Unterstützung für 32 bit float, keine Asm Intrinsics wie in C/C++, keine Standard GUI Bibliothek (mehrere unreifere Varianten).

Wo wird Go heute eingesetzt? Es hat sich als Standardsprache für die moderne Cloud etabliert. U.a. sind Kubernetes, Docker, Istio, Terraform, InfluxDB, CockroachDB in Go geschrieben. Neben Google bauen auch Cloud Foundry, Cloud Flare, Dropbox, Sendgrid, Soundcloud, und viele weitere darauf.

Unabhängig davon ist Python meine zweitliebste Programmiersprache, insbesondere für ML/AI ist die Bibliotheksunterstützung einfach klasse.

Viele Grüsse,
Markus
 
Hallo Markus,

was Programmiersprachen angeht, bin ich ganz entspannt. Da hat so jeder seine Vorlieben. Danke für die ausführliche Erklärung. Ich werde diese Woche vermutlich nicht viel Zeit haben. Im Debian 9 Repository habe ich mir go version go1.7.4 linux/amd64 heruntergeladen. Mittlerweile gibt es aber go1.14

Das werde ich mir herunterladen und installieren. Ich habe gesehen, es gibt auch einen Python -> Go Converter (Grumpy), das ist praktisch.

Ich melde mich wieder.

Gruß,
Peter
 
Peter, prima, viel Erfolg!

Steffen, Issue 9 ist umgesetzt, Stack of Session Stacks funktioniert. In der neuen Version führt `-stWeight 1` eine Gewichtung nach summierter Belichtungszeit durch, und `-stWeight 2` die vermutlich seltener genutzte Gewichtung nach 1/Rauschen. Das Signal-Rauschverhältnis ist damit viel besser.

Die Hintergrundsituation in Deinem Datensatz ist jedoch noch vertrackt. Ich schaue mal, wie erfolgreich die lineare Interpolation der Zellparameter ist. Daher noch kein neues Release.

Viele Grüsse
Markus
 
Hallo Markus,

es ist mir nun gelungen, go1.14 zu installieren und Deine Software zum laufen zu bringen.
Dazu habe ich folgendes Kommando abgesetzt:

nightlight -align 1 -cfa GRBG -flat MasterFlat.fits -dark MasterDark300_0_50.fits -out rgb.fits stack rgb L_NGC4274_2020-04-2*.fit

Damit hat nightlight zwar alle Bilder kombiniert, aber nicht debayert. Ich habe dann für alle Farben einzeln reduziert mit den Flags: -cfa GRBG und -debayer R|G|B
Dannach habe ich versucht die mit rgb zu kombinieren, hat aber nicht geklappt. Das habe ich dann in PI gemacht. Zum Einbinden hier mußte ich das Bild aber auf 25% verkleinern. Dadurch sind auch die Hotpixel verschwunden, die im Original noh sichtbar sind. Und im Verglcih zum unteren Bild etwas streifiger.

test2.png


Zum Vergleich habe ich das Bild mit meinem Python Programm erzeugt. Das sieht noch ein bisschen smoother aus, finde ich.
test1.png


Alles in allem aber schon ein großer Erfolg.


Hier mal ein Snapshot der CPU-Auslastung: Da geht die Post ab. Alle CPUs sind mit nightlight beschäftigt.
Screenshot_20200630_152549.png

Fast 800% CPU-Auslastung ist sehr gut. Bin beeindruckt.

Mein Python Programm schafft nur 137%, braucht aber nur 3:44 min für RGB, was ich zusammen in einem Durchgang berechne. Dein Programm braucht 4:28 min pro Farbkanal bei 800% .

Ich mache es mir aber auch einfacher mit dem Debayern, indem ich lediglich die R, G und B Pixel auslese und die Bilder damit verkleinere. Ich interpolieren nicht, das mit einer Interpolation sowieso nichts gewonnen wird. (Bi)linear sowieso nicht.

Vielleicht habe ich auch was falsch gemacht?

Gruß,
Peter
 
Ich mache es mir aber auch einfacher mit dem Debayern, indem ich lediglich die R, G und B Pixel auslese und die Bilder damit verkleinere. Ich interpolieren nicht, das mit einer Interpolation sowieso nichts gewonnen wird. (Bi)linear sowieso nicht.
Hallo Peter,
das stimmt so nicht. Selbst bei bilinear bekommst Du feine Strukturen in Nebeln und Farbübergängen, die real sind. Linear ist zwar auch eine Farbinterpolation, aber keine Detailinterpolation, weil ja für einen der 4 Punkte ( bei grün sogar 2 ) eine reale Struktur existiert. Du verlierst im Grünen auf jeden Fall. Klar sind deine Bilder nur noch 25 % der Größe und brauchen auch nur 25% des Speichers und der CPU.
 
Hallo Carsten,

mit meinem Equipment C925EHD und ASI1600 bin ich mit f/10 sowieso obversamplet. Da spielt das gar keine Rolle. Das Seeing ist nie besser als 1". Außerdem kommt durch das Dithering immer ein Versatz in die Bilder (deshalb muß man alignen). Das kompensiert das ganze wieder. Mit dem Hyperstar ist schon Vorsicht geboten.

Bei mir ist das Interpolieren durch das Debayern der zeitlich längste Prozess. Deshalb verkürze ich das und nehme nur setze nur die Farbpixel zusammen, die ich zum Schluß aber aligne, so dass kein Farbsaum entsteht.

Ein mehr n Information erhlält man aber durch lineare Interpolation nie.

Gruß,
Peter
 
mit meinem Equipment C925EHD und ASI1600 bin ich mit f/10 sowieso obversamplet
Das habe ich nachgerechnet und auch da muss ich Dir widersprechen: Bei der ASI 1600 sind die Pixel bei Dir 0.33 " in der Kante. Die Auflösung ist aber die Diagonale eines Pixels und da bist Du bei 0.5 ". Du schaffst also genau 1" mit dem 2x Oversampling. Du hast also Nichts zu verschenken. Außerdem im Vergleich zur DSLR hast Du noch nicht einmal einen Weichzeichnungfilter davor. Ich würde an Deiner Stelle mit voller "Auflösung" und Farbinterpolation stacken. Danach kannst Du schärfen und prozentweise herunterskalieren, bis dir die Sterne gefallen. Das Scheinargument, dass die Farbinterpolation so lange dauert, lasse ich nicht gelten. Du steckst doch eh so viel Zeit in die Bilder, da kommt es auf 10 oder 20 Minuten oder mehr auch nicht an.
Ein mehr an Information erhält man aber durch lineare Interpolation nie
Das ist schon richtig, aber wir reden hier (und das sage ich nochmal) von der Farbinterpolation.
Ich finde diese Technik auch eine Mogelpackung, da die volle Auflösung gar nicht erreicht wird. Aber mehr als bei Deiner Demosaikprozedur ist es schon.
 
Da hast Du in sofern recht, das ja immer ein anderes Farbpixel dazwischen liegt, das suggeriert dann etwas mehr an Auflösung. Das ist aber schwer, das in der Realität zu überprüfen. Ich habe keine bessere Auflösung bzw mehr Details mit dem originalen Debayerverfahren an meinen Bildern sehen können. Zudem resample ich meistens sowieso meine Bilder um einen Faktor 2 oder mehr, weil die sonst nicht auf meinem Bildschirm passen.

Meines Erachtens ist es bei meinen Belichtungszeiten von 300s ohnehin reine Illusion, an die theoretische Auflösung des Teleskops heranzukommen. Das geht allenfalls bei Kurzzeitbelichtungen von << 1s, wie man das bei Planeten macht. Beim Hyperstar sind meine Kamerapixel noch viel zu groß, um richtig samplen zu können. Da wird mein Verfahren sehr eng, wenn ich dann nur noch die halbe Anzahl an Pixel nehme. Also mit Löchern drin. Auch bei einem "normalen" Seeing um 2-3".
 
Hallo Peter, freut mich, dass Du erste Ergebnisse erzielen konntest. Wenn Du Nightlight ohne besondere Parameter stacken lässt, macht das Programm einen Suchlauf über alle möglichen Parameter, um die gängige Empfehlung von 0.5% low clipping und 0.5% high clipping zu erreichen. Um diese Automation zu erreichen, werden die Bilder meist 8-12x hintereinander gestackt. Im Logfile stehen die ermittelten Werte für --stSigLow und --stSigHigh. Stacke einfach mit diesen Parametern nochmal, dann siehst Du wie schnell ein einfacher Durchlauf trotz vierfacher Bildgröße wirklich ist.

Grundsätzlich haben alle Aufrufe die Form nightlight [-parameter1 wert1 ... -parameterN wertN] befehl file1.fits file2.fits ... fileM.fits. Dabei kannst Du beliebig viele der Parameter verwenden, aber nur einen Befehl wie stack oder rgb. Wenn Du wie in deinem Beispiel stack und rgb gleichzeitig verwendest, wird der zweite Eintrag als Dateiname aufgefasst, und erzeugt dann wegen einer fehlenden Datei einen Fehler. Probier bitte mal das:

Code:
nightlight -dark MasterDark300_0_50.fits -flat MasterFlat.fits -cfa GRBG -debayer R -out r.fits stack  L_NGC4274_2020-04-2*.fit
nightlight -dark MasterDark300_0_50.fits -flat MasterFlat.fits -cfa GRBG -debayer G -out g.fits stack  L_NGC4274_2020-04-2*.fit
nightlight -dark MasterDark300_0_50.fits -flat MasterFlat.fits -cfa GRBG -debayer B -out b.fits stack  L_NGC4274_2020-04-2*.fit
nightlight -out rgb.fits rgb r.fits g.fits b.fits

Wenn das tut, kannst Du beim Stacken ja -stSigLow X.X und -stSigHigh Y.Y mitgeben, oder mit Parametern für die RGB-Kombination experimentieren. -chroma 2.0 macht die Farben deutlich kräftiger, und -ppGamma 2.5 -ppSigma 2.0 wendet eine Gammakorrektur von 2.5 auf alle Werte an, die zwei Standardabweichungen über dem Hintergrundniveau liegen.

Hotpixel sind in Mono kein Problem mehr. Sie werden in der ersten Stufe von der kosmetischen Korrektur ausgefiltert (Einstellung --bpSigLow X.X und --bpSigHigh Y.Y mit Defaults 3 und 5. Auf RGB erzeugt diese Korrektur jedoch Artefakte, weil sie die Bayermatrix noch nicht kennt. Debayering ist als Funktion ja grade erst eine Woche alt. Ich mache mal Issue 10 dafür auf. Im zweiten Schritt sollten Hotpixel geditherten Bildern im Stacking verschwinden, wenn genügend Bilder vorliegen. Standardmäßig nimmt nightlight ab 6 Bildern Sigma Clipping, ab 15 Winsorized Sigma Clipping und ab 25 Bildern Linear Fit Clipping. Bei weniger als 6 Bildern erfolgt reines Durchschnittswert-Stacking, was Hotpixel nicht aussortiert. Statt dieser automatischen Wahl kannst Du den Stackingmodus über -stMode N auch einstellen.
 
Hallo Markus,

das werde ich heute Abend mal probieren. Ich habe 78 Einzelbilder gestackt. So, wie Du mir erklärt hast, ist das Programm wohl 11x durchgelaufen. Das er "rgb" als File sucht, war mir gar nicht aufgefallen. Hat aber offensichtlich auch nicht gestört. Ich habe den letzten Befehl mit "rgb" nun mal durchlaufen lassen. Da passiert ja noch einiges. Die Farben liegen aber auch schön übereinander.

Die Hotpixel identifiziere ich für alle drei Farben, indem ich mir vom ersten Set (RGB-Bild) eine Maske mache (die Hotpixel liegen ja immer an der selben Stelle). Das geht mit den Libs von Python natürlich einfach:

Python:
def repair_hotpixel(data, hpmask):

    if len(data.shape) == 2:

       for y, x in zip(hpmask[0], hpmask[1]):

           data[y, x] = np.median(data[y-1:y+2, x-1:x+2])

    else:

       for n in range(len(data.shape)):

           for y, x in zip(hpmask[n][0], hpmask[n][1]):

               data[n][y, x] = np.median(data[n][y-1:y+2, x-1:x+2])

    return data


def hotpixel_mask(data, eps=10.0):

    if len(data.shape) == 2:

       blurred = median_filter(data, size=2)

       difference = data - blurred

       threshold = eps*np.std(difference)

       hot_pixels = np.where((np.abs(difference[1:-1, 1:-1]) > threshold))

       hot_pixels = np.array(hot_pixels) + 1

    else:

       hot_pixels = len(data.shape)*[[]]

       for n in range(len(data.shape)):

           blurred = median_filter(data[n], size=2)

           difference = data[n] - blurred

           threshold = eps*np.std(difference)

           hot_pixels1 = np.nonzero(difference[1:-1, 1:-1] > threshold)

           hot_pixels2 = np.nonzero(difference[1:-1, 1:-1] < -threshold/3.0)

           hot_pixels[n] = np.hstack((hot_pixels1, hot_pixels2))

           #hot_pixels[n] = np.where((np.abs(difference[1:-1, 1:-1]) > threshold))

           hot_pixels[n] = np.array(hot_pixels[n]) + 1

    return hot_pixels

Wenn ich einmal die Masken für RGB erzeugt habe, wird nur noch repariert.

Gruß,
Peter
 
Am besten für Bilder mit Bayer-Matrix wäre natürlich ein Bayer-Drizzle, also gar keine Interpolation, aber trotzdem die volle Auflösung erhalten. Das funktioniert natürlich nur, wenn genügend viele Bilder mit ein wenig Versatz (Dithering!) vorhanden sind, um die Pixel-Lücken in der Farbinformation zu schließen.
Wenn nightlight das gut hinbekäme, dann hätte es auf jeden Fall für mich einen echten Pluspunkt gegenüber Siril ;)

Grüße,
Steffen
 
Steffen, das könnte vielleicht gehen. Nightlight nutzt zB bei der Projektion der Einzelbilder auf das Referenzbild den besonderen Fliesskommawert NaN für Bereiche die außerhalb des Originalbilds liegen. Dieser Wert wird im Stacking sowohl im Zähler als auch im Nenner ignoriert, um glatte Ränder zu erzeugen.

Man könnte beim Debayern mal die sonst interpolieren Bereiche auf NaN setzen. Ggf müsste man einige statistische Funktionen anpassen, weil QSelect davon ausgeht, dass alle Zahlen vergleichbar sind, doch NaN ist ungleich von sich selbst. NaN ist auch beim Export in andere Software Gift, der Gimp zeigt leere Bilder an wenn auch nur ein Pixel NaN ist. Dieser Wert wird daher standardmäßig beim Speichern durch 0 ersetzt.

Hmm aber man müsste die bilineare Interpolation in der Projektion irgendwie ausschalten. Vielleicht doch trickreich.

Ich mache mal Issue 11 dafür auf.
 
Die NaN-Pixel müssen aber nicht nur beim Stacking, sondern insbesondere auch bei der Alignment-Transformation berücksichtigt werden. Ich bin mir jetzt nicht sicher, wie Dein Programm da arbeitet. Werden transformierte Zwischenergebnis-Bilder erstellt, die dann gestackt werden, oder wird beim Stacken auf die Originalbilder mit einer Transformation zugegriffen?
Im zweiten Fall wäre die Behandlung von NaN-Pixeln relativ einfach möglich.
Nach dem Stacken könnten dann verbliebene NaN-Pixel aus den Umgebungspixeln interpoliert werden. Eventuell könnte man auch noch mit Umgebungsinformation interpolieren, wenn für ein Pixel nur vergleichsweise wenige Bilder Information beigetragen haben (weil die Bayer-Matrix in zu vielen Bildern ungünstig lag)
 
Insbesondere die R und B Kanäle haben mehr Leestellen (0) als Daten (D). Für R (GRBG) sieht das dann so aus:

0 D 0 D 0 D 0 D
0 0 0 0 0 0 0 0
0 D 0 D 0 D 0 D
0 0 0 0 0 0 0 0

Wenn das beim Alignen interpoliert werden soll, wird es schwierig und aufwendig. Zudem muß man beim Aufsummieren immer eine Gewichtsmap mitführen, die einem sagt, wieviele Daten gerade gemittelt werden müssen. Das variiert von Punkt zu Punkt, wegen der Leerstellen.
 
Hallo Markus,

ich habe es nochmals probiert, aber auch kein besseres Ergebnis herausbekommen, als vorher. Das Gamma setzen (-chroma 2.0) hat die Galaxie farblich nicht verändert, sonden nur den Hintergrund. Da sieht man nun den grünen und magenta Farbschleier noch besser. ;)
Die bekomme ich aber mit dem DBE-Tool aus PI heraus. Ich glaube, ich bleibe doch bei meinem Programm, das ganz auf meine Bedürfnisse angepasst ist. Ich habe eine Ringpuffer, der jeweils drei (oder 5) RGB-Karten enthält und Punkt für Punkt deb Median aus diesen Karten bildet und auf ein Summenbild addiert. So bekomme ich am leichtesten Störungen (wie Satelliten) heraus. Das geht ruck-zuck. Damit erhalte ich die besten Bilder für mich. Den Reste mache ich in PI.

Trotzdem ein interessantes Tool. Ich wünsche Dir weiterhin viel Erfolg beim Weiterentwickeln.

Gruß,
Peter
 
Carsten: Tausend Dank für Deine Adleraugen. Das Debayering des Grünkanals hatte tatsächlich noch einen Fehler in Zeile 112. Release 0.1.8 behebt ihn und steigert die Bildqualität damit deutlich.

Peter: Wenn Du magst, schau gerne nochmal, was das für Dich bringt. Ansonsten frohes Schaffen mit Deinem Programm!

Steffen: Hier der Stack of Stacks deiner vier Sessions von Arp 316 mit korrigiertem Debayering und dem aktuellen Stand der automatischen Hintergrundkorrektur. Letztere erkennt jetzt iterativ lokale Outlier im Hintergrund, und ersetzt sie iterativ durch Interpolationen aus der lokalen Umgebung.

Arp316_RGB_curves_1920.jpg


Die letzte Luminanzkurve habe ich in Gimp draufgelegt, ansonsten alles Nightlight. Mit gefühlvollen Händen an der letzten Kurve wäre hier vermutlich noch mehr herauszuholen. Wenn für Dich OK, stelle ich die nach FITS konvertierten Roh- und Kalibrierungsdaten sowie die zugehörigen Makefiles auf Github ein. Bitte sag Bescheid.

Markus
 
Hallo Markus,

Wieder ein schöner Fortschritt! Ich habe nichts dagegen, wenn Du die Files einstellst. Dann habe ich auch gleich ein Beispiel mit Makefile für eigene Experimente.

Grüße,
Steffen
 
Hallo Markus,

Ich wollte Deinen Stacker jetzt auch mal selbst ausprobieren, allerdings funktioniert das Bauen leider nicht:
Code:
GO111MODULE=on go get -u github.com/mlnoga/nightlight/cmd/nightlight
go: cannot find main module; see 'go help modules'
Das Ganze auf einem Debian 10.4, golang 1.11 ist installiert.
Was fehlt da noch?

Grüße,
Steffen
 
Status
Es sind keine weiteren Antworten möglich.
Oben