Qual algoritmo posso usar para simular bokeh?

12

Estou tentando escrever um script que percorre cada pixel em uma fotografia e aplica um bokeh à imagem como um todo.

Eu criei um script baseado neste link , no entanto, isso parece ser um hack.

Tenho três imagens de entrada: um mapa de profundidade em preto e branco, uma fotografia e uma imagem de "pincel" de bokeh (que atualmente é um hexágono). Para cada pixel da fotografia, carimbo o pincel de bokeh para que fique centrado no pixel e na cor desse pixel.

Parece ... ok em pequenos pincéis de bokeh, mas depois que eu aumento o tamanho do pincel, ele acaba parecendo um borrão gaussiano. Aqui está uma imagem do Times Square borrada com meu algoritmo:

insira a descrição da imagem aqui

Esqueça as bordas escuras, eu posso consertar isso.

Você pode até dizer que é diferente de gaussiano, mas ainda está muito longe do que poderia ser chamado respeitosamente de bokeh, com bordas nítidas:

insira a descrição da imagem aqui

Entendo por que meu algoritmo faz o que faz ... como posso simular com mais precisão um bokeh?

Entidade
fonte
@ Eu entendo as diferenças, e que o Bokeh é normalmente causado por uma lente, e Gaussian pelo pós-processamento, mas quero simular o Bokeh.
Entidade de
@ Entidade: Como procuro imagens de exemplo com um mapa de profundidade preciso? O seu é preciso? Eu gostaria de tentar isso sozinho (depois das finais). Talvez eu tenha uma resposta daqui a algumas semanas. Se o seu for público, posso ter um link para ele?
Martijn Courteaux 18/06/2015
@MartijnCourteaux Para meus testes iniciais, estou apenas usando um mapa de profundidade plana para que tudo fique embaçado. Para geometria simples (por exemplo, um copo em uma mesa), acho que seria bastante simples fazer um mapa de profundidade com boa aparência. Para imagens mais complexas, você provavelmente precisaria de um mapa de profundidade real. Isso pode ser calculado a partir de duas imagens, ou mesmo apenas de uma única imagem .
Entidade de

Respostas:

20

Acho que o principal problema é o alcance dinâmico, seu algoritmo provavelmente está certo, mas você está trabalhando no tipo errado de dados.

Uma fonte de luz pontual que, de outra forma, cortaria e tornaria branco puro, se espalhará por uma lente desfocada em uma área maior, de modo a formar um disco que não seja tão brilhante e, portanto, não cortará.

É por isso que você obtém esses círculos agradáveis ​​em sua imagem bokeh real. Se você capturar o sinal (tornando-o menos brilhante do que seria de outro modo e depois espalhá-lo com sua simulação de bokeh, você obtém um círculo escuro (ou hexágono ou qualquer outro)) que não se destaque e, portanto, não parece realista.

O que você tem em uma cadeia de imagens real é:

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

O que você está fazendo é

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

Você não obterá o resultado correto porque não está trabalhando com dados lineares.

O que você pode fazer é tentar linearizar os dados, substituir qualquer faixa dinâmica que foi perdida para cortar, executar sua simulação de bokeh e refazer as operações não lineares!

Aqui está um exemplo. Comecei com uma imagem HDR que foi mapeada por tom, fornecendo um resultado altamente não-linear. Este é o pior tipo de imagem para tentar a simulação de bokeh!

Fazer uma operação de convolução padrão para simular bokeh (usando a ferramenta de desfoque de lente do photoshop) gera esse resultado, que é muito semelhante ao que você está obtendo:

Para obter um resultado melhor, apliquei uma curva extrema para tentar recuperar a imagem mais ou menos do que teria sido antes do mapeamento de tom, onde os realces são muito, muito mais brilhantes que o restante da imagem. Fiz isso usando a ferramenta de níveis, empurrando a entrada central para a direita, de 1,0 a 0,2). Apliquei a ferramenta Desfoque de lente, como antes. Finalmente, apliquei uma curva extrema na direção oposta à primeira curva. O resultado, embora muito longe da perfeição, parece muito mais com o bokeh de lente real:

 

Se você estiver fazendo isso no código, tente cubar cada valor, aplicando sua rotina de simulação de bokeh e pegue a raiz do cubo de cada valor. Você deve ver uma melhoria. Pode levar alguns ajustes.

tl; dr mesmo se você tiver implementado um modelo matemático perfeita de bokeh, ele deve ser aplicado em dados lineares unclipped. Se você aplicar os mesmos cálculos aos dados fortemente modificados (mesmo um padrão no JPEG da câmera é fortemente modificado do ponto de vista matemático), obterá um resultado muito diferente.

Matt Grum
fonte
12

Antes de tudo, na óptica, apenas a luz aumenta e a escuridão não. Verifique se o seu algoritmo não sangra pixels escuros para fora da localização original. Os pixels resultantes devem se parecer com o máximo de pixels de origem próximos, em vez da média. Ou, para ser ainda mais exato, você resumiria logaritmos que afetam os pixels de origem.

Outra causa possível pela qual as bordas talvez não sejam nítidas seria se as bordas da máscara não forem nítidas. A animação na página que você forneceu como referência pode ser mal interpretada, de modo que, em uma máscara, o pixel original é brilhante e outros são gradualmente mais escuros. Isso também se traduziria em bordas enlameadas no bokeh calculado. Na fotografia, as aberturas têm bordas definidas, não graduais. Na verdade, a maioria dos pixels em uma máscara deve ter brilho igual e apenas as bordas (onde menos de um pixel deve ser colorido para uma linha suave) podem ter um tom de cinza.

Você também mencionou ter um mapa de profundidade, mas nenhuma palavra sobre como usá- lo. O tamanho da sua máscara de bokeh deve estar correlacionado com a profundidade do pixel e a diferença de profundidade do plano focal - quanto mais um pixel estiver do plano focal (em qualquer direção), maior será sua máscara. No plano focal, o tamanho da máscara deve ser 1 × 1 pixel.

Imre
fonte
Desde que todas as operações sejam aditivas, você não terá o problema de áreas escuras se espalhando. É verdade que você precisa de uma máscara nítida para obter círculos nítidos, mas o principal problema é que a operação do bokeh está sendo aplicada a dados não lineares.
precisa