Ich denke, das Hauptproblem ist der dynamische Bereich. Ihr Algorithmus ist wahrscheinlich richtig, aber Sie arbeiten mit dem falschen Datentyp.
Eine Punktlichtquelle, die ansonsten reinweiß ausschneiden würde, wird durch eine defokussierte Linse über einen größeren Bereich verteilt, so dass sie eine Disc bildet, die nicht so hell ist und daher nicht ausschneidet.
Das ist der Grund, warum Sie diese schönen Kreise in Ihrem echten Bokeh-Bild sehen. Wenn Sie das Signal abschneiden (weniger hell machen als sonst, und es dann mit Ihrer Bokeh-Simulation ausbreiten), erhalten Sie einen dunklen Kreis (oder ein Sechseck oder was auch immer), der nicht auffällt und daher nicht realistisch aussieht.
Was Sie in einer realen Bildkette haben, ist:
bokeh (from the lens) -> digitisation (clipping) -> gamma correction & dynamic range compression
Was Sie tun, ist
sharp image -> digitisation (clipping) -> gamma correction & dynamic range compression -> bokeh simulation
Sie erhalten nicht das richtige Ergebnis, da Sie nicht mit linearen Daten arbeiten.
Sie können versuchen, die Daten zu linearisieren, den durch das Abschneiden verlorenen Dynamikbereich zu ersetzen, eine Bokeh-Simulation durchzuführen und dann die nichtlinearen Operationen erneut auszuführen !
Hier ist ein Beispiel. Ich habe mit einem HDR-Bild begonnen, das tonemappt wurde und ein sehr nichtlineares Ergebnis liefert. Dies ist die schlechteste Art von Bild, mit der Sie eine Bokeh-Simulation versuchen können!
Wenn Sie eine Standard-Faltungsoperation durchführen, um Bokeh zu simulieren (mit dem Objektivunschärfewerkzeug von Photoshop), erhalten Sie dieses Ergebnis, das dem sehr ähnlich ist, was Sie erhalten:
Um ein besseres Ergebnis zu erzielen, habe ich eine extreme Kurve angewendet, um zu versuchen, das Bild wieder in etwa so zu machen, wie es vor dem Tonemapping gewesen wäre, bei dem die Glanzlichter viel, viel heller als der Rest des Bildes sind. Ich habe das mit dem Ebenen-Werkzeug gemacht, indem ich den mittleren Eingang weit nach rechts geschoben habe (von 1,0 auf ungefähr 0,2). Ich habe dann wie zuvor das Werkzeug für die Linsenunschärfe angewendet. Schließlich habe ich der ersten Kurve eine extreme Kurve entgegengesetzt angewendet. Das Ergebnis ist noch lange nicht perfekt, ähnelt jedoch eher einem echten Linsenbokeh:
Wenn Sie dies im Code tun, versuchen Sie, jeden Wert zu würfeln, dann wenden Sie Ihre Bokeh-Simulationsroutine an und nehmen Sie dann die Kubikwurzel jedes Werts. Sie sollten eine Verbesserung sehen. Es könnte einige Anpassungen erfordern.
tl; dr , auch wenn Sie ein perfektes mathematisches Modell Bokeh implementiert haben, müssen sie auf unclipped lineare Daten angewendet werden. Wenn Sie dieselben Berechnungen auf stark veränderte Daten anwenden (selbst ein Standard in Kamera-JPEG wird mathematisch stark verändert), erhalten Sie ein ganz anderes Ergebnis.