Je pense que le problème principal est celui de la plage dynamique, votre algorithme a probablement raison mais vous travaillez sur le mauvais type de données.
Une source de lumière ponctuelle qui, autrement, se détacherait et deviendrait d'un blanc pur est répartie sur une plus grande surface par une lentille défocalisée, de sorte qu'elle forme un disque qui n'est pas aussi brillant et donc ne se clipse pas.
C'est pourquoi vous obtenez ces jolis cercles dans votre image bokeh réelle. Si vous coupez le signal (le rendant moins brillant qu'il ne le serait autrement, puis l'étalez avec votre simulation de bokeh, vous obtenez un cercle sombre (ou hexagone, ou autre) qui ne se démarque pas et ne semble donc pas réaliste.
Ce que vous avez dans une vraie chaîne d'images, c'est:
bokeh (from the lens) -> digitisation (clipping) -> gamma correction & dynamic range compression
Ce que vous faites c'est
sharp image -> digitisation (clipping) -> gamma correction & dynamic range compression -> bokeh simulation
Vous n'obtiendrez pas le résultat correct car vous ne travaillez pas avec des données linéaires.
Ce que vous pouvez faire est d'essayer de linéariser les données, de remplacer toute plage dynamique perdue à cause de l'écrêtage, d'effectuer votre simulation de bokeh, puis de refaire les opérations non linéaires!
Voici un exemple. J'ai commencé avec une image HDR qui a été tonographiée, donnant un résultat très non linéaire. C'est le pire type d'image pour tenter une simulation de bokeh!
Faire une opération de convolution standard pour simuler le bokeh (en utilisant l'outil de flou de l'objectif de Photoshop) donne ce résultat, qui est très similaire à ce que vous obtenez:
Pour obtenir un meilleur résultat, j'ai appliqué une courbe extrême pour essayer de ramener l'image à peu près à ce qu'elle aurait été avant le mappage de tons, où les reflets sont beaucoup, beaucoup plus lumineux que le reste de l'image. Je l'ai fait avec l'outil Niveaux, en poussant l'entrée centrale un long chemin vers la droite, de 1,0 à environ 0,2). J'ai ensuite appliqué l'outil de flou de l'objectif, comme précédemment. Enfin, j'ai appliqué une courbe extrême dans la direction opposée à la première courbe. Le résultat, bien que loin d'être parfait, ressemble beaucoup plus à un véritable bokeh d'objectif:
Si vous faites cela dans du code, essayez de cuber chaque valeur, puis appliquez votre routine de simulation de bokeh, puis prenez la racine cubique de chaque valeur. Vous devriez voir une amélioration. Cela pourrait prendre quelques ajustements.
tl; dr même si vous avez implémenté un modèle mathématique parfait de bokeh, il doit être appliqué sur des données linéaires non écrêtées. Si vous appliquez les mêmes calculs à des données fortement modifiées (même une norme JPEG de l'appareil photo est fortement modifiée d'un point de vue mathématique), vous obtiendrez un résultat très différent.