Desfoque Gaussiano - Desvio Padrão, Raio e Tamanho do Kernel

18

Eu implementei um sombreador gaussiano de fragmentos no GLSL. Eu entendo os principais conceitos por trás de tudo isso: convolução, separação de x e y usando linearidade, passagens múltiplas para aumentar o raio ...

Ainda tenho algumas perguntas:

  • Qual é a relação entre sigma e raio?

    Eu li que o sigma é equivalente ao raio, não vejo como o sigma é expresso em pixels. Ou "raio" é apenas um nome para sigma, não relacionado a pixels?

  • Como escolho o sigma?

    Considerando que eu uso várias passagens para aumentar o sigma, como escolho um bom sigma para obter o sigma que quero em um determinado passe? Se o sigma resultante for igual à raiz quadrada da soma dos quadrados dos sigmas e o sigma for equivalente ao raio, qual é a maneira mais fácil de obter o raio desejado?

  • Qual é o bom tamanho de um kernel e como ele se relaciona com o sigma?

    Eu já vi a maioria das implementações usar um kernel 5x5. Essa é provavelmente uma boa opção para uma implementação rápida com qualidade decente, mas há outro motivo para escolher outro tamanho de kernel? Como o sigma se relaciona com o tamanho do kernel? Devo encontrar o melhor sigma para que os coeficientes fora do meu kernel sejam desprezíveis e normalizem?

LodeRunner
fonte

Respostas:

21

Qual é a relação entre sigma e raio? Eu li que o sigma é equivalente ao raio, não vejo como o sigma é expresso em pixels. Ou "raio" é apenas um nome para sigma, não relacionado a pixels?

Há três coisas em jogo aqui. A variação ( ), o raio e o número de pixels. Como essa é uma função gaussiana bidimensional, faz sentido falar da matriz de covariância \ boldsymbol {\ Sigma} . Seja como for, no entanto, esses três conceitos estão fracamente relacionados. Σσ2Σ

Primeiro de tudo, o gaussiano 2-D é dado pela equação:

g(z)=1(2π)2|Σ|e12(zμ)TΣ1 (zμ)

Onde é um vector de coluna que contém a e de coordenadas na sua imagem. Portanto, e é um vetor de coluna que codifica a média da sua função gaussiana, nas direções e . x y z = [ x y ] μ x y μ = [ μ x μ y ]zxyz=[xy]μxyμ=[μxμy]

Exemplo:

Agora, digamos que definimos a matriz de covariância e . Também definirei o número de pixels como x . Além disso, minha 'grade', onde avalio este PDF, de a , tanto em quanto em . Isso significa que eu tenho uma resolução de grade de . Mas isso é completamente arbitrário. Com essas configurações, receberei a imagem da função de densidade de probabilidade à esquerda. Agora, se eu mudar a 'variância' (realmente, a covariância), de modo que μ = [ 0 0 ] 100 100 - 10 10 x y 10 - ( - 10 )Σ=[1001]μ=[00]1001001010xyΣ=[ 9 0 0 9 ]10(10)100=0.2Σ=[9009] e mantenha tudo o mesmo, recebo a imagem à direita.

insira a descrição da imagem aqui

O número de pixels ainda é o mesmo para ambos, x , mas alteramos a variação. Suponha que façamos o mesmo experimento, mas use x pixels, mas eu ainda corri de a . Então, minha grade tem uma resolução de . Se eu usar as mesmas covariâncias de antes, recebo o seguinte:100 20 20 - 10 10 10 - ( - 10 )1001002020101010(10)20=1

insira a descrição da imagem aqui

É assim que você deve entender a interação entre essas variáveis. Se você quiser o código, posso postá-lo aqui também.

Como escolho o sigma?

A escolha da matriz de variância / covariância do seu filtro gaussiano é extremamente dependente da aplicação. Não há resposta correta. É como perguntar qual largura de banda se deve escolher para um filtro. Novamente, isso depende da sua aplicação. Normalmente, você deseja escolher um filtro gaussiano para anular uma quantidade considerável de componentes de alta frequência em sua imagem. Uma coisa que você pode fazer para obter uma boa medida é calcular o DFT 2D da sua imagem e sobrepor seus coeficientes à sua imagem gaussiana 2D. Isso informará quais coeficientes estão sendo fortemente penalizados.

Por exemplo, se sua imagem gaussiana tem uma covariância tão ampla que abrange muitos coeficientes de alta frequência da sua imagem, você precisa diminuir seus elementos de covariância.

Tarin Ziyaee
fonte
1
Essas imagens seriam melhores se eles usassem um mapa de cores seqüencial. jato é o pior.
endolith 27/07
@endolith "Melhor" depende da aplicação. Não uso jet quando é necessária discriminação visual. (Quente é melhor). Aqui, porém, a mensagem está dentro do tamanho do gaussiano, portanto, nenhum dano causado ao jato. Obrigado pelo link embora.
Tarin Ziyaee
2
Esta é uma resposta bem pensada e realmente bem visualizada! Veja a imagem superior esquerda, por exemplo. É claro que essa combinação de variação e tamanho do kernel seria um desperdício, já que é um kernel 100x100 em que apenas o centro 30x30 (~ 9%) é diferente de zero.
Adam Smith
4

O parâmetro sigma é suficiente para definir o desfoque gaussiano de um ponto de vista contínuo. Na prática, no entanto, imagens e núcleos de convolução são discretos. Como escolher uma aproximação discreta ideal do kernel Gaussiano contínuo?

A aproximação discreta estará mais próxima do kernel Gaussiano contínuo ao usar um raio maior. Mas isso pode custar uma duração de computação adicional.

Idealmente, alguém selecionaria um valor para sigma e depois calcularia um raio que permita representar fielmente o correspondente núcleo Gaussiano contínuo. Para um dado erro de aproximação, quanto maior o sigma, maior o raio.

Curiosamente, isso pode se tornar muito complicado para acertar. Ao construir a matriz gaussiana, é a melhor solução para amostrar o kernel contínuo ou existem aproximações melhores? Como normalizar o kernel discreto computado para explicar o truncamento? etc.

Como referência, no Mathematica, a função GaussianMatrix apresenta várias maneiras de calcular uma matriz discreta gaussiana, por exemplo, usando aproximação discreta de Bessel. Por padrão, raio = 2 * sigma, o que significa que com sigma = 1, a matriz será 5x5.

Matthias Odisio
fonte
Esta é uma pergunta bastante antiga. Mas um raio de 2 * sigma não resultaria em uma matriz 9x9?
Delusional Logic
@DelusionalLogic com sigma = 1, raio = 2, para que a matriz tenha o tamanho 4, mas precise de um tamanho ímpar para o tamanho 5x5. Pelo menos é assim que eu entendo ..
Micka
Se o raio for 2, a vizinhança estenderá o pixel central em 2 pixels para a esquerda, 2 para a direita, etc. É apenas a convenção que o Mathematica usa.
Matthias Odisio
2

Acontece que as linhas do Triângulo de Pascal se aproximam bastante de um gaussiano e têm a vantagem prática de ter valores inteiros cuja soma é uma potência de 2 (podemos armazenar esses valores exatamente como inteiros, valores de pontos fixos ou flutuantes). Por exemplo, digamos que desejamos construir um Kernel Gaussiano 7x7, podemos fazê-lo usando a sétima linha do triângulo de Pascal da seguinte maneira:

insira a descrição da imagem aqui

Observe que esse filtro exerce a influência mínima nos cantos enquanto permanece com valor inteiro. Você pode usar o valor do meio 20/64 para determinar o sigma do desvio padrão correspondente, que é 64 / (20 * sqrt (2 * pi)) = 1,276 para o Gaussiano aproximado neste caso. Você pode representar graficamente o gaussiano para ver se esse é um excelente ajuste.

Portanto, um bom ponto de partida para determinar um desvio padrão razoável para um Kernel Gaussiano vem do Triângulo de Pascal (também conhecido como Coeficientes Binomiais ) - para um filtro (N + 1) x (N + 1) correspondente ao uso de construção acima

insira a descrição da imagem aqui

GaussianMatrix de Wolfram Alpha [3] apenas usa r / 2 = 1,5. Estranhamente, GaussianMatrix [{3,1.276}] não produz o mesmo filtro 2D que o meu e não é o seguinte para x, y entre -3 e 3:

insira a descrição da imagem aqui

Não sei por que não? Meu filtro 2D é um excelente ajuste.

wcochran
fonte