Pergunta

Eu escrevo meu próprio filtro Gaussian, mas é muito lento.

algoritmo Gaussian da OpenCV é muito mais rápido, 20 vezes do meu filtro de Gauss. Eu quero reescrever algoritmo Gaussian da OpenCV no meu projeto, e eu não quero incluir opencv no meu projeto.

No entanto,

Alguém pode me dar a descrição do algoritmo, o código fonte do opencv parece muito difícil de entender?

Foi útil?

Solução

O filtro Gaussian tem uma propriedade que torna muito fácil para acelerar: o filtro pode ser aplicado em ambas as dimensões de forma independente. É possível definir um filtro unidimensional que opera verticalmente, e um outro que opera na horizontal, e aplicá-los a ambos; isto produz o mesmo efeito que um único filtro aplicado em duas dimensões.

Além disso, você provavelmente vai precisar de olhar para os SIMD por exemplo SSE3 disponível para o seu processador.

Outras dicas

Para responder à segunda parte da sua pergunta, um borrão Gaussian é simplesmente uma superfície gaussiana o 3-d aplicado como um kernel de convolução sobre a imagem. Wikipedia tem uma grande referência no próprio algoritmo, mas basicamente, você toma os valores de um Gaussian curva e convertê-lo em uma matriz quadrada, e multiplicá-lo por cada pixel em sua imagem, por exemplo:

Kernel:               
[0 1 2 0 0
1 4 6 4 1      X   Iterate over every single pixel in the image
2 6 10 6 2
1 4 6 4 1
0 1 2 1 0]

(Note-se que este é apenas um kernel amostra, há eqns muito específicas que, dependendo de suas variáveis ??Gaussian, você vai obter resultados diferentes)

Para responder à parte do desempenho da sua pergunta, a velocidade total deste algoritmo vai depender de algumas coisas, assumindo uma imagem de tamanho constante. Vamos dizer que a imagem é nxm pixels, eo kernel de convolução é PXP pixels. Você vai ter que fazer P P operações N * m. O maior P, as operações mais você vai ter que fazer por uma determinada imagem. Você pode obter astuto com o algoritmo que você usa aqui, fazendo fila muito específico ou de matemática com base em colunas.

A implementação também é muito importante. Se você quer ser extremamente eficiente, você provavelmente vai querer usar as instruções mais avançadas que sua arquitetura de ofertas. Se você estiver usando um chip Intel x86, você provavelmente vai querer olhar para obter uma licença para primitivas de desempenho Intel (IPP) e chamando essas instruções diretamente. IIRC, OpenCV faz uso de IPP quando seu disponível ...

Você também poderia fazer algo muito inteligente e trabalhar com todos os inteiros escalados se o desempenho de ponto flutuante no seu determinada arquitetura é pobre. Este seria provavelmente a acelerar as coisas um pouco, mas eu gostaria de olhar para outras opções primeiro antes de ir por este caminho.

Tente verificar aqui . Você quer descobrir a frente matriz gaussiano limitado de tempo, então convolve-lo com a imagem.

Se o seu kernel de convolução é relativamente grande e que está a implementar convolução direta, a diferença de desempenho pode ser porque OpenCV está a implementar convolução usando uma transformação rápida de Fourier (FFT).

Eu odeio ser pedante, mas você está pedindo um algoritmo, isto é, uma sequência precisa de passos necessários para realizar uma tarefa. Você já tem o algoritmo de Gauss. Então, o ponto-chave da sua pergunta é quando você pedir algo mais rápido , o que não é o mesmo que pedir um algoritmo.

Para responder à mais rápido questão - você quer saber como OpenCV otimiza seu código, que é um assunto altamente técnico e amplo. Eu arriscaria um palpite, dizendo que ele usa linguagem assembly, e funções específicas do GPU. Eu começaria por aprender montagem, e pesquisando o pacote CUDA para tirar proveito de sua GPU.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top