Linee fisse

Riepilogo

L'opzione Linee terrestri è un esperimento che consente di esplorare le immagini satellitari di Google Earth tramite gesti. Utilizzando una combinazione di machine learning, ottimizzazione dei dati e potenza della scheda grafica, l'esperimento può essere eseguito in modo efficiente sul browser web del telefono senza bisogno di server di backend. Questo è uno sguardo al nostro processo di sviluppo e ai vari approcci che abbiamo provato per portarci al risultato finale.

https://g.co/LandLines

Quando il team di Data Arts mi ha contattata per esplorare un set di dati di immagini della Terra era entusiasmante: le immagini erano meravigliose, rivelando tutti i diversi tipi di strutture e texture, sia realizzate dall'uomo che naturali, e ero incuriosito su come collegare questo set di dati. Ho fatto vari esperimenti iniziali esaminando la somiglianza tra le immagini e i vari modi per filtrarle e organizzarle.

layout somiglianza t-sne
Layout di similitudine t-sne, alta risoluzione 50 mb

Come gruppo continuavamo a tornare alle linee belle e dominanti nelle immagini. Queste linee erano facili da individuare (autostrada, fiumi, bordi di montagne e appezzamenti di terra) e abbiamo progettato alcuni progetti per esplorarle. Come artista, sono stata ispirata dalle belle cose che puoi fare con le raccolte di righe, ad esempio il lavoro di Cassandra C Jones con i fulmini, ed è stata entusiasta di lavorare con questo set di dati.

Rilevamento linee

Una delle sfide iniziali era come rilevare le linee nelle immagini. È facile prendere un foglio di carta da ricalco, gettarlo sopra una stampa di una di queste foto e tracciare le linee che l'occhio vede. Tuttavia, in generale, gli algoritmi di visione artificiale per trovare le linee tendono a non funzionare bene in immagini molto diverse.

Ho sviluppato una versione precedente della ricerca disegnando un algoritmo su un progetto con Progetti locali e per questo abbiamo annotato manualmente le righe da cercare. È stato divertente disegnare sulle opere d'arte, ma è noioso quando passi da decine di immagini a migliaia di immagini. Volevo provare ad automatizzare il processo di ricerca delle righe.

Con queste immagini aeree ho provato gli algoritmi di rilevamento delle linee tradizionali come l'algoritmo di rilevamento dei bordi pericolosi di openCv, ma ho scoperto che fornivano segmenti di linea molto discontinui o, se la soglia era troppo rilassata, un sacco di linee errate. Inoltre, le soglie per ottenere buoni risultati erano diverse per set di immagini diverse e volevo un algoritmo per trovare un insieme coerente di buone linee senza supervisione.

Ho sperimentato una varietà di algoritmi di rilevamento delle linee, inclusi quelli recenti, come gPb (PDF), che, sebbene producesse risultati sorprendenti, richiedeva minuti per l'esecuzione di ogni immagine. Alla fine, ho optato per Structured Forest Edge Detection, un algoritmo fornito con openCV.

Una volta creata una buona "immagine lineare", continuavo ad avere il problema di ottenere le linee e identificare le singole linee l'una dall'altra, ovvero come posso trasferire questi dati raster e renderli vettoriali. Spesso quando esamino i problemi di visione artificiale, mi occupo di imageJ, un ambiente di elaborazione di immagini open source basato su Java e utilizzato da scienziati e ricercatori che dispone di un sano ecosistema di plug-in. Ho trovato un plug-in chiamato Rilevamento dei Rilievi, che aiuta a prendere un'immagine di intensità e a trasformarla in un insieme di segmenti di linea. (Inoltre, ho trovato utile anche il codice di rilevamento ed etichettatura dei bordi di Matlab).

Immagine con segmenti di linea rilevati
Immagine con segmenti lineari rilevati

Serverless

Volevo anche vedere se fosse possibile realizzare un'app di visualizzazione dei dati essenzialmente serverless, in cui il duro lavoro di abbinamento e connessione avviene sul lato client. Di solito lavoro in openFrameworks, un framework c++ per la codifica delle creatività e, oltre ai progetti occasionali node, non ho eseguito molta programmazione lato server. Mi chiedevo se fosse possibile fare tutto il calcolo lato client e utilizzare il server solo per fornire dati JSON e immagini.

Per l'applicazione di disegno, la corrispondenza è un'operazione molto impegnativa. Quando tracci una linea, dobbiamo trovare la corrispondenza più vicina tra decine di migliaia di segmenti di linee. Per calcolare la distanza tra un disegno e un altro, utilizziamo una metrica del riconoscimento dei gesti di dollari, che a sua volta prevede molti calcoli della distanza. In passato ho usato il threading e altri trucchi, ma per farlo funzionare in tempo reale su un dispositivo client (inclusi i cellulari) avevo bisogno di qualcosa di meglio. Ho cercato gli alberi metriche per trovare i vicini più vicini/più vicini e ho optato per gli alberi di punti panoramici (implementazione JavaScript). L'albero dei punti di osservazione in pratica viene creato a partire da un insieme di dati e una metrica di distanza e se inserisci un nuovo insieme di dati ti fornisce rapidamente un elenco dei valori più vicini. La prima volta che ho visto questo lavoro su un cellulare ho subito un'esplosione. Uno dei grandi vantaggi di questa particolare implementazione dell'albero dei punti panoramici è la possibilità di salvare l'albero dopo averlo calcolato e risparmiare sui costi di calcolo di questo albero.

Risultati più vicini Risultati tracciati
Esempi di risultati dell'albero del punto di osservazione, l'input disegnato si trova sul lato destro e i risultati più vicini sono a sinistra.

Un'altra sfida per far funzionare il servizio senza un server è il caricamento dei dati su un dispositivo mobile. Per il disegno, i dati del segmento di albero e delle linee erano superiori a 12 MB e le immagini sono molto grandi, volevamo che l'esperienza fosse veloce e reattiva e l'obiettivo era cercare di ridurre il download. La nostra soluzione era caricare progressivamente i dati. Nell'app di disegno suddividiamo il set di dati dell'albero dei punti di osservazione in 5 parti. Quando l'app carica, carica solo il primo blocco e poi ogni 10 secondi carica un altro blocco di dati in background. In pratica, l'app migliora sempre di più nel primo minuto di utilizzo. Nell'app di trascinamento è stato anche eseguito un intenso lavoro di memorizzazione nella cache delle immagini in modo che, man mano che le trascini, venivano caricate nuove immagini in background.

Infine, ho trovato più difficile del previsto: creare un preloader per entrambe le app, quindi sarebbe comprensibile il ritardo iniziale del caricamento dei dati. Ho utilizzato il callback di avanzamento per le richieste Ajax e, sul lato pixi.js, per controllare che le immagini caricate in modo asincrono siano state effettivamente caricate e utilizzarlo per trasmettere il messaggio di precaricamento.

Linea connessa

Per il trascinamento, volevo creare una linea infinita dalle linee che abbiamo trovato nel rilevamento dei bordi. Il primo passaggio è stato quello di filtrare le linee dall'algoritmo di rilevamento delle linee e identificare le linee lunghe che iniziano su un bordo e terminano su uno degli altri tre bordi.

Le linee di collegamento corrette sono contrassegnate in rosso Le linee di collegamento corrette sono contrassegnate in rosso
Le linee corrette per i collegamenti sono contrassegnate in rosso

Dopo aver creato un insieme di linee lunghe (o, per usare un termine più preciso, polilinee, un insieme di punti connessi) per collegarle, le ho convertite in un insieme di cambiamenti di angoli. Di solito, quando si pensa a una polilinea, la si immagina come un insieme di punti: il punto a è connesso al punto b, che è connesso al punto c. Puoi invece considerare la linea come un insieme di variazioni angolari: spostati in avanti e ruota di una certa entità, avanti e ruota un po'. Un buon modo per capire questo concetto è pensare alle piegatrici, che prendono un pezzo di filo e mentre viene estruso eseguono rotazioni. La forma del disegno deriva dalla rotazione.

Se consideri la linea come modifiche di angolo e non come punti, diventa più facile combinare le linee in un'unica linea più grande con meno discontinuità. Invece di unire i punti, si tratta essenzialmente di aggiungere modifiche dell'angolo relativo. Per aggiungere una linea, prendi l'angolo corrente della linea principale e aggiungi le modifiche relative alla linea che vuoi aggiungere.

Come nota a margine, ho utilizzato questa tecnica per convertire una linea in un insieme di cambi di angolo per scopi artistici: puoi creare disegni "arricciati" in modo simile a come i cavi possono arricciarsi e arricciarsi. Alcuni esempi: uno, due, tre

Il calcolo dell'angolo ci consente di sterzare la linea man mano che la trascini. Calcoliamo la distanza dell'angolo principale dal punto in cui vogliamo arrivare e cerchiamo un'immagine che consenta di orientare al meglio la linea nella direzione giusta. È tutta una questione di pensare relativamente.

Infine, vorrei dire che è stato un progetto davvero divertente con cui collaborare. Per un artista è entusiasmante ricevere la richiesta di utilizzare un set di dati tanto bello come queste immagini. Per me è un onore che il team di Data Arts ci ha contattato. Spero che ti divertirai a provarla.