R
di classe ad esempio strada, albero, veicolo, pedone, utile a riconoscere cor-
rettamente le superfici e le categorie presenti nella scena. I canali e
G B
codificano invece un identificativo univoco per ciascuna istanza di oggetti
appartenenti alla stessa classe.
8 documentazione: https://carla.readthedocs.io/en/latest/tuto_G_instance_
segmentation_sensor/ 31
Figura 3.7: Esempio di un Instance Segmentation frame ottenuto dalla simulazione
3.2.4.1 Ground Truth
Per ottenere la ground truth, ossia la posizione, la forma e l’identificativo degli
oggetti in movimento è necessario unire le informazioni provenienti sia dalla se-
mantic segmentation che dalla instance segmentation. La prima ci permette di
isolare gli oggetti in movimento, scartando quelli statici come lampioni, segnaleti-
ca. La seconda, invece, ci permette di ottenere l’ID univoco riferito agli oggetti in
movimento come pedoni e veicoli.
Particolare attenzione va riservata alla vegetazione presente nella scena, poiché
presenta delle animazioni rilevate dalla event camera ma non dalla telecamera tra-
dizionale. Questo rappresenta un problema, in quanto la event camera riconosce la
vegetazione come oggetti in movimento, mentre la telecamera tradizionale no, im-
pedendo così un confronto diretto. Tale situazione va comunque considerata anche
nell’implementazione reale: infatti, anche una leggera brezza provoca un movimen-
to delle foglie sufficientemente intenso da essere rilevato dalla event camera, mentre
per una fotocamera tradizionale questo movimento risulta impercettibile. Potreb-
be quindi essere necessario effettuare una calibrazione più aggressiva dei bias per
filtrare i piccoli sbalzi di luce dovuti al movimento delle foglie, oppure implementa-
re via software la loro reiezione. Tuttavia, questa sensibilità non rappresenta una
pecca, ma anzi può essere sfruttata per rilevare le vibrazioni in oggetti o edifici
[37].
3.3 Rilevamento frame-based
In questa sezione viene presentato l’algoritmo per il rilevamento degli oggetti in
movimento per una telecamera tradizionale, quindi frame-based. Non c’è alcu-
na differenza tra l’applicazione dell’algoritmo in scenari real-time dal dataset, in
quanto in entrambi i casi vengono forniti all’algoritmo direttamente i fotogrammi,
32
solo che nel primo caso vengono prelevati da un topic ROS2 mentre nel secondo
da una directory locale.
L’algoritmo può essere scomposto in 3 componenti in cascata, (Figura 3.8): Back-
Ground Subtraction, Operazioni morfologiche e Riconoscimento degli oggetti.
Figura 3.8: Pipeline del rilevamento frame-based.
3.3.1 Background Subtraction
Questa è la fase principale dell’algoritmo in quanto si occupa della rilevazione del
movimento, prende in ingresso l’immagine e fornisce in uscita un’immagine binaria
(foreground mask), di dimensioni pari a quella di input, in cui ogni pixel ha inten-
sità se è stato rilevato del movimento, se è invece considerato fermo e quindi
1 0
appartenente allo sfondo. La funzione che ci permette di effettuare questa ope-
9 , che implementa il metodo delle
razione è la classe BackgroundSubtractorMOG2
GMM descritto nel paragrafo 2.1.2. La classe viene inizializzata con la funzione
che ha come input:
createBackgroundSubtractorMOG2
1. history: indica la lunghezza della memoria del modello, ovvero il numero di
frame precedenti che vengono utilizzati per costruire la stima dello sfondo;
2. varThreshold: rappresenta la soglia sulla differenza tra il valore di un pixel
e il modello statistico di sfondo. Questo parametro determina se un pixel è
ben rappresentato dallo sfondo oppure se deve essere considerato parte del
foreground;
3. detectShadows: se impostato a l’algoritmo attiva un meccanismo
true,
di rilevamento delle ombre, marcandole con un’etichetta distinta nella ma-
schera di output. Tuttavia, questa opzione comporta un lieve rallentamento
dell’elaborazione e non essendo necessaria per questa tesi è stata impostata
a false.
Questa classe una volta inizializzata, ad ogni chiamata aggiornerà il
.apply()
modello e fornirà in uscita la foreground mask che verrà poi utilizzata nello step
successivo.
9 documentazione: https://docs.opencv.org/4.x/d6/d17/group__cudabgsegm.html 33
# inizializzazione
backSub = cv2.createBackgroundSubtractorMOG2(
history=500,
varThreshold=16,
detectShadows=False
)
# esempio di utilizzo
fg_mask = backSub.apply(frame)
Codice 3.4: Background Subtraction nel rilevamento frame-based
3.3.2 Operazioni morfologiche nel rilevamento frame-based
Una volta ottenuta la foreground mask è necessario rimuovere il rumore, in parti-
colare i falsi positivi introdotti dalla funzione di background subtraction, che si pre-
sentano distribuiti in modo sparso e casuale sull’immagine. Questo tipo di rumore,
detto salt-and-pepper noise, può essere filtrato tramite un’operazione morfologica
di apertura, ossia un’erosione seguita da una dilatazione, che consente di eliminare
i pixel isolati senza alterare significativamente la struttura degli oggetti rilevati.
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
mask_eroded = cv2.morphologyEx(fg_mask, cv2.MORPH_OPEN,kernel)
Codice 3.5: Operazioni Morfologiche nel rilevamento frame-based
3.3.3 Riconoscimento nel rilevamento frame-based
Per completare la fase di rilevazione è necessario individuare i vari oggetti pre-
senti nella foreground mask. Questo processo viene svolto attraverso la funzione
che rileva i contorni all’interno di un’immagine binaria. Vengono
findCountours,
poi scartati gli oggetti che hanno una dimensione inferiore a una soglia predefinita
perché indicano dei falsi positivi o oggetti troppo piccoli che non siamo interes-
sati a rilevare. Questa soglia va definita in base all’uso di questo algoritmo: un
valore troppo basso non elimina efficacemente il rumore, mentre un valore ecces-
sivamente alto rischia di escludere oggetti validi ma di piccole dimensioni. Una
volta ottenuti i contorni validi, per ognuno si calcola la bounding box attraverso la
funzione Le coordinate dei due vertici opposti (quello in basso a
boundingRect.
sinistra e quello in alto a destra) delle bounding box vengono salvate in un array,
input dell’algoritmo di tracking. Ogni elemento dell’array include anche un valore
di attendibilità della rilevazione, richiesto dall’algoritmo di tracking utilizzato in
questa tesi, ossia SORT. Poiché non è possibile calcolare questa metrica, questo
valore viene impostato a 1, ovvero il massimo, indicando che tutte le rilevazioni
hanno lo stesso peso. 34
contours, _ = cv2.findContours(mask_eroded, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
→
, detections = []
for cnt in contours:
if cv2.contourArea(cnt) > min_contour_area:
x, y, w, h = cv2.boundingRect(cnt)
detections.append([x, y, x+w, y+h, 1.0])
Codice 3.6: Riconoscimento degli oggetti nel rilevamento frame-based
3.4 Rilevamento event-based
In questa sezione viene presentata la pipeline sviluppata per il rilevamento di ogget-
3.9). L’algoritmo è strutturato
ti in movimento tramite una event-camera (Figura
in quattro fasi principali: decodifica degli event packet, accumulo degli eventi,
operazioni morfologiche e riconoscimento degli oggetti. In particolare, sono stati
sviluppati due approcci distinti per la fase di riconoscimento, dando origine a due
varianti che condividono la stessa struttura di base. Infatti entrambi i metodi si
basano sul presupposto che, in assenza di ego motion, la generazione di un evento
sia dovuta esclusivamente al movimento di un oggetto, ad eccezione del rumore
o cambi di luminosità nella scena. Questo consente di ottenere direttamente la
foreground mask tramite l’hardware stesso della event camera, senza dover ricor-
rere alla background subtraction a livello software, come avviene nella rilevazione
tradizionale.
Inoltre, a differenza dell’algoritmo per telecamera tradizionale, in questo caso esi-
ste una differenza tra l’applicazione su dataset e quella in real-time. Nel caso
del dataset, gli eventi sono già stati accumulati e salvati in file di testo, pronti
per essere elaborati direttamente. Nel contesto real-time invece, è necessario pri-
ma decodificare gli eventi ricevuti all’interno degli event packet e successivamente
accumularli. Figura 3.9: Pipeline del rilevamento event-based
3.4.1 Decoder event-camera
Il decoder degli eventi è fornito dallo stesso sviluppatore del metavision-driver,
10 . Una volta inizializzata la classe
attraverso la libreria Python event_camera_py
10 Per la documentazione completa: https://github.com/ros-event-camera/event_
camera_py 35
è sufficiente utilizzare il metodo direttamente sul messaggio
Decoder, .decode
ricevuto dal topic ROS su cui il metavision-driver pubblica. Gli eventi ottenuti
possono poi essere convertiti in un array di dimensione [N, 4], in cui ogni riga
rappresenta un evento strutturato come e = [ x , y , p , t ]. In questo modo, i
i i i i i
dati risultano facilmente elaborabili nelle fasi successive.
# inizializzazione
decoder = Decoder()
# esempio di utilizzo
decoder.decode(ros_msg)
cd_events = self.decoder.get_cd_events()
if cd_events is None or cd_events.size == 0:
return
cd_events = np.asarray(cd_events.tolist(), dtype=np.float32)
Codice 3.7: Decoding degli event Packet
3.4.2 Metodi per l’accumulo degli eventi
Gli eventi contenuti in un singolo eventPacket non forniscono un quantità di infor-
mazioni sufficiente per essere elaborati dall’algoritmo di rilevazione, che lavorano
sul raggruppamento dei pixel in cui si è individuato del rumore. Risulta quin-
di necessario accumulare gli eventi in modo da ottenere un immagine più densa.
Esistono diversi approcci per l’accumulazione degli eventi, in base al [38]:
• Tempo: si accumulano gli eventi per un intervallo di tempo prefissato.
Questo è il modo in cui si ottengono gli pseudo-frame.
• Numero: gli eventi vengono accumulati in un buffer fino al raggiungimento
di una soglia prefissata. Una volta raggiunta la soglia questi eventi vengono
processati. A differenza dell’accumulo temporale, qui l’elaborazione avviene
in modo asincrono, poiché il tempo necessario per raggiungere la soglia di-
pende dal movimento presente nella scena. In scenari con poco movimento,
la frequenza di elaborazione sarà bassa, mentre in presenza di rapido mo-
vimento questa aumenterà. È una strategia particolarmente adatta al trac-
ciamento, poiché consente una risposta rapida ai cambiamenti veloci nella
scena, riducendo il rischio di perder
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.