Calcolo dell'Area

Progetto del corso Elaborazioni delle immagini

Il progetto del corso Elaborazione delle immagini ha come obbiettivo il calcolo e l'analisi dell'immagine aerea di un appezzamento di terra.
L'appezzamento in questione è la casa di campagna del nonno e l'immagine aerea usata è stata presa da google maps




Elaborazione Preliminare:

Per prima cosa ho rimosso manualmente tutto il terreno che non fa parte dell'area da calcolare.
Dal momento che il progetto si propone di analizzare in dettaglio l'area all'interno del giardino, si è preferito rimuovere manualmente velocemente il vicinato: una tra le ragioni di questa scelta risiede nella difficoltà che si sarebbe incontrata nella divisione sul confine sud (sinistra nell'immagine). Infatti il confine è delimitato da una sottile rete metallica e la qualità dell'immagine non permette una soluzione veloce e soddisfacente al problema.




Successivamente sono state filtrare le varie aree da analizzare: queste sono state suddivise in macro-regioni:

  • Prato
  • Casa
  • Alberi
  • Strada
  • Orto


La campionatura è stata molto semplice, con lo strumento "bacchetta magica" (che molti software permettono) si selezionano in base alla vicinanza di colore, tutti i px interessati. Salvandoli singolarmente avremo quindi un immagine singole dove posso trovare ad esempi tutti i colori del tetto, un immagine dove posso trovare quasi tutti i colori del prato, ecc.

Soluzione I "la sbrigativa"

L'analisi preliminare ci ha fornito le immagini base attraverso le quali proseguiremo con il calcolo dell'area, tanto quella dell'intero terreno quanto della di ogni regione specifica.
Per attacare computazionalmente il problema si è scelto il linguaggio di programmazione C#
Come indicato nell'Elaborazione Preliminare, le macro-regioni individuate per il terreno sotto investigazione sono Prato, Casa, Alberi, Strada ed Orto.
Il fulcro del programma è rappresentato da un oggetto Dictionary, impigato per salvare la coppia colore macroregione. In verità alle macro-regioni nell'implementazione dell'oggetto Dictionary si aggiungono anche le variabili mix, usata per identificare quei colori che sono condivisi da più regioni simultanamente, e unknown che serve ad identificare quei pixel che non possono essere associati ad alcuna area (sui quali, per esempio, non abbiamo alcuna informazione).


La funzione che estrare i px di una certa regione e li salva nel grosso "database" di tutti i colori.

OUTPUTS

In questa sezione presentiamo le immagini relative ai vari elementi (o macro-aree) identificati dal programma. Per ogni regione visualizziamo solo quei pixel che rientrano nell'insieme di valori associati a tale macroregione.

- Insieme dei pixels riconosciuti come "tetto"
- indipendentemente dal valore originale (cioè quale sfumatura di rosso), a ogni pixel è assegnato il valore red.
In modo simlare si procede con le altre regioni.




Visualizzazione dei pixels che sono in quel set di valori riconosciuti come "tetto" e come "orto".



Visualizzazione di tutte le aree:

  • Si noti come i pixel arancioni siano in gran numero
    questi sono i colori di tipo mix, cioè quelli che ritrovo in più aree e quindi non univocamente assegnabili a questa o quella regione.
  • Si noti anche che ci sono anche molte aree bianche
    Si tratta di quei pixel sui quali non sono disponibili informazioni.

 


Propagazione del Colore

Una veloce soluzione del problema white pixels, cioè quelle zone senza mappatura del colore, è far ricorso a quello che potremmo chiamare principio di continuità e contiguità
Fino a che non incontro un pixel di un colore ben definito, ipotizzo di trovarmi nella stessa regione dell'ultimo pixel noto.
Salvo in memoria l'ultimo colore utilizzato per assegnarlo a vicino pixel bianco.



Sbavature Cicliche

Visto che il programma elabora l'immagine con due cicli for innestati, si notano molto le sbavature dovute all'andamento del ciclo (dall'alto al basso).

Una soluzione per ovviare a questo problema: "raddrizzo" l'immagine così che i cicli innestati lavorano meglio.



Il risultato ottenuto è decisamente migliore ma ci sono ancora tante zone indecise.Per ovviare al problema cerco con un filtro mediano di smussare i picchi e omogeneizare i colori.



Il risultato ottenuto non è soddisfacente, cerco quindi un altre strade per smussare i colori, modificando grazie a filtri l'immagine originale.

Soluzione II "filtro Region Growing"

Il primo passo è stato analizzato l'istogramma, si vede che la maggior parte dell'informazione è tra 30 e 190. Grazie ad un filtro espando l'output da 0 a 255.



Il secondo passo è stato usare un filtro mediano per creare un effetto blur e omogeneizzare i colori



Con la nuova immagine elaborata faccio di nuovo girare il programma.



L'output prodotto è però fallimentare, infatti le immagini di campionamento sono rimaste originali.

Aggiornato anche le immagini di campionamento l'output prodotto è adesso migliore dell'immagine non elaborata.



Il problema adesso sembra la presenza troppo invasiva del colore "alberi" nella nuova campionatura.



Ricampiono il colore degli alberi. Adesso il risultato è migliore.



Le aree di mix (colorate di arancione) dopo i vari filtri sono decisamente diminuite, le aree bianche invece sono rimaste con aree importanti.

Per cercare di ovviare al problema creo un piccolo script che può assomigliare ad un Region Growing o ad un filtro mediano:


Lo script funziona con una maschera (3x3) e passa tutta l'immagine. Il primo passo è il controllare che il px sia arancione o bianco [ovvero colore mix oppure informazione mancante] se si provo quindi a guardare i suoi vicini.

Se la maggior parte dei miei vicini sono tutti di prato, probabilmente anche il px selezionato sarà prato.

Se non riesco a capire con una maschera 3x3 aumento con una maschera 5x5. Se anche con una maschera 5x5 provo con una maschera 7x7.

Se nemmeno con la maschera 7x7 non allargo a 9x9 poichè per mancanza di memoria del mio pc il programma va in blocco!

Una volta che la funzione ha finito tutta l'immagine, riparte rianalizzando e cercando di erodere le zone di margine.



Ho fatto fare il ciclo 20 volte, per ogni volta ho scaricato la foto. In sequenza:

(1)
(2)
(3)

(4)
(5)
(6)

(7)
(8)
(9)

(10)
(11)
(12)

(13)
(14)
(15)

(16)
(17)
(18)

(19)
(20)
(21)


L'animazione del processo
Refresh image

Dopo 20 passate del filtro i tetti, la strada e gli alberi sono abbastanza definiti e veritieri, coloro quindi di "prato" le rimanenti zone bianche che il filtro non è riuscito a calcolare. La velocità "di riempimento dei buchi" del filtro come si vede dall'immagine è più veloce all'inizio per poi diminuire.



Questa sequenza è il numero dei px bianchi per ogni iterazione, la sequenza risulta tagliata ma si nota che all'inizio l'algoritmo converte più px bianchi, poi man mano che procede ne modifica sempre meno ...


Prendendo la legenda di google calcoliamo che 11,50 m sono 115px. (purtroppo ho cancellato la foto originale con la scala e ho dovuto ricalcolarla in modo approssimativo)


11.50m*11.50m = 132 m² oppure in px 115px*115px=13225 px²

Se divido tutto per 132 ottengo:

  • 132/132 = 1 metro
  • 13225/132= 100,1893939393939 px

Ogni 100px è come se avessi 1m²

Non ci resta che calcolare i metri quadrati dividendo il numero dei px di ogni regione per 100,18:

  • Prato: 184075px = 1837,27 m²
  • Tetti: 34396px = 343 m²
  • Strada: 49353px = 492 m²
  • Alberi: 177889px = 1775 m²
  • Orto: 12718px = 127 m²
  • Vicinato: 420101px = 4193 m²
  • Errori: 11388px = 113 m²
  • Immagine analizzata 469819px = 4689 m²
  • Immagine Totale (compreso il vicinato non conteggiato) 889920px = 8882 m²

Elaborando tutti i dati con un grafico a torta:



Per invece avere un riscontro almeno grossolano, ho confrontato con i dati direttamente di google maps.



Facendo un confronto con google:
Misura distanza
Fai clic sulla mappa da aggiungere al tuo percorso
Superficie totale: 4.095,28 m² vs 4689 m²
Distanza totale: 279,54 m

Conclusioni:

Con questo progetto ho cercato inizialmente a non elaborare l'immagine pensando che lo script potesse essere abbastanza potente e "capire" le varie zone.

Invece la difficolta di campionare in base ai colori (infatti vi sono tante zone di mix oppure senza informazioni) ha reso necessario un pre-processo di elaborazione dell'immagine per rendere più omogenei i colori (e quindi più facilmente riconoscibili successivamente).

Il progetto, per quanto semplice mi ha posto davanti ad alcune difficolta, le più importanti sono state:

  • Difficolta di campionamento: Il fatto che il programma non riconosce tutti i px campionati o vi sono dei colori che sono condivisi tra più zone. Soluzione: Applicare dei filtri (il mediano in questo caso) per smussare i colori e renderli più uniformi.
  • Script locale: Lo script è una maschera che viaggiando per tutta l'immagine cerca i punti "mix" o "bianchi" e quindi prova di dare un colore conforme ai px vicini. Soluzione: ho provato ad aumentare la maschera (parte da un 3x3 e si espande automaticamente fino ad un 7x7) ma ci vorrebbe uno script più inteligente. (Per esempio che riempia uno spazio bianco se sono completamente circondato in un campo oppure che non capisca come errore pochissimi px del tetto che per sbaglio sono stati campionati nel mezzo del prato)

In questo caso l'elaborazione dell'immagine si è resa necessaria, non tanto per ottenere la precisione del singolo px ma per avere una visione d'insieme e ad ottenere un buon risultato.




Tutto il codice


Tutto il programma in C# per Visual Studio Scarica lo .zip