Quale algoritmo posso usare per simulare il bokeh?


12

Sto tentando di scrivere una sceneggiatura che attraversi ciascun pixel di una fotografia e applichi un bokeh all'intera immagine.

Ho creato uno script basato su questo link , tuttavia sembra essere un trucco.

Ho tre immagini di input: una mappa di profondità in bianco e nero, una fotografia e un'immagine "pennello" di bokeh (che attualmente è un esagono). Per ogni pixel della fotografia, stampo il pennello bokeh in modo che sia centrato su quel pixel e nel colore di quel pixel.

Sembra ... va bene su minuscoli pennelli bokeh, ma una volta aumentato la dimensione del pennello bokeh finisce per sembrare sfocatura gaussiana. Ecco un'immagine di times square sfocata con il mio algoritmo:

inserisci qui la descrizione dell'immagine

Non importa i bordi scuri, posso sistemarlo.

Puoi dire che è diverso dal gaussiano, ma è ancora molto lontano da quello che potrebbe essere chiamato rispettabilmente bokeh, con bordi nitidi:

inserisci qui la descrizione dell'immagine

Capisco perché il mio algoritmo fa quello che fa ... come posso simulare più accuratamente un bokeh?



@Imre Capisco le differenze e che Bokeh è in genere causato da una lente e gaussiano dalla post-elaborazione, ma voglio simulare Bokeh.
Entità,

@Entity: come posso cercare immagini di esempio con una mappa di profondità accurata? Il tuo è preciso? Mi piacerebbe provare questo da solo (dopo le finali). Forse mi verrà in mente una risposta tra un paio di settimane. Se il tuo è pubblico, posso avere un link ad esso?
Martijn Courteaux,

@MartijnCourteaux Per i miei test iniziali sto solo usando una mappa di profondità piatta in modo che tutto sia sfocato. Per la geometria semplice (ad es. Una tazza su un tavolo) penso che sarebbe abbastanza semplice creare una bella mappa di profondità. Per immagini più complesse, probabilmente avresti bisogno di una vera mappa di profondità. Questo può essere calcolato da due immagini o anche solo dalla tua singola immagine .
Entità

Risposte:


20

Penso che il problema principale sia quello della gamma dinamica, il tuo algoritmo è probabilmente giusto ma stai lavorando su un tipo di dati sbagliato.

Una fonte di luce puntiforme che altrimenti taglierebbe e diventerebbe bianco puro viene diffusa su un'area più ampia da una lente sfocata, in modo da formare un disco che non è così luminoso e quindi non si ritaglia.

Ecco perché ottieni quei bei cerchi nella tua vera immagine bokeh. Se ritagli il segnale (rendendolo meno luminoso di quanto non sarebbe altrimenti e poi lo diffondi con la tua simulazione bokeh, otterrai un cerchio tenue (o esagono o qualsiasi altra cosa) che non si distingue e quindi non sembra realistico.

Quello che hai in una vera catena di immagini è:

bokeh (from the lens) -> digitisation (clipping) -> gamma correction & dynamic range compression

Quello che stai facendo è

sharp image -> digitisation (clipping) -> gamma correction & dynamic range compression -> bokeh simulation

Non otterrai il risultato corretto perché non stai lavorando con dati lineari.

Quello che puoi fare è tentare di linearizzare i dati, sostituire qualsiasi intervallo dinamico che è stato perso nel ritaglio, eseguire la simulazione del bokeh e quindi ripetere le operazioni non lineari!

Ecco un esempio Ho iniziato con un'immagine HDR che è stata tonemappata, dando un risultato altamente non lineare. Questo è il peggior tipo di immagine con cui provare la simulazione del bokeh!

Effettuare un'operazione di convoluzione standard per simulare il bokeh (usando lo strumento sfocatura obiettivo di Photoshop) produce questo risultato, che è molto simile a quello che stai ottenendo:

Per ottenere un risultato migliore, ho applicato una curva estrema per provare a riportare l'immagine all'incirca a quello che sarebbe stata prima del tonemapping, dove le alte luci sono molto, molto più luminose del resto dell'immagine. L'ho fatto con lo strumento Livelli, spingendo l'ingresso centrale molto a destra, da 1,0 a circa 0,2). Ho quindi applicato lo strumento sfocatura obiettivo, proprio come prima. Alla fine ho applicato una curva estrema nella direzione opposta alla prima curva. Il risultato, benché lontano dalla perfezione, sembra molto più simile al vero bokeh dell'obiettivo:

 

Se lo stai facendo nel codice, prova a cubare ogni valore, quindi applica la routine di simulazione del bokeh, quindi prendi la radice del cubo di ciascun valore. Dovresti vedere un miglioramento. Potrebbero essere necessarie alcune modifiche.

tl; dr anche se hai implementato un modello matematico perfetto di bokeh, deve essere applicato su dati lineari non ritagliati. Se si applicano gli stessi calcoli a dati fortemente modificati (anche uno standard in JPEG della fotocamera è fortemente modificato da un punto di vista matematico) si otterrà un risultato molto diverso.


12

Innanzitutto, in ottica, solo la luce si aggiunge e l'oscurità no. Assicurati che l'algoritmo non sparga i pixel scuri verso l'esterno della loro posizione originale. I pixel risultanti dovrebbero piuttosto assomigliare al massimo dei pixel sorgente vicini rispetto alla media. Oppure, per essere ancora più precisi, riassumeresti i logaritmi dei pixel sorgente interessati.

Un'altra possibile causa per cui i bordi potrebbero non essere nitidi potrebbe essere se i bordi della maschera non sono nitidi. L'animazione nella pagina che hai fornito come riferimento potrebbe essere fraintesa in modo tale che in una maschera il pixel originale sia luminoso e altri siano gradualmente più scuri. Questo si tradurrebbe in bordi fangosi anche nel bokeh calcolato. In fotografia, le aperture hanno bordi definiti, non graduali. Quindi in realtà la maggior parte dei pixel di una maschera dovrebbe avere la stessa luminosità e solo i bordi (dove meno di un pixel dovrebbero essere colorati per una linea liscia) possono essere di qualche sfumatura di grigio.

Hai anche detto di avere una mappa di profondità, ma nessuna parola su come usarla . Le dimensioni della tua maschera bokeh dovrebbero essere correlate alla profondità dei pixel e alla differenza di profondità del piano focale: più un pixel proviene dal piano focale (in entrambe le direzioni), più grande dovrebbe essere la sua maschera. Sul piano focale, la dimensione della maschera dovrebbe essere 1 × 1 pixel.


A condizione che le operazioni siano tutte additive non si otterrà il problema delle aree scure che si espandono. È vero che hai bisogno di una maschera nitida per ottenere cerchi nitidi, ma il problema principale è che la sua operazione bokeh viene applicata a dati non lineari.
Matt Grum,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.