Emulieren Sie die Verschlusszeit auf RAW-Fotos mit Belichtungsstapelung

Also ich habe dieses Problem jetzt seit ungefähr einem Jahr und konnte es nicht lösen. Ich habe es vor einer Weile aufgegeben, aber jetzt habe ich recherchiert und bin bereit, eine Antwort zu bekommen.

Ich versuche, eine Langzeitbelichtung vorzutäuschen, indem ich mehrere RAW-Fotos mache und etwas mit den Bayer-Filterwerten mache , um den Effekt zu erzielen, den Verschluss so lange offen zu lassen.

Die Idee, die ich im Kopf habe, ist, dass Langzeitbelichtung intuitiv funktioniert, indem der Verschluss länger geöffnet bleibt, und daher sind die Lichtsensorwerte (die RAW-Bilder speichern) einfach eine Ansammlung von mehreren kürzeren Fotowerten .

Wenn ich beispielsweise drei 1/3-Sekunden-lange Fotos aufgenommen habe, ohne die Kamera zu bewegen, sollten sie die gleichen Informationen wie ein 1-Sekunden-langes Foto speichern.

Das Problem, das ich bekomme, ist, wie ich diese Aggregation quantifizieren kann. Ich habe festgestellt, dass viele verschiedene Methoden fehlschlagen, und ich bin mir nicht sicher, warum. Wenn ich einfach die mehreren Fotos mittele, bekomme ich eine Menge Rauschunterdrückung . Also das Teil ist schön zu haben. Ich kann Camera Raw später verwenden, um das Foto aufzuhellen , und ich bekomme eine gute Annäherung an das, was ich mit einer 1-Sekunden-Langzeitbelichtung bekommen hätte. Das Problem ist, ich möchte das auf dem Gerät machen. Ich verwende derzeit ein iPhone zum Testen, aber ich denke nicht, dass das eine Rolle spielen sollte.

Aktuelles Setup & Formel

Ich verwende drei 1/3-Sekunden-Belichtungen, um zu versuchen, ein 1-Sekunden-Foto zu fälschen. Meine aktuelle Formel ist einfach:

out_picture[x][y] = picture1[x][y] + picture2[x][y] + picture3[x][y]

Das Problem ist, dass ich dadurch wirklich pinke Bilder wie folgt bekomme:

JPEG-Version der RAW-Datei

Ich habe mehrere verschiedene Variationen der obigen Formel ausprobiert. Eine, die ich für vielversprechend hielt, war die Ableitung der Sigmoidfunktion . Der Grund, warum ich die Ableitung des Sigmoids verwendet habe, ist, dass ich eine Fallstudie durchgeführt habe, in der ich die Wirkung der endgültigen RGB-Ausgaben als Funktion des „EV“-Schiebereglerwerts in Photoshop Camera Raw untersucht und ein Sigmoid-ähnliches Muster gefunden habe. So sieht das aus, wenn ich es für einige Pixel zeichne:

Sigma vielleicht?

Also dachte ich, dass vielleicht die Ableitung des Sigmoids (hohe Änderungen für mittlere Werte, niedrige Änderungen für niedrige und hohe Filterwerte) die Dinge beheben würde. Ich habe die Filterwerte auf einen Bereich von 0-1 normalisiert, indem ich den Schwarzwert und den maximalen Bitwert der Kamera verwendet habe. Ich habe einige Änderungen an der Ableitung vorgenommen, damit sie in den Wertebereich 0-1 passt, das ist die Funktion, die ich am Ende hatte. Ich habe dann mit der Anzahl der aufgenommenen Bilder multipliziert, um den EVSchieberegler in Camera Raw zu emulieren.

Hier ist die Formel dafür (in Python):

def exposureAdjust(x):
   black_level = 528    ## iPhone RAW Photos have a black_level of 528
   max_pixel_value = 2**14 - 1    ## 14-bit depth
   normalized = (x - black_level)/max_pixel_value    ## now x is between [0,1]
   EV = num_pics    ## faking EV value
   adjustment = EV * (np.exp(-10 *(x - 0.25)))/(np.exp(-10*(x - 0.25)) + 1)^2

   return min(x * (1+adjustment), max_pixel_value)    ## Cap at 2**14 


num_pics = 3
out_picture[x][y] = picture1[x][y] + picture2[x][y] + picture3[x][y]
out_picture[x][y] = exposureAdjust(out_picture[x][y]/3)

Wenn ich diese Formel ausführe, erhalte ich ein ähnliches Ergebnis:

Immer noch kaputt


Fazit & Beobachtungen

Wie Sie sehen können, ist es immer noch rosa. Die obigen Bilder sind JPEGs, ja, aber ich arbeite tatsächlich mit den RAWs. Ich musste sie nur als JPEG hochladen, damit sie inline angehängt werden können.

Pink entsteht, wenn Grün fehlt. Die Kamera hat ein Bayer-Filterlayout von RGGB, aber ich sehe wirklich nicht, wie ich diesen Effekt erzielen könnte. Hat jemand eine Ahnung was hier schuld ist und wie ich das programmatisch anpassen kann. Ich habe die gesamte Pipeline eingerichtet. Ich brauche nur die Formel, aber irgendwie funktioniert es nicht. Ich habe dies in Python und Swift codiert, und die Ergebnisse sind die gleichen. Es gibt definitiv ein Problem mit der Formel, die die RAW-Bayer-Filterwerte verwendet. Ich denke, das ist eine coole Herausforderung, aber ich bin mit meiner Weisheit am Ende.

Irgendwelche Gedanken?


UPDATE: Hier sind die Histogrammergebnisse für das Bild vor und nachexposureAdjust Anwendung der Funktion. Es scheint, als müsste der grüne Kanal anders eingestellt werden?

Was fotografieren Sie in Ihrem Beispiel? Es wirkt sehr dunkel und unterbelichtet.
Warten Sie eine Minute, arbeiten Sie direkt mit Rohwerten oder mit debayerisierten Daten?
@scottbb nur ein paar Kabel auf meinem Schreibtisch. Arbeiten Sie direkt mit den Rohwerten. Es ist absichtlich dunkel und unterbelichtet, damit meine Langzeitbelichtung heller sein kann. Ich kann ein besseres Foto hinzufügen
FWIW, das ist genau das, was "Night Mode" auf aktuellem Android tut.
Haben Sie einen funktionierenden Code, um ein einzelnes Bild, das mit einer mittleren ("richtigen") Belichtung aufgenommen wurde, korrekt anzuzeigen?
Also ja, mein Code funktioniert tatsächlich, wenn ich einfach den Durchschnitt aller Bilder ausgebe (Rauschen wird auch reduziert!). Ich möchte es jetzt nur aufhellen. Ich habe auch festgestellt, dass mein Code nicht widerspiegelt, dass ich den Durchschnitt an die Funktion exposureAdjust übergebe, nicht die Summe.
Ich glaube, Sie haben beim Stapeln ein Missverständnis: Unterbelichten Sie nicht jede einzelne Aufnahme im Stapel, in der Erwartung, die Belichtung in der Nachbearbeitung erheblich zu steigern. Nutzen Sie den vollen Bereich Ihrer Kamera für jede Aufnahme und mitteln Sie einfach die Aufnahmen zusammen.
Heilige f... Ich bin ein Idiot. Das macht absolut Sinn, es gibt mir etwas, woran ich mich jetzt abarbeiten kann. Aus Neugier würde ich aber gerne eine Lösung dafür haben. Werde mich mal kurz einlesen.

Antworten (2)

Beobachtungen:

  1. Sie summieren die Werte jedes Pixels, aber Ihre exposureAdjust()Funktion geht davon aus, dass nach der Konditionierung jedes Pixel im Bereich [0, 1) liegt. Das ist nicht richtig. Nehmen wir an, dass der Wert eines Pixels in jedem der 3 Eingabebilder beispielsweise 50 % der vollen Skala beträgt (also 2 13 = 8192). Wenn man das dreimal summiert, ergibt das 3 * 8192 = 24.576. Dann ist das Ergebnis danach normalized = (x - black_level)/max_pixel_valueungefähr 1,47, definitiv nicht auf weniger als 1 normalisiert.

  2. Entfernen Sie Ihre Sigmoidlinie, adjustment =bis Sie den Rest der Logik geklärt haben (wie oben). Hier ist ein Diagramm Ihrer Sigmoidfunktion:

    Geben Sie hier die Bildbeschreibung ein

    Beachten Sie, dass für Werte von x über etwa 0,4 eine Erhöhung von x schnell kleinere Werte von y ergibt (Ihr "angepasster" Wert. Zum Vergleich sollte ein nicht angepasster Wert dem linearen Diagramm y = x entsprechen.

  3. Für die Normalisierung (unter der Annahme korrekt begrenzter Eingaben von [0, max_pixel_value - 1]) sollten Sie wahrscheinlich black_levelauch den Nenner um (dh normalized = (x - black_level)/(max_pixel_value - black_level)) reduzieren. Wenn Sie dies nicht tun, liegen Ihre normalisierten Werte im Bereich von [0, ∼0,969) (genau (2 13 - 511) / (2 14 - 1)).

1. Der erste Codeblock war nur mein erster Versuch. Ich stimme zu 100% zu, dass einer nicht richtig normalisiert wurde. Ich wollte nur zeigen, wie eine falsch normalisierte Eingabe dieselbe Ausgabe ergab.
2. Der Grund, warum ich diese Funktion haben wollte, war, dass ich dachte, dass die Skalierung der Bayer-Werte nicht linear ist. y=x wäre ideal, aber ich dachte, dass die Ursache des Problems vielleicht darin bestand, dass dunkle Pixel (0-0,5) nicht ausreichend hochskaliert wurden.
3. Sicher, das ist ein fairer Punkt, das ist sicher ein Fehler in meinen Berechnungen. Leider glaube ich nicht, dass dies das Problem beheben wird :/

Ihre Ergebnisse sind entschieden magenta und das ist das Gegenteil von dem, wo sie sein sollten. Sie sollten für ein unkorrigiertes Bayer-RGB grün sein.

Ich vermute, dass Ihre beobachtete Sigmoid-Korrektur stark von den Rohdaten beeinflusst wurde, bei denen bereits eine Weißabgleichskorrektur in ACR angewendet wurde. Möglicherweise erhalten Sie an dieser Stelle sogar eine "doppelte Korrektur", aber ich weiß es nicht.

Dieser Artikel zu Uni-WB enthält viele Informationen zu den Rohdatenkorrekturen/-methoden und WB-Korrekturfaktoren. http://www.guillermoluijk.com/tutorial/uniwb/index_en.htm

Die RAW-Daten werden direkt von den Fotos übernommen, die von der Kamera aufgenommen wurden, und passieren niemals ACR. Sie haben Recht, dass mit den Kanälen definitiv etwas nicht stimmt, denn hier sind die Ergebnisse vor und nach der ExposureAdjustment-Funktion. Offensichtlich werden der rote und der blaue Kanal völlig unterschiedlich beeinflusst.
Sie haben angegeben, dass Sie eine Sigmoid-Korrektur entwickelt haben, die auf dem basiert, was Sie mit Photoshop Camera Raw beobachtet haben ... bei dieser Beobachtung wurden Weißabgleichskorrekturen angewendet. Mit welchem ​​Programm renderst du jetzt die manipulierten Rohdaten? AFAIK, das einzige Programm, das eine Rohdatei rendern kann, ohne WB-Korrekturen anzuwenden, ist DCRAW; vielleicht RawDigger.