Como posso filtrar o passa-baixo, reduzindo apenas os dados de pico?

16

Eu tenho uma imagem 2D, que eu quero filtro lowpass, com essas restrições / métricas de qualidade:

  1. Como não posso "adicionar" luz à imagem, cada pixel no resultado deve ser <= o pixel correspondente na entrada.
  2. A frequência de corte lowpass deve ser um parâmetro, para experimentar
  3. A aplicação repetida desse filtro não deve alterar o resultado de maneira significativa.
  4. O tempo necessário para executar esse algoritmo (5 minutos para uma imagem de 5 MPix parece razoável)
  5. Minimizar a quantidade de luz que é filtrada.

Abaixo estão algumas abordagens que tentei, juntamente com suas deficiências:

  1. Filtro Gaussiano como o normal, puxe o resultado para baixo para cumprir a restrição 1. Isso está de acordo muito bem com os três primeiros pontos, mas reduz muito mais a luz do que o necessário.

  2. Ajustar parábolas "para cima" através dos pontos "baixos" e parábolas "para baixo" entre eles para suavizar. Isso funciona muito bem em 1D, mas aplicá-lo primeiro na horizontal e depois na vertical produz maus resultados em 2D. Leva muito mais tempo, mas não muito para o meu aplicativo. No entanto, a aplicação repetida desse filtro alterará drasticamente o resultado. Se a entrada (1D) for uma parábola "descendente" perfeita (que não deve ser filtrada), ela será substituída por 2 parábolas "ascendentes" sentadas no início / fim.

  3. Usando alguma outra forma de funções "básicas" 2D e solução linear para encontrar os parâmetros ideais. Esta é uma ideia apenas atualmente, ainda não implementada / testada.

Meu domínio de experiência no processamento de sinais é quase exclusivamente processamento de imagens, por isso espero encontrar alternativas para esse problema com a participação de especialistas ativos em outras áreas do processamento de sinais.

update 18/08/2011

Com base nas reações atuais, decidi deixar as coisas um pouco mais claras adicionando gráficos de uma entrada típica e os resultados das três abordagens que descrevi originalmente + as sugestões que recebi até agora. Para facilitar a comparação, usei apenas a filtragem 1D nesses exemplos.

Dados de entrada: Dados de entrada

Filtro Gaussiano + reduza-o para atender ao requisito (1).
Você pode ver que derrubá-lo resulta em reduções desnecessárias de luz no lado direito. gaussiano filtrado

Parábolas Para
mim, isso é excelente, mas infelizmente não se traduz perfeitamente em 2D, aplicando primeiro a horizontal e depois a vertical. Nesse caso, você também vê que posso avaliar as parábolas ajustadas na resolução de ponto flutuante, o que é um pequeno benefício, mas não é absolutamente necessário. montagem de parábola

Erosão da escala de cinza
Com base na sugestão de rwong, tentei a erosão da escala de cinza. Eu usei um elemento estruturador com a mesma forma parabólica que minhas parábolas "ajustadas". O resultado é quase exatamente o mesmo, então isso parece promissor. No entanto, ainda existem alguns problemas: 1. Meu elemento estruturador não era "suficientemente grande" (embora já tivesse 801 pixels de largura) 1. Só tenho parábolas "para cima", sem parábolas para baixo para facilitar a transição de uma parábola para o próximo. erosão em escala de cinza

Filtragem mediana
Somente incluída para ser completa, não é exatamente o que eu quero. filtro mediano

dados brutos
Colei os dados de entrada brutos + os vários comandos python no pastebin, para que você também possa experimentar os mesmos dados.
http://pastebin.com/ASnJ9M0p

Pieter-Jan Busschaert
fonte
1
Você pode explicar um pouco mais sobre as restrições 1 e 5? Eles parecem ser (à primeira vista) contraditórios.
Peter K.
Provavelmente estou entendendo mal o que você quer dizer com "esse algoritmo", mas 5 minutos para 5 MP parecem muito para a aplicação de um filtro passa-baixo.
bjoernz

Respostas:

8

De fato, existe uma versão 2D para sua tentativa nº 2 - é semelhante em teoria, mas não pode ser decomposta em duas operações 1D. Por favor, leia sobre "Filtragem morfológica em escala de cinza 2D". É mais rápido que o ajuste da curva.

A filtragem mediana também pode ser útil se você estiver tentando remover manchas. Uma forma mais avançada de filtragem mediana é a "filtragem ordinal".

Em todos os casos, o requisito nº 1 pode ser cumprido trivialmente, utilizando o mínimo de pixel entre a saída e a entrada. É um critério de qualidade importante, mas não limitará a escolha dos algoritmos.


A filtragem gaussiana (e vários outros filtros úteis) podem ser decompostos (primeiro das operações 2D para 1D, depois via transformada de Fourier), mas existem muitas outras técnicas úteis de processamento de imagem que não são decomponíveis, o que as torna lentas, mas não diminuem. sua utilidade.

rwong
fonte
Olá, obrigado pelo ponteiro para a filtragem morfológica em escala de cinza. A descrição na wikipedia parece interessante e vou investigar isso. No entanto, no seu link para a documentação do OpenCV, só vejo filtros morfológicos normais, não filtros em escala de cinza. Definitivamente irei verificar esta opção e informar os resultados. Obrigado.
Pieter-Jan Busschaert 17/08/11
6
A sugestão de rwong de filtragem mediana ajuda em tudo? Explicar um pouco mais sobre o que você está tentando alcançar apresentando um exemplo simples dos dados e um exemplo "falso" do que você deseja divulgar pode ajudar.
Peter K.
Atualizei minha pergunta com dados de amostra + resultados de várias sugestões. Espero que as coisas estejam mais claras agora.
Pieter-Jan Busschaert
2

Sugiro usar um spline de suavização.

Veja como você pode fazer isso usando o Matlab com a robusta função de suavização de spline SMOOTHN do Matlab File Exchange (que contém o código fonte completo, para que você possa reimplementá-lo em outro lugar, se necessário). Observe que ele também funciona com dados n-dimensionais:

%# - get inputlist from pastebin

%# - smoothen data. Lower factor means less smooth
smoothingFactor = 1000;
smoothData = smoothn(inputlist,smoothingFactor);

%# - shift down
smoothData = smoothData - max(inputlist-smoothData);

%# - show results
plot(inputlist,'b'),hold on,plot(smoothData,'r')

insira a descrição da imagem aqui

Jonas
fonte
Obrigado pela sua sugestão, vou investigar. Pelo seu gráfico, parece que eu preciso de um fator de suavização muito maior do que o seu exemplo. A aresta íngreme em torno de x = 700 não é removida e será claramente visível. Além disso, o aumento inicial em x = [0, 400] não é removido. Você não acha que isso terá o mesmo problema que qualquer outra abordagem (filtro passa-baixo + movimento para baixo)? Você pode ver o deslocamento global entre os dois gráficos, o que provavelmente aumentará mesmo quando eu usar um fator de suavização mais alto.
Pieter-Jan Busschaert 2/11
@ Pieter-JanBusschaert: Ah, eu pensei que o primeiro pico era de alguma forma útil para você. De qualquer forma, todo o filtro passa-baixo + o movimento para baixo terá dificuldades com a subida acentuada em ~ 650: eles tornarão essa parte mais plana e, portanto, a curva deverá ser movida muito para baixo. O filtro mediano seguido de um spline de suavização ajuda um pouco.
Jonas