Come posso filtrare passa-basso riducendo solo i dati di picco?


16

Ho un'immagine 2D, che voglio filtrare passa basso, con questi vincoli / metriche di qualità:

  1. Non posso "aggiungere" luce all'immagine, quindi ogni pixel nel risultato dovrebbe essere <= il pixel corrispondente nell'input.
  2. La frequenza di taglio passa basso dovrebbe essere un parametro, da sperimentare
  3. L'applicazione ripetuta di questo filtro non dovrebbe modificare il risultato in modo significativo.
  4. Il tempo necessario per eseguire questo algoritmo (5 minuti per un'immagine da 5 MPix sembrano ragionevoli)
  5. Ridurre al minimo la quantità di luce filtrata.

Di seguito sono riportati alcuni approcci che ho provato, insieme alle loro carenze:

  1. Filtro gaussiano come al solito, quindi abbassa il risultato per rispettare il vincolo 1. Ciò si adatta molto bene ai primi 3 punti, ma riduce molta più luce del necessario.

  2. Montare le parabole "verso l'alto" attraverso i punti "bassi" e le parabole "verso il basso" per uniformarle. Funziona alla grande in 1D, ma applicandolo prima in orizzontale, quindi in verticale produce cattivi risultati in 2D. Ci vuole molto più tempo, ma non troppo a lungo per la mia applicazione. Tuttavia, l'applicazione ripetuta di questo filtro cambierà drasticamente il risultato. Se l'ingresso (1D) è una parabola "verso il basso" perfetta (che non dovrebbe essere affatto filtrata), sarà sostituito da 2 parabole "verso l'alto" che si trovano all'inizio / alla fine.

  3. Utilizzando qualche altra forma di funzioni 2D "di base" e risoluzione lineare per trovare i parametri ottimali. Questa è un'idea solo attualmente, non ancora implementata / testata.

Il mio dominio di esperienza nell'elaborazione del segnale è quasi esclusivamente l'elaborazione di immagini, quindi spero di trovare alternative a questo problema con l'input di esperti attivi in ​​altre aree dell'elaborazione del segnale.

aggiornamento 2011/08/18

Sulla base delle reazioni attuali, ho deciso di rendere le cose un po 'più chiare aggiungendo grafici di un input tipico e i risultati dei 3 approcci che ho descritto originariamente + i suggerimenti che ho ricevuto finora. Per un facile confronto, ho usato solo il filtro 1D in questi esempi.

Dati in ingresso: Dati in ingresso

Filtro gaussiano + abbattilo per soddisfare il requisito (1).
Si può vedere che l'abbattimento comporta riduzioni della luce non necessarie sul lato destro. filtrato gaussiano

Parabole
Per quanto mi riguarda, questo è praticamente eccellente, purtroppo non si traduce perfettamente in 2D applicando prima orizzontale, poi verticale. In questo caso, vedi anche che posso valutare le parabole adattate nella risoluzione in virgola mobile, il che è un piccolo vantaggio, ma non assolutamente necessario. raccordo per parabola

Erosione della scala di grigi
Sulla base del suggerimento di rwong, ho provato l'erosione della scala di grigi. Ho usato un elemento strutturante con la stessa forma parabolica delle mie parabole "adattate". Il risultato è quasi esattamente lo stesso, quindi questo sembra promettente. Tuttavia, ci sono ancora alcuni problemi: 1. Il mio elemento strutturante non era "abbastanza grande" (sebbene fosse già largo 801 pixel) 1. Ho solo parabole "verso l'alto", nessuna "parabola verso il basso per facilitare la transizione da una parabola al prossimo. erosione in scala di grigi

Filtro mediano
Incluso solo per completezza, non è proprio quello che voglio. filtro mediano

dati grezzi
Ho incollato i dati grezzi di input + i vari comandi di Python su pastebin, in modo da poter sperimentare anche gli stessi dati.
http://pastebin.com/ASnJ9M0p


1
Puoi spiegare qualcosa in più sulle restrizioni 1 e 5? Sembrano essere (a prima vista) contraddittori.
Peter K.

Probabilmente sto fraintendendo cosa intendi con "questo algoritmo", ma 5 minuti per 5 MP sembrano molto per l'applicazione di un filtro passa-basso.
bjoernz,

Risposte:


8

Esiste davvero una versione 2D per il tuo tentativo n. 2 - è teoricamente simile, ma non può essere scomposta in due operazioni 1D. Leggi "Filtro morfologico in scala di grigi 2D". È più veloce dell'adattamento alla curva.

Il filtro mediano potrebbe anche essere utile se stai cercando di rimuovere le macchioline. Una forma più avanzata di filtro mediano è il "filtro ordinale".

In tutti i casi, il requisito n. 1 può essere soddisfatto in modo banale prendendo il minimo pixel per pixel tra l'output e l'input. È un criterio di qualità importante, ma non limita la scelta degli algoritmi.


Il filtro gaussiano (e una serie di altri filtri utili) può essere decomposto (prima dalle operazioni 2D a 1D, quindi tramite trasformata di Fourier), ma ci sono molte altre utili tecniche di elaborazione delle immagini che non sono scomponibili, che le rendono lente ma non diminuiscono la loro utilità.


Ciao, grazie per il puntatore al filtro morfologico in scala di grigi. La descrizione su Wikipedia sembra interessante e la analizzerò. Tuttavia, nel tuo link alla documentazione di OpenCV, vedo solo normali filtri morfologici, non quelli in scala di grigi. Sicuramente selezionerò questa opzione e ti farò sapere i risultati. Grazie.
Pieter-Jan Busschaert,

6
Il suggerimento di rwong di filtraggio mediano aiuta a tutti? Spiegare un po 'di più su ciò che stai cercando di ottenere presentando un semplice esempio dei dati e un esempio "falso" di ciò che vuoi ottenere potrebbe aiutare.
Peter K.

Ho aggiornato la mia domanda con dati di esempio + risultati di vari suggerimenti. Spero che le cose siano più chiare ora.
Pieter-Jan Busschaert,

2

Suggerisco di usare una spline levigante.

Ecco come puoi farlo usando Matlab con la robusta funzione di spline SMOOTHN di Matlab File Exchange (che contiene il codice sorgente completo, in modo da poterlo implementare altrove se necessario). Nota che funziona anche con dati n-dimensionali:

%# - 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')

inserisci qui la descrizione dell'immagine


Grazie per il tuo suggerimento, lo esaminerò. Dal tuo grafico, mi sembra che abbia bisogno di un fattore di livellamento molto più alto del tuo esempio. Il bordo ripido intorno a x = 700 non viene rimosso e sarà chiaramente visibile. Anche il bump iniziale in x = [0, 400] non viene rimosso affatto. Non pensi che questo avrà lo stesso problema di qualsiasi altro approccio (filtro passa-basso + sposta in basso)? Puoi vedere l'offset globale tra i due grafici, che probabilmente aumenterà anche quando uso un smoothingFactor più alto.
Pieter-Jan Busschaert,

@ Pieter-JanBusschaert: Oh, pensavo che il primo picco ti fosse stato in qualche modo utile. Ad ogni modo, tutti i filtri passa-basso + spostamento verso il basso avranno difficoltà con il forte rialzo a ~ 650: renderanno questa parte più piatta e quindi la curva dovrà essere spostata molto verso il basso. Il filtro mediano seguito da una spline levigante aiuta un po '.
Jonas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.