Skip to content Skip to navigation

OpenStax_CNX

You are here: Home » Content » Signal Processing in Processing: Filtri Elementari

Navigation

Recently Viewed

This feature requires Javascript to be enabled.
 

Signal Processing in Processing: Filtri Elementari

Module by: Davide Rocchesso, Pietro Polotti. E-mail the authors

Summary: Si illustrano i filtri fondamentali per i segnali 1D e 2D e si forniscono esempi in Processing.

Filtri FIR

Si chiamano filtri Finite Impulse Response (FIR) tutti i filtri caratterizzati da una risposta all'impulso con un numero finito di campioni. Essi si realizzano mediante l'operazione di convoluzione. Cioè, per ogni campione di uscita prodotto viene calcolata una somma pesata di un numero finito di campioni dell'ingresso.

Filtro di media

Il più semplice filtro FIR non banale è il filtro che effettua la media di due campioni contigui, la cui convoluzione si può esprimere come

yn=0.5xn+0.5xn1 y n 0.5 x n 0.5 x n 1
(1)
e quindi la risposta all'impulso ha valore 0.5 0.5 negli istanti 0 0 e 1 1, e valore nullo altrove.

Immettendo un segnale sinusoidale nel filtro, l'uscita sarà ancora un segnale sinusoidale scalato in ampiezza e ritardato in fase secondo quanto prescritto dalla risposta in frequenza , che risulta essere

Hω=cosω2e(iω2) H ω ω 2 ω 2
(2)
il cui modulo e fase sono rappresentati in Figura 1.

Figura 1
Risposta di ampiezza e di fase per il filtro di media
Risposta di ampiezza e di fase per il filtro di media (fir1.png)

Quello appena presentato è un filtro del primo ordine (e di lunghezza 2 2), in quanto utilizza un solo campione del passato della sequenza di ingresso. Da Figura 1 si vede che la risposta in frequenza è di tipo passa-basso, cioè che le alte frequenze sono attenuate rispetto alle basse frequenze. Attenuare le alte frequenze significa smussare le variazioni repentine del segnale, rendendolo così più liscio. Se si vuole una risposta in frequenza più ripida da un filtro FIR bisogna aumentare l'ordine, cioè aumentare il numero di campioni del segnale di ingresso che vengono elaborati.

Filtro FIR del secondo ordine simmetrico

Un filtro FIR del secondo ordine simmetrico ha risposta all'impulso della forma a 0 a 1 a 0 a 0 a 1 a 0 , e la risposta in frequenza risulta essere Hω=( a 1 +2 a 0 cosω)e(iω) H ω a 1 2 a 0 ω ω . La convoluzione si può esprimere come

yn= a 0 xn+ a 1 xn1+ a 0 xn2 y n a 0 x n a 1 x n 1 a 0 x n 2
(3)
Nel caso particolare in cui a 0 =0.17654 a 0 0.17654 e a 1 =0.64693 a 1 0.64693 la risposta in frequenza (modulo e fase) è rappresentata in Figura 2.

Figura 2
Risposta di ampiezza e di fase per un filtro FIR del secondo ordine
Risposta di ampiezza e di fase per un filtro FIR del secondo ordine
	   (fir2.png)

Filtri passa-alto

Per i semplici filtri passa-basso appena visti, è sufficiente cambiare il segno di un coefficiente per ottenere una risposta di tipo passa-alto, cioè una enfatizzazione delle alte frequenze rispetto alle basse frequenze. Ad esempio, la Figura 3 riporta il modulo delle risposte in frequenza di filtri FIR passa-alto rispettivamente del primo e del secondo ordine, le cui risposte all'impulso sono, rispettivamente 0.50.5 0.5 0.5 e 0.176540.646930.17654 0.17654 0.64693 0.17654 .

Figura 3
Risposta di ampiezza per un filtro FIR passa-alto del primo (sinistra) e del secondo (destra) ordine.
(a) (b)
Figura 3(a) (fir1hp2.png)Figura 3(b) (fir2hp2.png)

Enfatizzare le alte frequenze significa rendere più evidenti le variazioni repentine del segnale, siano esse transienti nel caso dei suoni, o contorni nel caso delle immagini.

Filtri FIR in 2D

In 2D, la risposta all'impulso di un filtro FIR è una maschera di convoluzione con un numero finito di elementi, cioè una matrice. In particolare, il filtro di media si può rappresentare mediante la maschera di convoluzione 19( 111 111 111 ) 1 9 1 1 1 1 1 1 1 1 1 .

Esempio 1: Noise cleaning

I filtri passa-basso (e quindi, in particolare, i filtri di media) operano uno smoothing del segnale di ingresso, cioè smussano le discontinuità producendo un segnale dal profilo più dolce. Ciò può servire a ridurre la percettibilità di un rumore sovrapposto a un segnale audio o ad una immagine. Ad esempio, il codice sotto riportato carica una immagine, la corrompe con rumore bianco, e quindi ne sottopone metà ad un filtraggio di media, ottenendo Figura 4.

Figura 4
Smoothing
Smoothing (vetroRottoSporco.gif)

// smoothed_glass
// smoothing filter, adapted from REAS:
// http://processing.org/learning/topics/blur.html

size(210, 170); 
PImage a;  // Declare variable "a" of type PImage 
a = loadImage("vetro.jpg"); // Load the images into the program 
image(a, 0, 0); // Displays the image from point (0,0) 
 
// corrupt the central strip of the image with random noise 
float noiseAmp = 0.2;
loadPixels(); 
for(int i=0; i<height; i++) { 
  for(int j=width/4; j<width*3/4; j++) { 
    int rdm = constrain((int)(noiseAmp*random(-255, 255) + 
	      red(pixels[i*width + j])), 0, 255); 
    pixels[i*width + j] = color(rdm, rdm, rdm);
  } 
} 
updatePixels(); 
  
int n2 = 3/2; 
int m2 = 3/2; 
float  val = 1.0/9.0;
int[][] output = new int[width][height]; 
float[][] kernel = { {val, val, val}, 
                     {val, val, val}, 
                     {val, val, val} }; 
  
// Convolve the image 
for(int y=0; y<height; y++) { 
  for(int x=0; x<width/2; x++) { 
    float sum = 0; 
    for(int k=-n2; k<=n2; k++) { 
      for(int j=-m2; j<=m2; j++) { 
        // Reflect x-j to not exceed array boundary 
        int xp = x-j; 
        int yp = y-k; 
        if (xp < 0) { 
          xp = xp + width; 
        } else if (x-j >= width) { 
          xp = xp - width; 
        } 
        // Reflect y-k to not exceed array boundary 
        if (yp < 0) { 
          yp = yp + height; 
        } else if (yp >= height) { 
          yp = yp - height; 
        } 
        sum = sum + kernel[j+m2][k+n2] * red(get(xp, yp)); 
      } 
    } 
    output[x][y] = int(sum);  
  } 
} 
 
// Display the result of the convolution 
// by copying new data into the pixel buffer 
loadPixels(); 
for(int i=0; i<height; i++) { 
  for(int j=0; j<width/2; j++) { 
    pixels[i*width + j] = 
	      color(output[j][i], output[j][i], output[j][i]);
  } 
} 
updatePixels(); 
         
	

A scopo di smoothing, viene molto usata una maschera di convoluzione i cui valori sono letti da una campana gaussiana in due variabili. Una proprietà delle funzioni gaussiane è che la loro trasformata di Fourier è essa stessa gaussiana e, quindi, risposta all'impulso e risposta in frequenza hanno la stessa forma. Tuttavia, la trasformata di una campana stretta sarà una campana larga, e viceversa. Più è larga la campana e più accentuato sarà l'effetto di smoothing, con conseguente perdita di dettagli. In termini visuali, un filtraggio gaussiano è assimilabile alla presenza di un vetro opalino davanti all'immagine. Un esempio di maschera gaussiana è 1273( 14741 41626164 72641267 41626164 14741 ) 1 273 1 4 7 4 1 4 16 26 16 4 7 26 41 26 7 4 16 26 16 4 1 4 7 4 1 .

Se invece si vogliono rendere più evidenti i contorni e i tratti salienti (edge crispening o sharpening) di una immagine bisogna effettuare un filtraggio di tipo passa-alto. In modo analogo a quanto visto in Sezione 4 ciò si può fare con una maschera di convoluzione il cui valore centrale ha segno opposto rispetto ai valori di cui si circonda. Ad esempio, la maschera di convoluzione ( -1-1-1 -19-1 -1-1-1 ) -1 -1 -1 -1 9 -1 -1 -1 -1 produce l'effetto di Figura 5.

Figura 5
Edge crispening
Edge crispening (vetroSharpened.gif)

Filtraggio non lineare: filtro di mediana

Un filtro in cui la maschera di convoluzione dipende dal segnale perde le caratteristiche di linearità. I filtri di mediana usano la maschera per selezionare un insieme di pixel della immagine di ingresso, e sostituiscono il pixel centrale individuato dalla maschera con il valore mediano dell'insieme. Dato una insieme di N N (dispari) numeri, l'elemento mediano dell'insieme è quello che individua N12 N 1 2 elementi più piccoli di sè, e N12 N 1 2 elementi più grandi. Una tipica maschera per filtro mediano ha la forma di croce. Ad esempio, una maschera a croce 3×3 3 3 può individuare, quando applicata in un certo punto di una certa immagine, i pixel di valore ( x4x 79912 x9x ) x 4 x 7 99 12 x 9 x , e quindi sostituire al valore 99 99 il valore mediano 9 9.

Exercise 1

Si riscriva l'operazione di filtraggio filtra() del Sound Chooser presentato nel modulo Media Representation in Processing in modo che realizzi il filtro FIR la cui risposta in frequenza è rappresentata in Figura 2. Cosa succede se il filtro viene applicato più volte?

Solution


          
 //filtra = new function
void filtra(float[] DATAF, float[] DATA, float a0, float a1) {

  for(int i = 3; i < DATA.length; i++){
    DATAF[i] = a0*DATA[i]+a1*DATA[i-1]+a0*DATA[i-2];//filtraggio FIR del secondo ordine simmetrico
  }
}
 
 	      
	    

Creando un ciclo for che reiteri l'operazione di filtraggio un certo numero di volte, si può verificare che l'effetto del filtraggio passa-basso viene accentuato. Questo risultato abbastanza intuitivo corrisponde al fatto che un filtraggio successivo attraverso m m filtri di ordine N N (nel nostro caso N=2 N 2 ) è equivalente ad un filtraggio attraverso un filtro di ordine mN m N

Exercise 2

Considerato il codice Processing dell'esempio di blurring contenuto tra gli esempi di Processing, lo si modifichi in modo da effettuare un filtraggio gaussiano.

Solution

// smoothing Gaussian filter, adapted from REAS:
// http://processing.org/learning/topics/blur.html

size(200, 200); 
PImage a;  // Declare variable "a" of type PImage 
a = loadImage("vetro.jpg"); // Load the images into the program 
image(a, 0, 0); // Displays the image from point (0,0) 
 
int n2 = 5/2; 
int m2 = 5/2; 
int[][] output = new int[width][height]; 
float[][] kernel = { {1, 4, 7, 4, 1}, 
                     {4, 16, 26, 16, 4}, 
                     {7, 26, 41, 26, 7}, 
                     {4, 16, 26, 16, 4},
                     {1, 4, 7, 4, 1} }; 
 
for (int i=0; i<5; i++)
  for (int j=0; j< 5; j++)
    kernel[i][j] = kernel[i][j]/273; 
// Convolve the image 
for(int y=0; y<height; y++) { 
  for(int x=0; x<width/2; x++) { 
    float sum = 0; 
    for(int k=-n2; k<=n2; k++) { 
      for(int j=-m2; j<=m2; j++) { 
        // Reflect x-j to not exceed array boundary 
        int xp = x-j; 
        int yp = y-k; 
        if (xp < 0) { 
          xp = xp + width; 
        } else if (x-j >= width) { 
          xp = xp - width; 
        } 
        // Reflect y-k to not exceed array boundary 
        if (yp < 0) { 
          yp = yp + height; 
        } else if (yp >= height) { 
          yp = yp - height; 
        } 
        sum = sum + kernel[j+m2][k+n2] * red(get(xp, yp)); 
      } 
    } 
    output[x][y] = int(sum);  
  } 
} 
 
// Display the result of the convolution 
// by copying new data into the pixel buffer 
loadPixels(); 
for(int i=0; i<height; i++) { 
  for(int j=0; j<width/2; j++) { 
    pixels[i*width + j] = color(output[j][i], output[j][i], output[j][i]); 
  } 
} 
updatePixels(); 
 	      
	    

Exercise 3

Si modifichi il codice di Esempio 1 in modo da confrontare la maschera di convoluzione del filtro di media con la 110( 111 121 111 ) 1 10 1 1 1 1 2 1 1 1 1 . Cosa succede se si aumenta ancora il valore del punto centrale della maschera di convoluzione? Si provi quindi a realizzare il filtro di mediana con una maschera a croce 3×3 3 3 .

Solution

Ecco il filtro di mediana:


          
// smoothed_glass
// smoothing filter, adapted from REAS:
// http://www.processing.org/learning/examples/blur.html

size(210, 170); 
PImage a;  // Declare variable "a" of type PImage 
a = loadImage("vetro.jpg"); // Load the images into the program 
image(a, 0, 0); // Displays the image from point (0,0) 
 
// corrupt the central strip of the image with random noise 
float noiseAmp = 0.1;
loadPixels(); 
for(int i=0; i<height; i++) { 
  for(int j=width/4; j<width*3/4; j++) { 
    int rdm = constrain((int)(noiseAmp*random(-255, 255) + 
      red(pixels[i*width + j])), 0, 255); 
    pixels[i*width + j] = color(rdm, rdm, rdm);
  } 
} 
updatePixels(); 
  
int[][] output = new int[width][height]; 
int[] sortedValues = {0, 0, 0, 0, 0};
int grayVal;
  
// Convolve the image 
for(int y=0; y<height; y++) { 
  for(int x=0; x<width/2; x++) { 
    int indSort = 0;
    for(int k=-1; k<=1; k++) { 
      for(int j=-1; j<=1; j++) { 
        // Reflect x-j to not exceed array boundary 
        int xp = x-j; 
        int yp = y-k; 
        if (xp < 0) { 
          xp = xp + width; 
        } else if (x-j >= width) { 
          xp = xp - width;  
        } 
        // Reflect y-k to not exceed array boundary 
        if (yp < 0) { 
          yp = yp + height; 
        } else if (yp >= height) { 
          yp = yp - height; 
        } 
        if ((((k != j) && (k != (-j))) ) || (k == 0)) { //cross selection
          grayVal = (int)red(get(xp, yp)); 
          indSort = 0;
          while (grayVal < sortedValues[indSort]) {indSort++; }          
          for (int i=4; i>indSort; i--) sortedValues[i] = sortedValues[i-1];
          sortedValues[indSort] = grayVal;
        } 
      } 
    } 
    output[x][y] = int(sortedValues[2]);  
    for (int i=0; i< 5; i++) sortedValues[i] = 0;
  } 
} 
 
// Display the result of the convolution 
// by copying new data into the pixel buffer 
loadPixels(); 
for(int i=0; i<height; i++) { 
  for(int j=0; j<width/2; j++) { 
    pixels[i*width + j] = 
      color(output[j][i], output[j][i], output[j][i]);
  } 
} 
updatePixels(); 
          

Filtri IIR

L'operazione di filtraggio rappresentata dalla Equazione 1 è un caso particolare di equazione alle differenze, in cui un campione dell'uscita è funzione soltanto di campioni dell'ingresso. Più in generale, è possibile costruire equazioni alle differenze di tipo ricorsivo, in cui un campione dell'uscita è funzione di un altro campione dell'uscita stessa. Ad esempio, l'equazione alle differenze

yn=0.5yn1+0.5xn y n 0.5 y n 1 0.5 x n
(4)
consente di calcolare in maniera causale ogni campione dell'uscita conoscendo soltanto l'uscita all'istante precedente e l'ingresso allo stesso istante. E' facile rendersi conto che immettendo un impulso nel sistema rappresentato dalla Equazione 4 si ottiene la sequenza di lunghezza infinita y=0.50.250.1250.0625... y 0.5 0.25 0.125 0.0625 ... . Per questo, filtri di questo tipo si chiamano Infinite Impulse Response (IIR). L'ordine di un filtro IIR è pari al numero di campioni passati dell'uscita che esso deve memorizzare per l'uso nella sua equazione alle differenze. Quindi, quello di Equazione 4 è un filtro del primo ordine. A parità di ordine, i filtri IIR consentono risposte in frequenza più ripide di quelle dei filtri FIR, ma introducono sempre delle distorsioni di fase, cioè ritardano le componenti spettrali in maniera dipendente dalla frequenza. Ad esempio, Figura 6 riporta le risposte di ampiezza e fase per il filtro IIR del primo ordine rappresentato dalla equazione alle differenze Equazione 4.Detto a a il coefficiente che pesa la dipendenza dal valore precedente dell'uscita ( 0.5 0.5 nella specifica Equazione 4), la risposta all'impulso è del tipo hn=an h n a n . Quanto più a a si avvicina a 1 1, tanto più la risposta all'impulso si mantiene sostenuta nel tempo e la risposta in frequenza aumenta la sua ripidità, accentuando così il carattere passa-basso del filtro. Naturalmente, valori di a a maggiori di 1 1 provocano una risposta all'impulso divergente, e quindi un comportamento instabile del filtro.

Figura 6
Risposta di ampiezza e di fase per il filtro IIR del primo ordine
Risposta di ampiezza e di fase per il filtro IIR del
	  primo ordine (iir1resp.png)

I filtri IIR trovano soprattutto applicazione nei segnali monodimensionali, quali sono i segnali audio, in particolare per l'elaborazione in tempo reale, campione per campione. Viceversa, non ha molto senso estendere l'elaborazione ricorsiva su due dimensioni, e quindi per le immagini si usano soprattutto filtri FIR.

Filtro risonante

In campo audio assumono particolare importanza i filtri IIR del secondo ordine in quanto consentono di realizzare un risonatore elementare. Data l'equazione alle differenze

yn= a 1 yn1+ a 2 yn2+ b 0 xn y n a 1 y n 1 a 2 y n 2 b 0 x n
(5)
si può vedere che essa produce la risposta in frequenza di Figura 7. I coefficienti di dipendenza dal passato dell'uscita si possono anche esprimere come a 1 =2rcos ω 0 a 1 2 r ω 0 e a 2 =r2 a 2 r 2 , dove ω 0 ω 0 è la frequenza del picco di risonanza e r r produce picchi tanto più stretti quanto più è vicino a 1 1.

Figura 7
Risposta di ampiezza e di fase per il filtro IIR del secondo ordine
Risposta di ampiezza e di fase per il filtro IIR del
	  secondo ordine (iir2.png)

Exercise 4

Si verifichi che l'operazione di filtraggio filtra() del Sound Chooser presentato nel modulo Media Representation in Processing realizza un filtro IIR risonante. Quale è la relazione realizzata tra r r e la posizione del mouse lungo le barrette?

Content actions

Download module as:

PDF | EPUB (?)

What is an EPUB file?

EPUB is an electronic book format that can be read on a variety of mobile devices.

Downloading to a reading device

For detailed instructions on how to download this content's EPUB to your specific device, click the "(?)" link.

| More downloads ...

Add module to:

My Favorites (?)

'My Favorites' is a special kind of lens which you can use to bookmark modules and collections. 'My Favorites' can only be seen by you, and collections saved in 'My Favorites' can remember the last module you were on. You need an account to use 'My Favorites'.

| A lens I own (?)

Definition of a lens

Lenses

A lens is a custom view of the content in the repository. You can think of it as a fancy kind of list that will let you see content through the eyes of organizations and people you trust.

What is in a lens?

Lens makers point to materials (modules and collections), creating a guide that includes their own comments and descriptive tags about the content.

Who can create a lens?

Any individual member, a community, or a respected organization.

What are tags? tag icon

Tags are descriptors added by lens makers to help label content, attaching a vocabulary that is meaningful in the context of the lens.

| External bookmarks