Sei que essa pergunta pode não ser muito relevante para a programação, mas se não entender a teoria por trás do processamento de imagens, nunca poderei implementar algo na prática.
Se eu entendi direito, os filtros gaussianos são convoluídos com uma imagem para redução de ruído, pois calculam uma média ponderada da vizinhança de um pixel e são muito úteis na detecção de bordas, já que você pode aplicar um desfoque e derivar a imagem ao mesmo tempo, simplesmente convolvendo com a derivada de uma função gaussiana.
Mas alguém pode me explicar ou me dar algumas referências sobre como eles são computados?
Por exemplo, o detector de bordas de Canny fala sobre um filtro Gaussiano 5x5, mas como eles conseguiram esses números específicos? E como eles passaram de uma convolução contínua para uma multiplicação de Matrix?
Respostas:
Para que esta operação funcione, é necessário imaginar que sua imagem seja remodelada como um vetor. Então, esse vetor é multiplicado à esquerda pela matriz de convolução para obter a imagem borrada. Observe que o resultado também é um vetor do mesmo tamanho da entrada, ou seja, uma imagem do mesmo tamanho.
Cada linha da matriz de convolução corresponde a um pixel na imagem de entrada. Ele contém o peso das contribuições de todos os outros pixels da imagem para a contrapartida desfocada do pixel considerado.
Vamos dar um exemplo: desfoque de caixa de tamanho pixels em uma imagem de tamanho 6 × 6 pixels. A imagem remodelada é uma coluna de 36 eleitos, enquanto a matriz de desfoque tem tamanho 36 × 36 .3×3 6×6 36×36
Uma ilustração visual de um processo intimamente relacionado (convolução + subtração) pode ser encontrada nesta postagem do blog (do meu blog pessoal).
fonte
Para aplicativos em imagens ou redes de convolução, para usar com mais eficiência os multiplicadores de matriz em GPUs modernas, as entradas geralmente são remodeladas em colunas de uma matriz de ativação que podem ser multiplicadas com vários filtros / kernels de uma só vez.
Confira este link no CS231n de Stanford e role para baixo até a seção "Implementação como multiplicação de matrizes" para obter detalhes.
O processo funciona pegando todos os patches locais em uma imagem de entrada ou mapa de ativação, aqueles que seriam multiplicados com o kernel e estendendo-os para uma coluna de uma nova matriz X através de uma operação comumente chamada im2col. Os núcleos também são esticados para preencher as linhas de uma matriz de peso W, de modo que, ao executar a operação de matriz W * X, a matriz resultante Y tenha todos os resultados da convolução. Finalmente, a matriz Y deve ser remodelada novamente, convertendo as colunas novamente em imagens por uma operação normalmente chamada cal2im.
fonte
Convolução no domínio do tempo é igual à multiplicação da matriz no domínio da frequência e vice-versa.
A filtragem é equivalente a convolução no domínio do tempo e, portanto, multiplicação da matriz no domínio da frequência.
Quanto aos mapas ou máscaras 5x5, eles provêm da discretização dos operadores espertos / sóbrios.
fonte
Eu escrevi uma função que resolve isso no meu repositório StackOverflow Q2080835 GitHub (Dê uma olhada
CreateImageConvMtx()
).Na verdade, a função pode suportar qualquer formato de convolução que você queira -
full
,same
evalid
.O código é o seguinte:
Também criei uma função para criar uma matriz para filtragem de imagens (ideias semelhantes às do MATLAB
imfilter()
):O código foi validado no MATLAB
imfilter()
.O código completo está disponível no meu repositório do StackOverflow Q2080835 GitHub .
fonte