¿Qué algoritmo puedo usar para simular bokeh?

12

Estoy intentando escribir un guión que recorra cada píxel de una fotografía y aplique un bokeh a la imagen en su conjunto.

Creé un script basado en este enlace , sin embargo, parece ser un truco.

Tengo tres imágenes de entrada: un mapa de profundidad en blanco y negro, una fotografía y una imagen de "pincel" bokeh (que actualmente es un hexágono). Para cada píxel de la fotografía, sello el pincel bokeh para que quede centrado en ese píxel y en el color de ese píxel.

Se ve ... bien en pequeños pinceles bokeh, pero una vez que aumento el tamaño del pincel bokeh termina pareciendo un desenfoque gaussiano. Aquí hay una imagen de Times Square borrosa con mi algoritmo:

ingrese la descripción de la imagen aquí

No importa los bordes oscuros, puedo arreglar eso.

Puedes decir que es diferente del gaussiano, pero aún está muy lejos de lo que podría llamarse respetablemente bokeh, con bordes nítidos:

ingrese la descripción de la imagen aquí

Entiendo por qué mi algoritmo hace lo que hace ... ¿cómo puedo simular con mayor precisión un bokeh?

Entidad
fuente
@Imre entiendo las diferencias, y que Bokeh generalmente es causado por una lente, y gaussiano por el procesamiento posterior, pero quiero simular Bokeh.
Entidad
@Entity: ¿Cómo busco imágenes de muestra con un mapa de profundidad preciso? ¿El tuyo es exacto? Me gustaría probar esto yo mismo (después de la final). Tal vez encuentre una respuesta en un par de semanas. Si el tuyo es público, ¿puedo tener un enlace?
Martijn Courteaux
@MartijnCourteaux Para mi prueba inicial, solo estoy usando un mapa de profundidad plano para que todo esté borroso. Para una geometría simple (p. Ej., Una taza sobre una mesa), creo que sería bastante simple hacer un buen mapa de profundidad. Para imágenes más complejas, probablemente necesite un mapa de profundidad real. Esto se puede calcular a partir de dos imágenes, o incluso de una sola imagen .
Entidad

Respuestas:

20

Creo que el problema principal es uno de rango dinámico, su algoritmo probablemente sea correcto pero está trabajando en el tipo de datos incorrecto.

Una fuente de luz puntual que de otro modo se recortaría y pasaría a blanco puro se extiende sobre un área más grande por una lente desenfocada, de modo que forma un disco que no es tan brillante y, por lo tanto, no se recorta.

Es por eso que obtienes esos bonitos círculos en tu imagen bokeh real. Si recorta la señal (haciéndola menos brillante de lo que sería de otro modo y luego la extiende con su simulación de bokeh, obtendrá un círculo oscuro (o hexágono, o lo que sea) que no se destaque y, por lo tanto, no parezca realista.

Lo que tienes en una cadena de imagen real es:

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

Lo que estas haciendo es

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

No obtendrá el resultado correcto porque no está trabajando con datos lineales.

¡Lo que puede hacer es intentar linealizar los datos, reemplazar cualquier rango dinámico que se haya perdido por el recorte, realizar su simulación de bokeh y luego rehacer las operaciones no lineales!

Aquí hay un ejemplo. Comencé con una imagen HDR que ha sido mapeada, dando un resultado altamente no lineal. ¡Este es el peor tipo de imagen para intentar la simulación de bokeh!

Hacer una operación de convolución estándar para simular bokeh (usando la herramienta de desenfoque de lente de Photoshop) produce este resultado, que es muy similar a lo que está obteniendo:

Para obtener un mejor resultado, apliqué una curva extrema para intentar que la imagen volviera a ser lo que hubiera sido antes del mapeo de tonos, donde los resaltados son mucho, mucho más brillantes que el resto de la imagen. Hice esto con la herramienta de niveles, empujando la entrada central un largo camino hacia la derecha, de 1.0 a aproximadamente 0.2). Luego apliqué la herramienta de desenfoque de lente, como antes. Finalmente apliqué una curva extrema en la dirección opuesta a la primera curva. El resultado, aunque lejos de ser perfecto, se parece mucho más al bokeh de lente real:

 

Si está haciendo esto en código, intente dividir cada valor en cubos, luego aplique su rutina de simulación de bokeh y luego tome la raíz cúbica de cada valor. Deberías ver una mejora. Puede tomar algunos ajustes.

tl; dr incluso si ha implementado un modelo matemático perfecto de bokeh, debe aplicarse en datos lineales sin recortar. Si aplica los mismos cálculos a datos muy modificados (incluso un estándar en la cámara JPEG está muy modificado desde un punto de vista matemático) obtendrá un resultado muy diferente.

Matt Grum
fuente
12

En primer lugar, en óptica, solo la luz se suma y la oscuridad no. Asegúrese de que su algoritmo no sangra píxeles oscuros hacia afuera de su ubicación original. Los píxeles resultantes deberían parecerse más al máximo de píxeles de origen cercanos que al promedio. O, para ser aún más exactos, estarías sumando logaritmos de píxeles de origen que afectan.

Otra posible causa por la cual sus bordes podrían no ser afilados sería si los bordes de su máscara no lo son. La animación en la página que ha proporcionado como referencia podría malinterpretarse de modo que en una máscara, el píxel original sea brillante y otros sean gradualmente más oscuros. Esto también se traduciría en bordes fangosos en el bokeh calculado. En fotografía, las aberturas tienen bordes definidos, no graduales. Entonces, en realidad, la mayoría de los píxeles en una máscara deben tener el mismo brillo y solo los bordes (donde menos de un píxel debe ser coloreado para una línea suave) pueden tener un tono gris.

También mencionas tener un mapa de profundidad, pero no se sabe nada sobre su uso . El tamaño de su máscara de bokeh debe estar correlacionado con la profundidad de píxeles y la diferencia de profundidad del plano focal: cuanto más lejos esté un píxel del plano focal (en cualquier dirección), mayor será su máscara. En el plano focal, el tamaño de la máscara debe ser 1 × 1 píxel.

Imre
fuente
Siempre que las operaciones sean todas aditivas, no tendrá el problema de que se extiendan las áreas oscuras. Es cierto que necesita una máscara nítida para obtener círculos nítidos, pero el principal problema es que su operación bokeh se está aplicando a datos no lineales.
Matt Grum