◩ Grafica e immagini

Filtri di convoluzione: sfocatura, nitidezza e bordi con i kernel

Come funzionano i filtri delle immagini: convoluzione con un kernel, sfocatura gaussiana, maschera di contrasto, rilevamento dei bordi e il filtro mediano.

Sfocatura, nitidezza, rilievo, rilevamento dei contorni: molti dei filtri presenti in qualunque programma di grafica si basano sulla stessa operazione matematica, la convoluzione. Una volta capito il meccanismo, i filtri smettono di essere effetti misteriosi e diventano strumenti prevedibili, che si possono regolare con criterio o persino scrivere da sé in poche righe di codice.

L'idea: ogni pixel guarda i vicini

Una convoluzione calcola il nuovo valore di ciascun pixel come somma pesata del pixel stesso e dei suoi vicini. I pesi sono contenuti in una piccola matrice chiamata kernel (o maschera), di solito 3 × 3, 5 × 5 o più grande.

Il procedimento per ogni pixel è:

  1. si centra il kernel sul pixel;
  2. si moltiplica ogni peso per il valore del pixel che gli sta sotto;
  3. si sommano tutti i prodotti;
  4. il risultato è il nuovo valore del pixel centrale.

Si ripete per tutti i pixel, leggendo sempre dall'immagine originale e scrivendo in una nuova. Se si scrivesse sull'originale, i pixel già elaborati influenzerebbero i successivi.

Sfocatura

Il kernel di sfocatura più semplice è la media (box blur): tutti i pesi uguali, la cui somma fa 1.

1/9  1/9  1/9
1/9  1/9  1/9
1/9  1/9  1/9

Ogni pixel diventa la media dei nove pixel del suo intorno. Il risultato è morbido, ma con un difetto: produce artefatti squadrati, perché tutti i vicini contano allo stesso modo indipendentemente dalla distanza.

La sfocatura gaussiana usa pesi che decrescono con la distanza dal centro secondo una curva a campana. Il parametro raggio (o sigma) controlla l'ampiezza della campana. Il risultato è più naturale e privo di spigoli. Un vantaggio pratico: un kernel gaussiano bidimensionale si può scomporre in due passaggi monodimensionali, uno orizzontale e uno verticale, con un risparmio enorme di calcoli sui raggi grandi.

Regola importante: la somma dei pesi deve essere 1 per non cambiare la luminosità media dell'immagine. Se la somma è maggiore, l'immagine si schiarisce; se è minore, si scurisce.

Nitidezza

Aumentare la nitidezza significa enfatizzare le differenze tra un pixel e i vicini. Un kernel classico è:

 0  -1   0
-1   5  -1
 0  -1   0

La somma dei pesi è ancora 1, ma il pixel centrale viene rafforzato e i vicini sottratti. Nelle zone uniformi non cambia nulla; ai bordi la differenza viene esagerata.

La maschera di contrasto

Lo strumento di nitidezza più usato in fotografia, la maschera di contrasto (unsharp mask), funziona così:

  1. si crea una copia sfocata dell'immagine;
  2. si sottrae la copia sfocata dall'originale, ottenendo solo i dettagli;
  3. si aggiunge una frazione di questi dettagli all'originale.

I tre parametri tipici sono:

Parametro Cosa controlla
Fattore (quantità) quanto dettaglio aggiungere
Raggio la dimensione dei dettagli da enfatizzare
Soglia la differenza minima perché un pixel venga modificato, utile per non accentuare il rumore

Un raggio piccolo (meno di un pixel) rinforza la texture fine; un raggio ampio aumenta il contrasto locale. Esagerando compaiono aloni, bordi chiari e scuri attorno ai contorni.

Rilevamento dei bordi

Un kernel la cui somma dei pesi è zero produce zero nelle zone uniformi e valori alti solo dove l'intensità cambia. È il principio del rilevamento dei bordi. L'operatore di Sobel usa due kernel, uno per le variazioni orizzontali e uno per quelle verticali:

-1  0  1        -1  -2  -1
-2  0  2         0   0   0
-1  0  1         1   2   1

Combinando i due risultati si ottengono intensità e direzione del bordo in ogni punto. L'operatore laplaciano misura invece la variazione della variazione e reagisce ai bordi in tutte le direzioni insieme, ma è molto sensibile al rumore: per questo si applica di solito dopo una leggera sfocatura gaussiana.

Il problema dei bordi dell'immagine

Ai margini il kernel "esce" dall'immagine. Le strategie comuni sono:

  • estendere ripetendo i pixel del bordo;
  • riflettere l'immagine come in uno specchio;
  • avvolgere, usando i pixel del lato opposto (adatto per texture ripetibili);
  • riempire con zero, che però crea bordi scuri.

La scelta conta soprattutto con kernel grandi: una sfocatura forte con riempimento a zero produce una cornice scura evidente.

Oltre la convoluzione: il filtro mediano

Non tutti i filtri sono convoluzioni. Il filtro mediano sostituisce ogni pixel con il valore mediano del suo intorno, non con una media. È un filtro non lineare, molto efficace contro il rumore "sale e pepe", cioè pixel isolati completamente bianchi o neri, perché quei valori estremi non influenzano la mediana. A differenza della sfocatura, conserva bene i bordi netti.

Nel mio lavoro questi strumenti hanno anche un uso analitico: filtri di rilevamento dei bordi e di estrazione delle alte frequenze aiutano a evidenziare differenze di nitidezza o di rumore tra zone di un'immagine, che a occhio nudo non si notano.

In sintesi

  • Una convoluzione calcola ogni pixel come somma pesata dei vicini secondo un kernel.
  • Somma dei pesi 1: la luminosità media resta invariata; somma 0: si ottengono solo le variazioni.
  • La sfocatura gaussiana pesa i vicini in base alla distanza ed è scomponibile in due passaggi.
  • La maschera di contrasto aggiunge all'originale la differenza tra immagine e versione sfocata.
  • Il filtro mediano non è una convoluzione ed elimina il rumore impulsivo conservando i bordi.
MM
Marco Marzaduri

Marco Marzaduri si occupa di cybersecurity, informatica forense e sviluppo web. Laureato in informatica, unisce il rigore dell'analisi tecnica all'attenzione per le persone che usano la tecnologia.

Leggi anche