Elaborazione delle immagini
Uno scanner 3D sopra un nastro trasportatore fornisce una nuvola di punti: molte migliaia di punti nello spazio, disordinati, rumorosi e con lacune. Le domande che ci stanno dietro sono semplici: che cosa c'è lì? È un cilindro, un parallelepipedo, una sfera? Quanto è grande, e che volume ha?
La catena di elaborazione
- Filtrare: ritagliare l'area, sfoltire con una griglia di voxel, rimuovere i valori anomali – nella Point Cloud Library (PCL) con
CropBox,VoxelGrideStatisticalOutlierRemoval. - Rimuovere il fondo: trovare il nastro trasportatore o il pavimento come piano e sottrarlo.
- Segmentare: suddividere i punti rimanenti in singoli oggetti in base alla vicinanza, ad esempio con
EuclideanClusterExtraction. - Riconoscere la forma: adattare modelli come piano, cilindro o sfera e prendere quello con il maggior numero di punti corrispondenti.
- Misurare: determinare dimensioni, box di contenimento e volume.
RANSAC: robusto rispetto ai valori anomali
RANSAC (Random Sample Consensus) è il cavallo di battaglia dell'analisi delle nuvole di punti. Sceglie ripetutamente a caso il campione più piccolo possibile – per un piano tre punti –, ne calcola il modello e conta i punti all'interno della banda di tolleranza. Vince il modello con il maggior numero di corrispondenze; i valori anomali non trovano mai abbastanza sostenitori.
Il numero necessario di iterazioni è N = log(1 − p) / log(1 − ws), con la sicurezza p, la quota di punti corrispondenti w e la dimensione del campione s. Se il 30 % dei punti si trova sul nastro, per una sicurezza del 99 % bastano circa 170 iterazioni.
Il più piccolo box di contenimento
Per imballaggio, spazio in magazzino o smistamento conta spesso il box più piccolo attorno a un oggetto. Il box allineato agli assi dipende da come è posizionato l'oggetto, il box lungo gli assi principali (PCA) è solo un'approssimazione. Per oggetti su un nastro c'è una scorciatoia elegante, perché il box poggia sul piano del nastro. Si proiettano i punti dell'oggetto in questo piano e si cerca il rettangolo più piccolo attorno alla pianta. Secondo Freeman e Shapira un lato di questo rettangolo giace sempre su un lato dell'inviluppo convesso. Basta quindi verificare un rettangolo per ogni lato dell'inviluppo – è ciò che fanno i rotating calipers. In Python questa ricerca la svolge cv2.minAreaRect:
import numpy as np
import cv2
def ebene_ransac(punkte, schwelle=2.0, durchlaeufe=200):
"""Piano a cui la maggior parte dei punti è più vicina di 'schwelle' (mm)."""
rng = np.random.default_rng(1)
beste, beste_anzahl = None, 0
for _ in range(durchlaeufe):
p1, p2, p3 = punkte[rng.choice(len(punkte), 3, replace=False)]
n = np.cross(p2 - p1, p3 - p1)
if np.linalg.norm(n) < 1e-9: # tre punti su una linea
continue
n /= np.linalg.norm(n)
anzahl = np.count_nonzero(np.abs((punkte - p1) @ n) < schwelle)
if anzahl > beste_anzahl:
beste, beste_anzahl = (n, -n @ p1), anzahl
return beste
def vermesse_objekt(punkte, schwelle=2.0):
n, d = ebene_ransac(punkte, schwelle)
abstand = punkte @ n + d
if np.median(abstand) < 0: # la normale deve puntare lontano dal nastro
n, abstand = -n, -abstand
oben = abstand > 3 * schwelle
# Definire due assi nel piano, proiettarvi i punti dell'oggetto
u = np.cross(n, [1.0, 0, 0] if abs(n[0]) < 0.9 else [0, 1.0, 0])
u /= np.linalg.norm(u)
grundriss = np.column_stack((punkte[oben] @ u, punkte[oben] @ np.cross(n, u)))
_, (a, b), _ = cv2.minAreaRect(grundriss.astype(np.float32))
return max(a, b), min(a, b), np.percentile(abstand[oben], 99)
Per un parallelepipedo simulato di 120 × 80 × 50 mm su un nastro inclinato con 0,5 mm di rumore il codice restituisce 120,5 × 80,4 × 50,9 mm. Il 99° percentile per l'altezza attenua i singoli valori anomali.
Volume: box, inviluppo o mappa delle altezze
Il volume del box è solo un limite superiore: un cilindro riempie il suo box per poco più di tre quarti, una sfera per poco più della metà. Più preciso è l'inviluppo convesso, che però per oggetti concavi è ancora troppo grande. Poiché uno scanner dall'alto vede solo la parte superiore, il volume si calcola spesso come mappa delle altezze: per ogni cella della pianta, area per altezza sopra il nastro.
Dalla pratica
Per un produttore internazionale di sensori abbiamo sviluppato un software che nelle nuvole di punti dei suoi scanner 3D riconosce gli oggetti, ne classifica la forma – cilindro, parallelepipedo, sfera – e successivamente ne calcola rapidamente il volume. Sono stati impiegati tra l'altro RANSAC, minimal bounding box, rotating calipers e calcoli di autovalori. Ogni algoritmo lo abbiamo prima precalcolato e verificato in MATLAB, prima di implementarlo in C++ con PCL, OpenCV, Halcon ed Eigen. Abbiamo eseguito i test in laboratorio con scanner in diverse posizioni, con dati di un impianto di produzione e con una simulazione dei dati di scansione, per la quale abbiamo modellato l'allestimento in 3D.
Errori tipici
- Calcolare senza filtri. Valori anomali e riflessioni multiple gonfiano ogni box.
- Scegliere la tolleranza di RANSAC più piccola del rumore di misura – allora il metodo non trova il piano in modo affidabile.
- Presentare il volume del box come volume reale.
- Testare solo con dati di laboratorio puliti. Ne fanno parte anche i dati dell'impianto e i casi limite simulati.
Come La aiutiamo
- Studio di fattibilità: verifichiamo sui Suoi dati di scansione se riconoscimento e misura riescono con la precisione richiesta – come studio di fattibilità per l'elaborazione delle immagini a prezzo fisso.
- Algoritmi e software: dalla verifica in MATLAB fino all'implementazione in C++ o C# su PC e sistema embedded: L'elaborazione delle immagini presso Cadida.
- Il Suo progetto: Richieda un progetto o fissi un primo colloquio
Dai nostri progetti: riconoscimento di oggetti in nuvole di punti e calibrazione di scanner 3D per un produttore internazionale di sensori. Approfondimento: M. A. Fischler, R. C. Bolles, «Random Sample Consensus», Communications of the ACM 24(6), 1981; H. Freeman, R. Shapira, Communications of the ACM 18(7), 1975; Point Cloud Library.
