Quel algorithme puis-je utiliser pour simuler le bokeh?

12

J'essaie d'écrire un script qui parcourt chaque pixel d'une photographie et applique un bokeh à l'image dans son ensemble.

J'ai construit un script basé sur ce lien , mais cela semble être un hack.

J'ai trois images d'entrée: une carte de profondeur en noir et blanc, une photographie et une image de "pinceau" bokeh (qui est actuellement un hexagone). Pour chaque pixel de la photographie, je tamponne le pinceau bokeh pour qu'il soit centré sur ce pixel et dans la couleur de ce pixel.

Ça a l'air ... d'accord sur de minuscules pinceaux bokeh, mais une fois que j'augmente la taille du pinceau bokeh, cela finit par ressembler à un flou gaussien. Voici une image des temps carrés flous avec mon algorithme:

entrez la description de l'image ici

Peu importe les bords sombres, je peux arranger ça.

Vous pouvez en quelque sorte dire que c'est différent du gaussien, mais c'est encore loin de ce qui pourrait être respectablement appelé bokeh, avec des bords nets:

entrez la description de l'image ici

Je comprends pourquoi mon algorithme fait ce qu'il fait ... comment puis-je simuler plus précisément un bokeh?

Entité
la source
@Imre Je comprends les différences, et que le Bokeh est généralement causé par une lentille, et gaussien par le post-traitement, mais je veux simuler le Bokeh.
Entité
@Entity: Comment rechercher des exemples d'images avec une carte de profondeur précise? Le vôtre est-il exact? Je voudrais essayer moi-même (après la finale). Peut-être que je trouverai une réponse dans quelques semaines. Si le vôtre est public, puis-je avoir un lien vers celui-ci?
Martijn Courteaux
@MartijnCourteaux Pour mes premiers tests, j'utilise simplement une carte de profondeur plate pour que tout soit flou. Pour une géométrie simple (par exemple une tasse sur une table), je pense qu'il serait assez simple de faire une bonne carte de profondeur. Pour des images plus complexes, vous auriez probablement besoin d'une vraie carte de profondeur. Cela peut être calculé à partir de deux images, ou même à partir de votre seule image .
Entité

Réponses:

20

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.

Matt Grum
la source
12

Tout d'abord, en optique, seule la lumière s'additionne et l'obscurité non. Assurez-vous que votre algorithme ne saigne pas les pixels sombres vers l'extérieur de leur emplacement d'origine. Les pixels résultants devraient plutôt ressembler au maximum de pixels sources proches que la moyenne. Ou, pour être encore plus exact, vous résumeriez des logarithmes affectant les pixels source.

Une autre cause possible pour laquelle vos bords pourraient ne pas être nets serait si les bords de votre masque ne sont pas nets. L'animation de la page que vous avez fournie comme référence peut être mal comprise, de sorte que dans un masque, le pixel d'origine est lumineux et les autres sont progressivement plus sombres. Cela se traduirait également par des bords boueux dans le bokeh calculé. En photographie, les ouvertures ont des bords définis, pas progressifs. Donc, en fait, la plupart des pixels d'un masque doivent être de luminosité égale et seuls les bords (où moins d'un pixel doit être coloré pour une ligne lisse) peuvent avoir une certaine nuance de gris.

Vous mentionnez également avoir une carte de profondeur, mais aucun mot sur son utilisation . La taille de votre masque bokeh doit être en corrélation avec la profondeur des pixels et la différence de profondeur du plan focal - plus un pixel est éloigné du plan focal (dans les deux sens), plus son masque doit être grand. Au plan focal, la taille du masque doit être de 1 × 1 pixel.

Imre
la source
À condition que toutes les opérations soient additives, vous n'aurez pas le problème de l'étalement des zones sombres. Il est vrai que vous avez besoin d'un masque net pour obtenir des cercles nets, mais le problème majeur est que son opération de bokeh est appliquée aux données non linéaires.
Matt Grum