<?xml version="1.0" encoding="utf-8"?>
<document xmlns="http://cnx.rice.edu/cnxml" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:bib="http://bibtexml.sf.net/" xmlns:q="http://cnx.rice.edu/qml/1.0" id="new" module-id="" cnxml-version="0.6">
  <title>Signal Processing in Processing: Filtri Elementari</title>
  <metadata xmlns:md="http://cnx.rice.edu/mdml/0.4">
  <!-- WARNING! The 'metadata' section is read only. Do not edit below.
       Changes to the metadata section in the source will not be saved. -->
  <md:content-id>m12827</md:content-id>
  <md:title>Signal Processing in Processing: Filtri Elementari</md:title>
  <md:version>1.6</md:version>
  <md:created>2005/06/02 03:18:24 GMT-5</md:created>
  <md:revised>2009/06/15 09:52:45.728 GMT-5</md:revised>
  <md:authorlist>
    <md:author id="drocchesso">
        <md:firstname>Davide</md:firstname>
        <md:surname>Rocchesso</md:surname>
        <md:fullname>Davide Rocchesso</md:fullname>
        <md:email>roc@iuav.it</md:email>
    </md:author>
    <md:author id="ppolotti">
        <md:firstname>Pietro</md:firstname>
        <md:surname>Polotti</md:surname>
        <md:fullname>Pietro Polotti</md:fullname>
        <md:email>polotti@sci.univr.it</md:email>
    </md:author>
  </md:authorlist>
  <md:maintainerlist>
    <md:maintainer id="drocchesso">
        <md:firstname>Davide</md:firstname>
        <md:surname>Rocchesso</md:surname>
        <md:fullname>Davide Rocchesso</md:fullname>
        <md:email>roc@iuav.it</md:email>
    </md:maintainer>
    <md:maintainer id="ppolotti">
        <md:firstname>Pietro</md:firstname>
        <md:surname>Polotti</md:surname>
        <md:fullname>Pietro Polotti</md:fullname>
        <md:email>polotti@sci.univr.it</md:email>
    </md:maintainer>
  </md:maintainerlist>
  <md:license href="http://creativecommons.org/licenses/by/2.0/"/>
  <md:licensorlist>
    <md:licensor id="drocchesso">
        <md:firstname>Davide</md:firstname>
        <md:surname>Rocchesso</md:surname>
        <md:fullname>Davide Rocchesso</md:fullname>
        <md:email>roc@iuav.it</md:email>
    </md:licensor>
    <md:licensor id="ppolotti">
        <md:firstname>Pietro</md:firstname>
        <md:surname>Polotti</md:surname>
        <md:fullname>Pietro Polotti</md:fullname>
        <md:email>polotti@sci.univr.it</md:email>
    </md:licensor>
  </md:licensorlist>
  <md:keywordlist>
    <md:keyword>FIR filters</md:keyword>
    <md:keyword>first- and second-order filters for sounds and images</md:keyword>
    <md:keyword>IIR filters</md:keyword>
    <md:keyword>sharpening filters</md:keyword>
    <md:keyword>smoothing filters</md:keyword>
  </md:keywordlist>
  <md:subjectlist>
    <md:subject>Science and Technology</md:subject>
  </md:subjectlist>
  <md:abstract>Si illustrano i filtri fondamentali per i segnali 1D e 2D e si forniscono esempi in Processing.</md:abstract>
  <md:language>it</md:language>
  <!-- WARNING! The 'metadata' section is read only. Do not edit above.
       Changes to the metadata section in the source will not be saved. -->
</metadata>
  <content>
    <section id="id1166303430057">
      <title>Filtri FIR</title> <para id="firp">Si chiamano filtri
      <term>Finite Impulse Response</term> (FIR) tutti i filtri
      caratterizzati da una risposta all'impulso con un numero finito
      di campioni. Essi si realizzano mediante l'operazione di <link document="m12809" target-id="convolution"> convoluzione</link>. Cioè,
      per ogni campione di uscita prodotto viene calcolata una somma
      pesata di un numero finito di campioni dell'ingresso.</para>
      <section id="id1166300247139">
	<title>Filtro di media</title>
	<para id="averagingp">Il più semplice filtro FIR non banale è il filtro che effettua la media di due campioni contigui, la cui convoluzione si può esprimere come <equation id="convmedia">
<m:math type="block">
	    <m:apply>
	      <m:eq/>
	      <m:apply>
		<m:ci type="fn">y</m:ci>
		<m:ci>n</m:ci>
	      </m:apply>
	      <m:apply>
		<m:plus/>
		<m:apply>
		  <m:times/>
		  <m:mn>0.5</m:mn>
		  <m:apply>
		    <m:ci type="fn">x</m:ci>
		    <m:ci>n</m:ci>
		  </m:apply>
		</m:apply>
		<m:apply>
		  <m:times/>
		  <m:mn>0.5</m:mn>
		  <m:apply>
		    <m:ci type="fn">x</m:ci>
		    <m:apply>
		      <m:minus/>
		      <m:ci>n</m:ci>
		      <m:mn>1</m:mn>
		    </m:apply>
		  </m:apply>
		</m:apply>
	      </m:apply>
	    </m:apply>
	  </m:math> </equation> e quindi la risposta all'impulso ha
	    valore <m:math> <m:ci>0.5</m:ci> </m:math> negli istanti
	    <m:math> <m:ci>0</m:ci> </m:math> e <m:math>
	    <m:ci>1</m:ci> </m:math>, e valore nullo altrove.
	</para>
	<para id="averagingfrp">
	  Immettendo un segnale sinusoidale nel filtro, l'uscita sarà
      ancora un segnale sinusoidale scalato in ampiezza e ritardato in
      fase secondo quanto prescritto dalla <link document="m12809" target-id="freqrespp"> risposta in frequenza </link>, che risulta essere
	  <equation id="freqrespmedia">
	  <m:math type="block">
	    <m:apply>
	      <m:eq/>
	      <m:apply>
		<m:ci type="fn">H</m:ci>
		<m:ci>ω</m:ci>
	      </m:apply>
	      <m:apply>
		<m:times/>
	      <m:apply>
		<m:cos/>
		<m:apply>
		  <m:divide/>
		  <m:ci>ω</m:ci>
		  <m:mn>2</m:mn>
		</m:apply>
	      </m:apply>
		<m:apply>
		  <m:exp/>
		  <m:apply>
		    <m:minus/>
		    <m:apply>
		      <m:times/>
		      <m:imaginaryi/>
		      <m:apply>
			<m:divide/>
			<m:ci>ω</m:ci>
			<m:mn>2</m:mn>
		      </m:apply>		      
		    </m:apply>
		  </m:apply>
		</m:apply>
	      </m:apply>
	    </m:apply>
	  </m:math> 	
	  </equation> il cui modulo e fase sono rappresentati in <link target-id="averagingresponse"/>.
	</para> 
	<figure id="averagingresponse">
	  <title>Risposta di ampiezza e di fase per il filtro di media</title>
	   <media id="id1166302543235" alt=""><image src="fir1.png" mime-type="image/png"/></media> 
	</figure>  
	<para id="averagingdiscp">Quello appena presentato è un filtro
	    del primo ordine (e di lunghezza <m:math> <m:ci>2</m:ci>
	    </m:math>), in quanto utilizza un solo campione del
	    passato della sequenza di ingresso.  Da <link target-id="averagingresponse"/> si vede che la risposta in
	    frequenza è di tipo <term>passa-basso</term>, 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.</para>
      </section>
      <section id="id8005201">
	<title>Filtro FIR del secondo ordine simmetrico</title> <para id="fir2p"> Un filtro FIR del secondo ordine simmetrico ha
	  risposta all'impulso della forma <m:math>
	    <m:list>
	      <m:ci><m:msub>
		  <m:mi>a</m:mi>
		  <m:mn>0</m:mn>
		</m:msub>
	      </m:ci>
	      <m:ci><m:msub>
		  <m:mi>a</m:mi>
		  <m:mn>1</m:mn>
		</m:msub>
	      </m:ci>
	      <m:ci><m:msub>
		  <m:mi>a</m:mi>
		  <m:mn>0</m:mn>
		</m:msub>
	      </m:ci>
	    </m:list>
	  </m:math>, e la risposta in frequenza risulta essere
	  <m:math>
	    <m:apply>
	      <m:eq/>
	      <m:apply>
		<m:ci type="fn">H</m:ci>
		<m:ci>ω</m:ci>
	      </m:apply>
	      <m:apply>
		<m:times/>
		<m:apply>
		  <m:plus/>
		  <m:ci><m:msub>
		      <m:mi>a</m:mi>
		      <m:mn>1</m:mn>
		    </m:msub>
		  </m:ci>
		  <m:apply>
		    <m:times/>
		    <m:mn>2</m:mn>
		    <m:ci><m:msub>
			<m:mi>a</m:mi>
			<m:mn>0</m:mn>
		      </m:msub>
		    </m:ci>
		    <m:apply>
		      <m:cos/>
		      <m:ci>ω</m:ci>
		    </m:apply>
		  </m:apply>
		</m:apply>
		<m:apply>
		  <m:exp/>
		  <m:apply>
		    <m:minus/>
		    <m:apply>
		      <m:times/>
		      <m:imaginaryi/>
			<m:ci>ω</m:ci>
		    </m:apply>
		  </m:apply>
		</m:apply>
	      </m:apply>
	    </m:apply>
	  </m:math>. 
La convoluzione si può esprimere come <equation id="convfir2">
<m:math type="block">
	    <m:apply>
	      <m:eq/>
	      <m:apply>
		<m:ci type="fn">y</m:ci>
		<m:ci>n</m:ci>
	      </m:apply>
	      <m:apply>
		<m:plus/>
		<m:apply>
		  <m:times/>
		    <m:ci><m:msub>
		      <m:mi>a</m:mi>
		      <m:mn>0</m:mn>
		    </m:msub>
		  </m:ci>
		  <m:apply>
		    <m:ci type="fn">x</m:ci>
		    <m:ci>n</m:ci>
		  </m:apply>
		</m:apply>
		<m:apply>
		  <m:times/>
		    <m:ci><m:msub>
		      <m:mi>a</m:mi>
		      <m:mn>1</m:mn>
		    </m:msub>
		  </m:ci>
		  <m:apply>
		    <m:ci type="fn">x</m:ci>
		    <m:apply>
		      <m:minus/>
		      <m:ci>n</m:ci>
		      <m:mn>1</m:mn>
		    </m:apply>
		  </m:apply>
		</m:apply>
		<m:apply>
		  <m:times/>
		    <m:ci><m:msub>
		      <m:mi>a</m:mi>
		      <m:mn>0</m:mn>
		    </m:msub>
		  </m:ci>
		  <m:apply>
		    <m:ci type="fn">x</m:ci>
		    <m:apply>
		      <m:minus/>
		      <m:ci>n</m:ci>
		      <m:mn>2</m:mn>
		    </m:apply>
		  </m:apply>
		</m:apply>
	      </m:apply>
	    </m:apply>
	  </m:math> </equation>
	  Nel caso particolare in cui <m:math>
	    <m:apply>
	      <m:eq/>		    
	      <m:ci><m:msub>
			<m:mi>a</m:mi>
			<m:mn>0</m:mn>
		      </m:msub>
		    </m:ci>
	      <m:mn>0.17654</m:mn>
	    </m:apply>
	  </m:math> e <m:math>
	    <m:apply>
	      <m:eq/>		    
	      <m:ci><m:msub>
			<m:mi>a</m:mi>
			<m:mn>1</m:mn>
		      </m:msub>
		    </m:ci>
	      <m:mn>0.64693</m:mn>
	    </m:apply>
	  </m:math> la risposta in frequenza (modulo e fase) è rappresentata in 
	  <link target-id="fir2response"/>.
	</para>  
	<figure id="fir2response"> 
	  <title>Risposta di ampiezza e di fase per un filtro FIR del secondo ordine
	  </title>
	   <media id="id1166300538354" alt=""><image src="fir2.png" mime-type="image/png"/></media> 
	</figure> 
      </section>
      <section id="hp12">
	<title>Filtri passa-alto</title> <para id="hipassp">Per i
	semplici filtri passa-basso appena visti, è sufficiente
	cambiare il segno di un coefficiente per ottenere una risposta
	di tipo <term>passa-alto</term>, cioè una enfatizzazione delle
	alte frequenze rispetto alle basse frequenze. Ad esempio, la
	<link target-id="resp12hp"/> 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
<m:math>
	    <m:list>
	      <m:mn>0.5</m:mn>
	      <m:apply>
		<m:minus/>
		<m:mn>0.5</m:mn>
	      </m:apply>
	    </m:list>
	  </m:math> e
<m:math>
	    <m:list>
	      <m:mn>0.17654</m:mn>
	      <m:apply>
		<m:minus/>
		<m:mn>0.64693</m:mn>
	      </m:apply>
	      <m:mn>0.17654</m:mn>
	    </m:list>
	  </m:math>.
 	<figure id="resp12hp" orient="horizontal">
	  <title>Risposta di ampiezza per un filtro FIR passa-alto del
	  primo (sinistra) e del secondo (destra) ordine.</title>
	    <subfigure id="id1166301316019">
	      <media id="id1166298329049" alt=""><image src="fir1hp2.png" mime-type="image/png"/></media>  
	    </subfigure>  
	    <subfigure id="id8717729">
	  <media id="id1166302835581" alt=""><image src="fir2hp2.png" mime-type="image/png"/></media> 
	    </subfigure>  
	</figure> 
	</para>	 

	<para id="hipasstransp">
	  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.
	</para>
      </section>
      <section id="id7878381">
	<title>Filtri FIR in 2D</title>
	<para id="fir2dp">
	  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 <term>filtro di media
	  </term> si può rappresentare mediante la maschera di
	  convoluzione
	  <m:math type="block" id="maskmean">
	    <m:apply>
	      <m:times/>
	      <m:apply>
		<m:divide/>
		<m:mn>1</m:mn>
		<m:mn>9</m:mn>
	      </m:apply>
	  <m:matrix>
	    <m:matrixrow>
		  <m:mn>1</m:mn>
		  <m:mn>1</m:mn>
		  <m:mn>1</m:mn>
	    </m:matrixrow>
	    <m:matrixrow>
		  <m:mn>1</m:mn>
		  <m:mn>1</m:mn>
		  <m:mn>1</m:mn>
	    </m:matrixrow>
	    <m:matrixrow>
		  <m:mn>1</m:mn>
		  <m:mn>1</m:mn>
		  <m:mn>1</m:mn>
	    </m:matrixrow>
	  </m:matrix>
	    </m:apply>
	</m:math>.
	</para>

	<example id="noise_cleaning">
	  <title>Noise cleaning</title>
	  <para id="noisecleaningp">
	    I filtri passa-basso (e quindi, in particolare, i filtri
	    di media) operano uno <term>smoothing</term> 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 <link target-id="noise_cleaning_code"> sotto riportato </link> carica una immagine, la
	    corrompe con rumore bianco, e quindi ne sottopone metà ad
	    un filtraggio di media, ottenendo <link target-id="smoothingf"/>. </para>

	<figure id="smoothingf">
	  <title>Smoothing</title>
	  <media id="id1166303425141" alt=""><image src="vetroRottoSporco.gif" mime-type="image/gif"/></media> 
	</figure> 

	<para id="noise_cleaning_code">
<!--	<table id="glass_table" frame="all">
	<tgroup cols="1" align="left" colsep="0" rowsep="0">
	<colspec colname="col1" colnum="1" colwidth="400"/> -->
	<!-- <colspec colname="col2" colnum="2" colwidth="400"/> -->
<!--	<tbody>
	<row> -->
<!--	<entry> 
	  <media type="image/gif" src="vetroRottoSporco.gif">
		      </media> 
	</entry> -->
<!--	<entry> -->
	<code id="id7780164" display="block">// 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&lt;height; i++) { 
  for(int j=width/4; j&lt;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&lt;height; y++) { 
  for(int x=0; x&lt;width/2; x++) { 
    float sum = 0; 
    for(int k=-n2; k&lt;=n2; k++) { 
      for(int j=-m2; j&lt;=m2; j++) { 
        // Reflect x-j to not exceed array boundary 
        int xp = x-j; 
        int yp = y-k; 
        if (xp &lt; 0) { 
          xp = xp + width; 
        } else if (x-j &gt;= width) { 
          xp = xp - width; 
        } 
        // Reflect y-k to not exceed array boundary 
        if (yp &lt; 0) { 
          yp = yp + height; 
        } else if (yp &gt;= 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&lt;height; i++) { 
  for(int j=0; j&lt;width/2; j++) { 
    pixels[i*width + j] = 
	      color(output[j][i], output[j][i], output[j][i]);
  } 
} 
updatePixels(); 
         
	</code>
<!--    </entry>
      </row>
      </tbody>
      </tgroup>
      </table> -->
</para>
	</example>
	<para id="gaussianfilterp">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 è
	  	  <m:math type="block" id="maskgauss">
	    <m:apply>
	      <m:times/>
	      <m:apply>
		<m:divide/>
		<m:mn>1</m:mn>
		<m:mn>273</m:mn>
	      </m:apply>
	  <m:matrix>
	    <m:matrixrow>
		  <m:mn>1</m:mn>
		  <m:mn>4</m:mn>
		  <m:mn>7</m:mn>
		  <m:mn>4</m:mn>
		  <m:mn>1</m:mn>
	    </m:matrixrow>
	    <m:matrixrow>
		  <m:mn>4</m:mn>
		  <m:mn>16</m:mn>
		  <m:mn>26</m:mn>
		  <m:mn>16</m:mn>
		  <m:mn>4</m:mn>
	    </m:matrixrow>
	    <m:matrixrow>
		  <m:mn>7</m:mn>
		  <m:mn>26</m:mn>
		  <m:mn>41</m:mn>
		  <m:mn>26</m:mn>
		  <m:mn>7</m:mn>
	    </m:matrixrow>
	    <m:matrixrow>
		  <m:mn>4</m:mn>
		  <m:mn>16</m:mn>
		  <m:mn>26</m:mn>
		  <m:mn>16</m:mn>
		  <m:mn>4</m:mn>
	    </m:matrixrow>
	    <m:matrixrow>
		  <m:mn>1</m:mn>
		  <m:mn>4</m:mn>
		  <m:mn>7</m:mn>
		  <m:mn>4</m:mn>
		  <m:mn>1</m:mn>
	    </m:matrixrow>
	  </m:matrix>
	    </m:apply>
	</m:math>.
	</para>
	<para id="crispp">
	  Se invece si vogliono rendere più evidenti i contorni e i
	  tratti salienti (<term>edge crispening</term> o sharpening)
	  di una immagine bisogna effettuare un filtraggio di tipo
	  passa-alto. In modo analogo a quanto visto in <link target-id="hp12"/> 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
<m:math type="block">
	  <m:matrix>
	    <m:matrixrow>
		  <m:mn>-1</m:mn>
		  <m:mn>-1</m:mn>
		  <m:mn>-1</m:mn>
	    </m:matrixrow>
	    <m:matrixrow>
		  <m:mn>-1</m:mn>
		  <m:mn>9</m:mn>
		  <m:mn>-1</m:mn>
	    </m:matrixrow>
	    <m:matrixrow>
		  <m:mn>-1</m:mn>
		  <m:mn>-1</m:mn>
		  <m:mn>-1</m:mn>
	    </m:matrixrow>
	  </m:matrix>
	</m:math>
	  produce l'effetto di <link target-id="crispenf"/>.
	</para> 
	<figure id="crispenf">
	  <title>Edge crispening</title>
	    <media id="id1166305053801" alt=""><image src="vetroSharpened.gif" mime-type="image/gif"/></media> 
	</figure>
	<section id="id1166302765201">
	  <title>Filtraggio non lineare: filtro di mediana</title>
	  <para id="medianfilterp">
	    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 <m:math>
	      <m:mn>N</m:mn> </m:math> (dispari) numeri, l'elemento
	      mediano dell'insieme è quello che individua <m:math>
	      <m:apply>
		<m:divide/>
		<m:apply>
		  <m:minus/>
		  <m:mi>N</m:mi>
		  <m:ci>1</m:ci>
		</m:apply>
		<m:ci>2</m:ci>
	      </m:apply>
	    </m:math> elementi più piccoli di sè, e <m:math>
	      <m:apply>
		<m:divide/>
		<m:apply>
		  <m:minus/>
		  <m:mi>N</m:mi>
		  <m:ci>1</m:ci>
		</m:apply>
		<m:ci>2</m:ci>
	      </m:apply>
	    </m:math> elementi più grandi. Una tipica maschera per
	    filtro mediano ha la forma di croce. Ad esempio, una
	    maschera a croce <m:math>
	      <m:apply>
		<m:vectorproduct/>
		<m:mn>3</m:mn>
		<m:mn>3</m:mn>
	      </m:apply>
	    </m:math>
 può individuare, quando applicata in un certo punto di una certa
 immagine, i pixel di valore
	  <m:math type="block" id="maskcross">
	  <m:matrix>
	    <m:matrixrow>
		  <m:ci>x</m:ci>
		  <m:mn>4</m:mn>
		  <m:mn>x</m:mn>
	    </m:matrixrow>
	    <m:matrixrow>
		  <m:mn>7</m:mn>
		  <m:mn>99</m:mn>
		  <m:mn>12</m:mn>
	    </m:matrixrow>
	    <m:matrixrow>
		  <m:mn>x</m:mn>
		  <m:mn>9</m:mn>
		  <m:mn>x</m:mn>
	    </m:matrixrow>
	  </m:matrix>
	    </m:math>, e quindi sostituire al valore <m:math>
	      <m:mn>99</m:mn> </m:math> il valore mediano <m:math>
	      <m:mn>9</m:mn> </m:math>.
	  </para>
	</section>
      </section>
      <exercise id="audiofiltering">
	<problem id="id1166302166291">
	  <para id="audiofilteringpp">Si riscriva l'operazione di
	  filtraggio <code>filtra()</code> del <link document="m12664" target-id="sound_chooser">Sound Chooser</link> presentato nel
	  modulo <link document="m12664">Media Representation in
	  Processing</link> in modo che realizzi il filtro FIR la cui
	  risposta in frequenza è rappresentata in <link target-id="fir2response"/>. Cosa succede se il filtro viene
	  applicato più volte?</para>
	</problem>
	<solution id="id6806714">
	  <para id="audiofilteringsp">

<code id="id1166305018445" display="block">
          
 //filtra = new function
void filtra(float[] DATAF, float[] DATA, float a0, float a1) {

  for(int i = 3; i &lt; DATA.length; i++){
    DATAF[i] = a0*DATA[i]+a1*DATA[i-1]+a0*DATA[i-2];//filtraggio FIR del secondo ordine simmetrico
  }
}
 
 	      
	    </code>
          </para>
<para id="audiofilteringsp2">
	    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:math>
	      <m:ci>m</m:ci>
	    </m:math>
	    filtri di ordine <m:math>
	      <m:ci>N</m:ci>
	    </m:math>
	    (nel nostro caso <m:math>
	      <m:apply>
		<m:eq/>
		<m:ci>N</m:ci>
		<m:mn>2</m:mn>
	      </m:apply>
	    </m:math>
) è equivalente ad un filtraggio attraverso un filtro di ordine <m:math>
	      <m:apply>
		<m:times/>
		<m:ci>m</m:ci>
		<m:ci>N</m:ci>
	      </m:apply>
	    </m:math>
</para>  
	</solution>


      </exercise>
      <exercise id="imagefiltering">
	<problem id="id5727410">
	  <para id="imagefilteringpp">Considerato il codice
	  Processing dell'<link url="http://processing.org/learning/topics/blur.html">esempio
	  di blurring</link> contenuto tra gli <link url="http://www.processing.org/learning/topics/"> esempi
	  di Processing</link>, lo si modifichi in modo da effettuare
	  un filtraggio gaussiano.
	  </para>
	</problem> 
	<solution id="id1166298422209"> 	  
	  <para id="imagefilteringsp">
	<code id="id8643129" display="block">// 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&lt;5; i++)
  for (int j=0; j&lt; 5; j++)
    kernel[i][j] = kernel[i][j]/273; 
// Convolve the image 
for(int y=0; y&lt;height; y++) { 
  for(int x=0; x&lt;width/2; x++) { 
    float sum = 0; 
    for(int k=-n2; k&lt;=n2; k++) { 
      for(int j=-m2; j&lt;=m2; j++) { 
        // Reflect x-j to not exceed array boundary 
        int xp = x-j; 
        int yp = y-k; 
        if (xp &lt; 0) { 
          xp = xp + width; 
        } else if (x-j &gt;= width) { 
          xp = xp - width; 
        } 
        // Reflect y-k to not exceed array boundary 
        if (yp &lt; 0) { 
          yp = yp + height; 
        } else if (yp &gt;= 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&lt;height; i++) { 
  for(int j=0; j&lt;width/2; j++) { 
    pixels[i*width + j] = color(output[j][i], output[j][i], output[j][i]); 
  } 
} 
updatePixels(); 
 	      
	    </code>
	  </para>
	</solution> 
      </exercise> 
      <exercise id="noise_cleaningex">
	<problem id="id1166301111734">
	  <para id="noisecleaningexp">
	    Si modifichi il codice di <link target-id="noise_cleaning"/>
	    in modo da confrontare la maschera di convoluzione del
	    <link target-id="maskmean"> filtro di media </link> con la
	  <m:math type="block">
	    <m:apply>
	      <m:times/>
	      <m:apply>
		<m:divide/>
		<m:mn>1</m:mn>
		<m:mn>10</m:mn>
	      </m:apply>
	  <m:matrix>
	    <m:matrixrow>
		  <m:mn>1</m:mn>
		  <m:mn>1</m:mn>
		  <m:mn>1</m:mn>
	    </m:matrixrow>
	    <m:matrixrow>
		  <m:mn>1</m:mn>
		  <m:mn>2</m:mn>
		  <m:mn>1</m:mn>
	    </m:matrixrow>
	    <m:matrixrow>
		  <m:mn>1</m:mn>
		  <m:mn>1</m:mn>
		  <m:mn>1</m:mn>
	    </m:matrixrow>
	  </m:matrix>
	    </m:apply>
	</m:math>. 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 <m:math>
	      <m:apply>
		<m:vectorproduct/>
		<m:mn>3</m:mn>
		<m:mn>3</m:mn>
	      </m:apply>
	    </m:math>.
	  </para>
	</problem>
	<solution id="id1166300527362">
	  <para id="noisecleaningexsolp">
Ecco il filtro di mediana:
	<code id="id4565982" display="block">
          
// 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&lt;height; i++) { 
  for(int j=width/4; j&lt;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&lt;height; y++) { 
  for(int x=0; x&lt;width/2; x++) { 
    int indSort = 0;
    for(int k=-1; k&lt;=1; k++) { 
      for(int j=-1; j&lt;=1; j++) { 
        // Reflect x-j to not exceed array boundary 
        int xp = x-j; 
        int yp = y-k; 
        if (xp &lt; 0) { 
          xp = xp + width; 
        } else if (x-j &gt;= width) { 
          xp = xp - width;  
        } 
        // Reflect y-k to not exceed array boundary 
        if (yp &lt; 0) { 
          yp = yp + height; 
        } else if (yp &gt;= height) { 
          yp = yp - height; 
        } 
        if ((((k != j) &amp;&amp; (k != (-j))) ) || (k == 0)) { //cross selection
          grayVal = (int)red(get(xp, yp)); 
          indSort = 0;
          while (grayVal &lt; sortedValues[indSort]) {indSort++; }          
          for (int i=4; i&gt;indSort; i--) sortedValues[i] = sortedValues[i-1];
          sortedValues[indSort] = grayVal;
        } 
      } 
    } 
    output[x][y] = int(sortedValues[2]);  
    for (int i=0; i&lt; 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&lt;height; i++) { 
  for(int j=0; j&lt;width/2; j++) { 
    pixels[i*width + j] = 
      color(output[j][i], output[j][i], output[j][i]);
  } 
} 
updatePixels(); 
          
</code>
	  </para>
	</solution>
      </exercise>
    </section>
    <section id="id8188230">
      <title>Filtri IIR</title>
      <para id="recursivediffeq">
	L'operazione di filtraggio rappresentata dalla <link target-id="convmedia"/> è un caso particolare di <term>equazione alle differenze</term>, in cui un campione dell'uscita è funzione soltanto di campioni dell'ingresso. Più in generale, è possibile costruire equazioni alle differenze di tipo <term>ricorsivo</term>, in cui un campione dell'uscita è funzione di un altro campione dell'uscita stessa. Ad esempio, l'equazione alle differenze 
	<equation id="iirdiffeq">
<m:math type="block">
	    <m:apply>
	      <m:eq/>
	      <m:apply>
		<m:ci type="fn">y</m:ci>
		<m:ci>n</m:ci>
	      </m:apply>
	      <m:apply>
		<m:plus/>
		<m:apply>
		  <m:times/>
		  <m:mn>0.5</m:mn>
		  <m:apply>
		    <m:ci type="fn">y</m:ci>
		  <m:apply>
		    <m:minus/>
		    <m:ci>n</m:ci>
		    <m:mn>1</m:mn>
		  </m:apply>
		  </m:apply>
		</m:apply>
		<m:apply>
		  <m:times/>
		  <m:mn>0.5</m:mn>
		  <m:apply>
		    <m:ci type="fn">x</m:ci>
		      <m:ci>n</m:ci>
		  </m:apply>
		</m:apply>
	      </m:apply>
	    </m:apply>
	  </m:math> 	 
	</equation>
	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 <link target-id="iirdiffeq"/> si ottiene la
	sequenza di lunghezza infinita <m:math>
	  <m:apply>
	    <m:eq/>
	    <m:ci>y</m:ci>
	    <m:list>
	      <m:mn>0.5</m:mn>
	      <m:mn>0.25</m:mn>
	      <m:mn>0.125</m:mn>
	      <m:mn>0.0625</m:mn>
	      <m:ci>...</m:ci>
	    </m:list>
	  </m:apply>
	</m:math>. Per questo, filtri di questo tipo si chiamano
	<term>Infinite Impulse Response</term>
	(IIR). L'<term>ordine</term> 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
	<link target-id="iirdiffeq"/> è 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,
	<link target-id="iir1response"/> riporta le risposte di ampiezza
	e fase per il filtro IIR del primo ordine rappresentato dalla
	equazione alle differenze <link target-id="iirdiffeq"/>.Detto
	<m:math> <m:ci>a</m:ci> </m:math> il coefficiente che pesa la
	dipendenza dal valore precedente dell'uscita (<m:math>
	<m:mn>0.5</m:mn> </m:math> nella specifica <link target-id="iirdiffeq"/>), la risposta all'impulso è del tipo
	<m:math>
	  <m:apply>
	    <m:eq/>
	    <m:apply>
	      <m:ci type="fn">h</m:ci>
	      <m:ci>n</m:ci>
	    </m:apply>
	    <m:apply>
	      <m:power/>
	      <m:ci>a</m:ci>
	      <m:ci>n</m:ci>
	    </m:apply>
	  </m:apply>
	</m:math>. Quanto più <m:math> <m:ci>a</m:ci> </m:math> si
	  avvicina a <m:math> <m:mn>1</m:mn> </m:math>, 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 <m:math> <m:ci>a</m:ci> </m:math> maggiori di
	  <m:math> <m:mn>1</m:mn> </m:math> provocano una risposta
	  all'impulso divergente, e quindi un comportamento
	  <term>instabile</term> del filtro.  </para>
	<figure id="iir1response">
	  <title>Risposta di ampiezza e di fase per il filtro IIR del
	  primo ordine</title>
	   <media id="id1166300507626" alt=""><image src="iir1resp.png" mime-type="image/png"/></media> 
	</figure>
      <para id="iiraudio">
	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.
      </para>
      <section id="id1166299651371">
	<title>Filtro risonante</title> 
	<para id="iir2">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
	<equation id="iir2diffeq">
<m:math type="block">
	    <m:apply>
	      <m:eq/>
	      <m:apply>
		<m:ci type="fn">y</m:ci>
		<m:ci>n</m:ci>
	      </m:apply>
	      <m:apply>
		<m:plus/>
		<m:apply>
		  <m:times/>
		  <m:ci><m:msub>
		      <m:mi>a</m:mi>
		      <m:mn>1</m:mn>
		    </m:msub>
		  </m:ci>
		  <m:apply>
		    <m:ci type="fn">y</m:ci>
		  <m:apply>
		    <m:minus/>
		    <m:ci>n</m:ci>
		    <m:mn>1</m:mn>
		  </m:apply>
		  </m:apply>
		</m:apply>
		<m:apply>
		  <m:times/>
		  <m:ci><m:msub>
		      <m:mi>a</m:mi>
		      <m:mn>2</m:mn>
		    </m:msub>
		  </m:ci>
		  <m:apply>
		    <m:ci type="fn">y</m:ci>
		  <m:apply>
		    <m:minus/>
		    <m:ci>n</m:ci>
		    <m:mn>2</m:mn>
		  </m:apply>
		  </m:apply>
		</m:apply>
		<m:apply>
		  <m:times/>
		  <m:ci><m:msub>
		      <m:mi>b</m:mi>
		      <m:mn>0</m:mn>
		    </m:msub>
		  </m:ci>
		  <m:apply>
		    <m:ci type="fn">x</m:ci>
		      <m:ci>n</m:ci>
		  </m:apply>
		</m:apply>
	      </m:apply>
	    </m:apply>
	  </m:math> </equation> si può vedere che essa produce la
	  risposta in frequenza di <link target-id="iir2response"/>. I coefficienti di dipendenza dal passato dell'uscita si possono anche esprimere come <m:math>
	    <m:apply>
	      <m:eq/>
 		  <m:ci><m:msub>
		      <m:mi>a</m:mi>
		      <m:mn>1</m:mn>
		    </m:msub>
		  </m:ci>
	      <m:apply>
		<m:times/>
		<m:mn>2</m:mn>
		<m:ci>r</m:ci>
		<m:apply>
		  <m:cos/>
		  <m:ci><m:msub>
		      <m:mi>ω</m:mi>
		      <m:mn>0</m:mn>
		    </m:msub>
		  </m:ci>
		</m:apply>
	      </m:apply>
	    </m:apply>
	  </m:math> e <m:math>
	    <m:apply>
	      <m:eq/>
 		  <m:ci><m:msub>
		      <m:mi>a</m:mi>
		      <m:mn>2</m:mn>
		    </m:msub>
		  </m:ci>	
	      <m:apply>
		<m:minus/>
		<m:apply>
		<m:power/>
		<m:ci>r</m:ci>
		<m:mn>2</m:mn>
		</m:apply>
	      </m:apply>
	    </m:apply>
	  </m:math>, dove <m:math>		  <m:ci><m:msub>
		      <m:mi>ω</m:mi>
		      <m:mn>0</m:mn>
		    </m:msub>
		  </m:ci>
	  </m:math> è la frequenza del picco di risonanza e <m:math>
	    <m:ci>r</m:ci>
	  </m:math> produce picchi tanto più stretti quanto più è vicino a <m:math>
	    <m:mn>1</m:mn>
	  </m:math>.
	</para> 
	<figure id="iir2response">
	  <title>Risposta di ampiezza e di fase per il filtro IIR del
	  secondo ordine</title>
	    <media id="id1166300901863" alt=""><image src="iir2.png" mime-type="image/png"/></media> 
	</figure>
      </section>
      <exercise id="audiofiltering2">
	<problem id="id1166300791418">
	  <para id="audiofiltering2pp">Si verifichi che l'operazione
	  di filtraggio <code>filtra()</code> del <link document="m12664" target-id="sound_chooser">Sound
	  Chooser</link> presentato nel modulo <link document="m12664">Media Representation in Processing</link>
	  realizza un filtro IIR risonante. Quale è la relazione
	  realizzata tra <m:math> <m:ci>r</m:ci> </m:math> e la
	  posizione del mouse lungo le barrette?
	  </para>
	</problem>
      </exercise>
    </section>
  </content> 
</document>
