5.22. Correzione dell’obiettivo e della prospettiva¶
Due classi di correzione geometrica deformano l’immagine in modi che una mappatura da rettangolo a rettangolo non può ottenere. La correzione dell’obiettivo annulla la distorsione radiale introdotta da un vero obiettivo grandangolare – il rigonfiamento fisheye che piega le linee rette della scena in curve visibili vicino agli angoli del frame. La correzione della prospettiva annulla l’effetto keystone che si verifica quando l’obiettivo non è puntato perpendicolarmente alla scena – la deformazione trapezoidale che trasforma un rettangolo noto nel mondo reale in un blob non rettangolare nell’immagine. Entrambe le correzioni annullano, dopo che l’acquisizione è completata, effetti di origine ottica.
5.22.1. Distorsione radiale dell’obiettivo¶
Il materiale su gli effetti reali dell’obiettivo descrive la distorsione a barile introdotta dagli economici obiettivi grandangolari. I pixel vicini al centro del frame sono all’incirca dove il modello pinhole prevede; i pixel vicini ai bordi sono incurvati verso l’esterno di una quantità che cresce con il quadrato della distanza radiale dall’asse ottico. Una linea retta nella scena che corre vicino al bordo del frame si curva visibilmente nell’immagine acquisita, e qualsiasi algoritmo classico di visione artificiale che presuppone che le linee rette restino rette – il rilevamento degli angoli AprilTag, l’inseguimento dei bordi, la navigazione a inseguimento di linea – ottiene la risposta sbagliata vicino agli angoli.
lens_corr() annulla la distorsione. Il metodo esegue la mappatura inversa: ogni pixel di output viene campionato dalla posizione nell’input da cui l’obiettivo lo avrebbe incurvato verso l’esterno, e il risultato è un’immagine geometricamente diritta.
img.lens_corr(strength=1.8)
Il parametro strength è il cuore della correzione. È un singolo numero che descrive con quanta intensità l’obiettivo incurva; un valore vicino a 1.0 è una correzione lieve per un obiettivo moderatamente grandangolare, e valori fino a circa 2.0 sono ragionevoli per un fisheye marcato. Il valore predefinito di 1.8 è un buon punto di partenza per gli obiettivi di serie della OpenMV Cam; il valore giusto per un obiettivo specifico è una questione di provarne alcuni e osservare l’immagine.
I due parametri laterali vanno di solito bene con i loro valori predefiniti. zoom (predefinito 1.0) ridimensiona l’output – un valore maggiore di uno ritaglia verso l’esterno per compensare il modo in cui la correzione dell’obiettivo spinge gli angoli ancora più all’esterno; valori più piccoli lasciano visibile una porzione maggiore della scena corretta al costo di includere pixel vuoti ai bordi dell’immagine. x_corr e y_corr spostano il centro della correzione lontano dal centro geometrico dell’immagine, il che è utile quando l’obiettivo non è otticamente centrato sopra il sensore (un caso insolito, ma utile da conoscere).
Una pipeline tipica: acquisire, eseguire lens_corr() una volta per raddrizzare la geometria, quindi eseguire ciò che l’applicazione effettivamente fa con il risultato.
5.22.2. Correzione della rotazione 3D¶
L’altra classe di distorsione geometrica è la deformazione prospettica che si verifica quando il piano del sensore non è parallelo al piano della scena. Il caso classico è un cartello o una targa visti dal basso: la parte superiore del cartello è più lontana dall’obiettivo rispetto a quella inferiore, quindi si proietta più piccola, e l’immagine acquisita mostra il rettangolo come un trapezio con il bordo superiore più corto di quello inferiore.
La soluzione consiste nell’applicare una rotazione 3D al frame acquisito che riorienta virtualmente il piano del sensore in modo che sia parallelo al piano della scena. La matematica è la stessa mappatura prospettica che il rilevamento AprilTag usa per ricavare la posa di un tag dai suoi quattro angoli, eseguita al contrario: data una rotazione, l’operazione rimappa ogni pixel di output alla posizione di input da cui la rotazione sarebbe provenuta.
rotation_corr() esegue tale correzione:
img.rotation_corr(x_rotation=10.0, y_rotation=0.0, z_rotation=0.0)
I tre parametri di rotazione sono in gradi e descrivono le rotazioni attorno agli assi x, y e z di una camera virtuale centrata sull’immagine. x_rotation inclina la camera verso l’alto o il basso (la correzione naturale per uno scatto a livello del suolo di una parete); y_rotation ruota la camera a sinistra o a destra; z_rotation ruota la camera attorno al proprio asse ottico (la correzione naturale per un montaggio non a livello).
x_translation e y_translation spostano la camera virtuale lateralmente senza ruotarla. zoom (predefinito 1.0) ridimensiona l’output. fov (predefinito 60.0) descrive il campo visivo verticale della camera, usato per calcolare la proiezione – il valore dovrebbe corrispondere all’obiettivo reale per mantenere la geometria coerente.
Per una combinazione arbitraria di inclinazione e rotazione orizzontale, più rotazioni non nulle si compongono in una sola chiamata. L’ordine delle operazioni è fisso all’interno dell’implementazione; l’applicazione fornisce semplicemente gli angoli e il risultato viene prodotto.
5.22.3. Rettifica di un rettangolo noto¶
La forma più comunemente utile di rotation_corr() è la parola chiave corners=, che accetta una lista di quattro tuple (x, y) che descrivono gli angoli di un rettangolo noto nell’immagine di input. Il metodo calcola quale rotazione 3D avrebbe mappato un vero rettangolo a quei quattro punti specifici, applica l”inverso di quella rotazione all’intera immagine e restituisce un risultato in cui il rettangolo noto torna a essere rettangolare:
plate_corners = [(45, 80), (300, 60), (310, 180), (40, 200)]
img.rotation_corr(corners=plate_corners)
L’uso classico è esattamente ciò che il nome suggerisce: una targa (o qualsiasi altra caratteristica rettangolare) fotografata da un angolo obliquo. Uno stadio a monte rileva la targa e riporta le posizioni dei suoi quattro angoli nell’immagine acquisita; passando quegli angoli a rotation_corr() si produce un’immagine in cui la targa appare come un vero rettangolo, pronta per qualsiasi stadio di riconoscimento dei caratteri o template matching che segue.
Quando la forma a quattro angoli risolve il problema che un’applicazione sta cercando di risolvere, è notevolmente più utile della forma a sei parametri. L’applicazione non deve stimare alcun angolo di rotazione; passa semplicemente al metodo quattro punti e lascia che il metodo capisca il resto. La forma a sei parametri è utile quando nella scena non è visibile alcun rettangolo identificabile e la rotazione deve essere regolata manualmente a partire da conoscenze esterne (un angolo di montaggio calibrato, ad esempio).