Na convolução, duas funções matemáticas são combinadas para produzir uma terceira função. No processamento de imagens, as funções são geralmente chamadas de kernels. Um kernel nada mais é do que uma matriz (quadrada) de pixels (uma pequena imagem, por assim dizer). Geralmente, os valores no kernel somam um. Isso é para garantir que nenhuma energia seja adicionada ou removida da imagem após a operação.
Especificamente, um núcleo gaussiano (usado para desfoque gaussiano) é uma matriz quadrada de pixels em que os valores de pixel correspondem aos valores de uma curva gaussiana (em 2D).
Cada pixel da imagem é multiplicado pelo kernel gaussiano. Isso é feito colocando o pixel central do kernel no pixel da imagem e multiplicando os valores na imagem original pelos pixels no kernel que se sobrepõem. Os valores resultantes dessas multiplicações são somados e esse resultado é usado para o valor no pixel de destino. Olhando para a imagem, você multiplicaria o valor em (0,0) na matriz de entrada pelo valor em (i) na matriz do kernel, o valor em (1,0) na matriz de entrada pelo valor em (h ) na matriz do kernel e assim por diante. e adicione todos esses valores para obter o valor de (1,1) na imagem de saída.
Para responder sua segunda pergunta primeiro, quanto maior o kernel, mais cara será a operação. Portanto, quanto maior o raio do desfoque, mais longa será a operação.
Para responder à sua primeira pergunta, como explicado acima, a convolução pode ser feita multiplicando cada pixel de entrada com o kernel inteiro. No entanto, se o kernel for simétrico (que é um kernel gaussiano), você também poderá multiplicar cada eixo (x e y) independentemente, o que diminuirá o número total de multiplicações. Em termos matemáticos adequados, se uma matriz é separável, ela pode ser decomposta em matrizes (M × 1) e (1 × N). Para o kernel gaussiano acima, isso significa que você também pode usar os seguintes kernels:
1256⋅⎡⎣⎢⎢⎢⎢⎢⎢1464141624164624362464162416414641⎤⎦⎥⎥⎥⎥⎥⎥=1256⋅⎡⎣⎢⎢⎢⎢⎢⎢14641⎤⎦⎥⎥⎥⎥⎥⎥⋅[14641]
Agora você multiplicaria cada pixel na imagem de entrada com os dois núcleos e adicionaria os valores resultantes para obter o valor do pixel de saída.
Para mais informações sobre como ver se um kernel é separável, siga este link .
Editar: os dois núcleos mostrados acima usam valores ligeiramente diferentes. Isso ocorre porque o parâmetro (sigma) usado para a curva gaussiana para criar esses núcleos foi ligeiramente diferente nos dois casos. Para uma explicação sobre quais parâmetros influenciam a forma da curva gaussiana e, portanto, os valores no kernel seguem este link
Edit: na segunda imagem acima, diz que o kernel usado é invertido. Obviamente, isso só faz diferença se o kernel que você usa não é simétrico. A razão pela qual você precisa inverter o kernel tem a ver com as propriedades matemáticas da operação de convolução (consulte o link para obter uma explicação mais aprofundada sobre convolução). Simplificando: se você não inverter o kernel, o resultado da operação de convolução será invertido. Ao virar o kernel, você obtém o resultado correto.
Aqui está o melhor artigo que li sobre o tema: Desfoque Gaussiano eficiente com amostragem linear . Ele aborda todas as suas perguntas e é realmente acessível.
Para o leigo, uma explicação muito curta: Gaussiana é uma função com a bela propriedade de ser separável, o que significa que uma função Gaussiana 2D pode ser calculada combinando duas funções Gaussianas 1D.
fonte
Em geral, uma convolução é realizada tomando-se a integral do produto de duas funções em uma janela deslizante, mas se você não é do fundo da matemática, essa não é uma explicação muito útil e certamente não lhe dará uma intuição útil por isso. Mais intuitivamente, uma convolução permite que vários pontos em um sinal de entrada afetem um único ponto em um sinal de saída.
Como você não está muito confortável com as convoluções, vamos primeiro revisar o que significa uma convolução em um contexto discreto como esse e, em seguida, analisar um borrão mais simples.
Em nosso contexto discreto, podemos multiplicar nossos dois sinais simplesmente multiplicando cada amostra correspondente. A integral também é simples de fazer de forma discreta, apenas adicionamos cada amostra no intervalo em que estamos integrando. Uma convolução simples e discreta é calcular uma média móvel. Se você deseja obter a média móvel de 10 amostras, isso pode convencer seu sinal por uma distribuição com 10 amostras e 0,1 de altura, cada amostra na janela primeiro é multiplicada por 0,1 e todas as 10 são adicionadas para produzir a média. Isso também revela uma distinção interessante e importante, quando você está desfocando com uma convolução, a distribuição que você usa deve somar 1,0 em todas as suas amostras; caso contrário, aumentará ou diminuirá o brilho geral da imagem quando você a aplicar.
Agora que analisamos as convoluções, podemos passar para os borrões. Um desfoque gaussiano é implementado mediante a convolução de uma imagem por uma distribuição gaussiana. Outros borrões são geralmente implementados pela convolução da imagem por outras distribuições. O desfoque mais simples é o desfoque de caixa e usa a mesma distribuição que descrevemos acima, uma caixa com área de unidade. Se quisermos desfocar uma área de 10x10, multiplicamos cada amostra na caixa por 0,01 e, em seguida, somamos todas elas para produzir o pixel central. Ainda precisamos garantir que a soma total de todas as amostras em nossa distribuição de desfoque seja 1,0 para garantir que a imagem não fique mais clara ou mais escura.
r
fonte
Mas há mais dois truques que você pode considerar em uma implementação real:
O filtro tem um certo raio e, por isso, nas bordas, você precisará calcular com pixels que ficam fora da imagem. Nesse caso, você pode tentar um dos seguintes procedimentos: para os pixels externos, você simplesmente pega o último valor possível (ou seja, o pixel na borda, como em
max(x, 0)
.) Ou pode "refletir" a imagem para fora (como emx < 0 ? -x : x
). Ou você pode simplesmente parar na fronteira, mas precisará ajustar o denominador no filtro de convolução para que ele totalize 1. Por exemplo:fonte