Summary: The fundamental filters for 1D and 2D signals are introduced and examples are given in Processing (in italian).
Nota: You are viewing an old version of this document. The latest version is available here.
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.
Il più semplice filtro FIR non banale è il filtro che effettua la media di due campioni contigui, la cui convoluzione si può esprimere come
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
| Risposta di ampiezza e di fase per il filtro di media |
|---|
![]() |
Quello appena presentato è un filtro
del primo ordine (e di lunghezza
Un filtro FIR del secondo ordine simmetrico ha
risposta all'impulso della forma
| Risposta di ampiezza e di fase per un filtro FIR del secondo ordine |
|---|
![]() |
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
| Risposta di ampiezza per un filtro FIR passa-alto del primo (sinistra) e del secondo (destra) ordine. | ||||
|---|---|---|---|---|
|
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.
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
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.
| Smoothing |
|---|
![]() |
// 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.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. Più è larga la campana e più accentuato sarà
l'effetto di smoothing, con conseguente perdita di dettagli. Un esempio di maschera gaussiana è
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
| Edge crispening |
|---|
![]() |
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
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?
//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
Considerato il codice Processing dell'esempio di blurring contenuto tra gli esempi di Processing, lo si modifichi in modo da effettuare un filtraggio gaussiano.
// smoothing Gaussian filter, adapted from REAS:
// http://www.processing.org/learning/examples/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();
Si modifichi il codice di Esempio 1
in modo da confrontare la maschera di convoluzione del
filtro di media con la
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();
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
| Risposta di ampiezza e di fase per il filtro IIR del primo ordine |
|---|
![]() |
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.
In campo audio assumono particolare importanza i filtri IIR del secondo ordine in quanto consento di realizzare un risonatore elementare. Data l'equazione alle differenze
| Risposta di ampiezza e di fase per il filtro IIR del secondo ordine |
|---|
![]() |
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