Myślę, że głównym problemem jest zakres dynamiczny, twój algorytm prawdopodobnie ma rację, ale pracujesz na niewłaściwym typie danych.
Punktowe źródło światła, które w przeciwnym razie przycinałoby się i przechodziło w czystą biel, rozprzestrzenia się na większym obszarze przez rozmytą soczewkę, dzięki czemu tworzy dysk, który nie jest tak jasny i dlatego nie zacina się.
Właśnie dlatego masz ładne kręgi na swoim prawdziwym obrazie bokeh. Jeśli przyciśniesz sygnał (sprawiając, że będzie mniej jaśniejszy niż w innym przypadku, a następnie rozłożysz go za pomocą symulacji bokeh, otrzymasz przyciemniony okrąg (lub sześciokąt lub cokolwiek innego), który nie wyróżnia się, a zatem nie wygląda realistycznie.
To, co masz w prawdziwym łańcuchu obrazów, to:
bokeh (from the lens) -> digitisation (clipping) -> gamma correction & dynamic range compression
To co robisz jest
sharp image -> digitisation (clipping) -> gamma correction & dynamic range compression -> bokeh simulation
Nie uzyskasz poprawnego wyniku, ponieważ nie pracujesz z danymi liniowymi.
Możesz spróbować zlinearyzować dane, zastąpić dowolny zakres dynamiczny, który został utracony z powodu przycinania, wykonać symulację bokeh, a następnie ponownie wykonać operacje nieliniowe!
Oto przykład. Zacząłem od obrazu HDR, który został zmapowany tonem, co daje wysoce nieliniowy wynik. To najgorszy rodzaj obrazu, przy którym można przeprowadzić symulację bokeh!
Wykonanie standardowej operacji splotu w celu symulacji bokeh (za pomocą narzędzia do rozmycia soczewek w Photoshopie) daje ten wynik, który jest bardzo podobny do tego, co otrzymujesz:
Aby uzyskać lepszy wynik, zastosowałem ekstremalną krzywą, aby spróbować przywrócić obraz mniej więcej taki, jaki byłby przed mapowaniem tonalnym, gdzie podświetlenia są znacznie, znacznie jaśniejsze niż reszta obrazu. Zrobiłem to za pomocą narzędzia poziomów, przesuwając środkowy sygnał wejściowy daleko w prawo, od 1,0 do około 0,2). Następnie zastosowałem narzędzie do rozmycia obiektywu, tak jak poprzednio. W końcu zastosowałem ekstremalną krzywą w przeciwnym kierunku do pierwszej krzywej. Rezultat, choć daleki od ideału, wygląda bardziej jak prawdziwy bokeh obiektywu:
Jeśli robisz to w kodzie, spróbuj podzielić każdą wartość na kostkę, a następnie zastosować procedurę symulacji bokeh, a następnie weź pierwiastek kostki z każdej wartości. Powinieneś zobaczyć poprawę. Może to wymagać drobnych poprawek.
tl; dr, nawet jeśli zaimplementowałeś idealny matematyczny model bokeh, należy go zastosować do nielipowanych danych liniowych. Jeśli zastosujesz te same obliczenia do mocno zmodyfikowanych danych (nawet standardowy aparat JPEG jest mocno zmodyfikowany z matematycznego punktu widzenia), otrzymasz zupełnie inny wynik.