Usare EasyAR in un engine 3D
Per usare EasyAR in un engine 3D è necessario renderizzare l'immagine della camera e gli oggetti virtuali. Gli oggetti virtuali renderizzati devono essere allineati all'immagine della camera. Durante il rendering dell'immagine della camera, alcuni parametri della generazione dell'immagine e della visualizzazione potrebbero non corrispondere. Ad esempio, posizione, orientamento, dimensione del frame, aspect ratio e altri parametri della camera fisica possono essere diversi dall'immagine del display, e devono essere considerati durante il rendering. Se è necessario integrare EasyAR in un engine 3D non supportato, prestare particolare attenzione ai seguenti dettagli.
Ritagliare il padding dei bordi dell'immagine della camera
Il ritaglio, la trasposizione e la codifica delle immagini richiedono tutti molto calcolo. Per ridurre il calcolo e la latency, di solito si usano formati relativamente raw. Per facilitare il video encoding, le immagini prodotte dalle camere fisiche vengono spesso allineate a griglie come 8x8, 16x16, 32x32 o 64x64. Ad esempio, quando su alcuni telefoni viene selezionata una risoluzione 1920x1080, l'immagine in uscita può diventare 1920x1088, perché 1080 non è un multiplo di 64.

Questo richiede di rimuovere le parti di padding extra durante il rendering. Esistono diversi approcci possibili. Uno consiste nello specificare la larghezza quando si carica l'immagine nella memoria video, ad esempio in OpenGL usando glPixelStorei(GL_PACK_ROW_LENGTH, ...). Un altro consiste nel calcolare manualmente le coordinate UV nel fragment shader e troncare la parte eccedente durante il sampling dall'immagine.
Rendering seguendo la rotazione dello schermo
Sui telefoni, l'immagine registrata dalla camera fisica è solitamente fissa rispetto al corpo del dispositivo e non cambia con l'orientamento di visualizzazione dello schermo. Tuttavia, i cambiamenti dell'orientamento del corpo del telefono influenzano il modo in cui definiamo le direzioni alto, basso, sinistra e destra dell'immagine. Durante il rendering, anche l'orientamento di visualizzazione corrente dello schermo influisce sulla direzione dell'immagine visualizzata.
Di solito, durante il rendering è necessario determinare l'angolo di rotazione dell'immagine della camera rispetto all'orientamento di visualizzazione dello schermo.
Se \(\theta_{screen}\) rappresenta i radianti della rotazione in senso orario dell'immagine dello schermo rispetto all'orientamento naturale dello schermo, \(\theta_{phycam}\) rappresenta i radianti della rotazione in senso orario necessaria affinché l'immagine della camera fisica sia visualizzata correttamente su uno schermo in orientamento naturale, e \(\theta\) rappresenta i radianti della rotazione in senso orario necessaria affinché l'immagine della camera fisica sia visualizzata sullo schermo corrente.
Per la camera posteriore:
Ad esempio, su un telefono Android, quando il telefono viene usato nell'orientamento naturale, \(\theta_{screen} = 0, \theta_{phycam} = \frac{\pi}{2}\), quindi \(\theta = \frac{\pi}{2}\).
Per la camera frontale, se dopo il completamento della rotazione viene eseguito un flip orizzontale:
Nota
Quando l'immagine dello schermo ruota, \(\theta\) deve essere ricalcolato immediatamente nel primo frame successivo alla rotazione; altrimenti la direzione dell'immagine sullo schermo può risultare momentaneamente errata.
Rendering dello sfondo della camera e degli oggetti virtuali
Quando si renderizzano oggetti virtuali su un telefono, gli oggetti virtuali devono essere allineati all'immagine della camera. Ciò richiede di posizionare sia la render camera sia gli oggetti in uno spazio virtuale che corrisponda esattamente allo spazio reale, e di renderizzare con lo stesso field of view e aspect ratio della camera fisica. Le perspective projection transforms applicate all'immagine della camera e agli oggetti virtuali sono quasi identiche. L'unica differenza è che la maggior parte della perspective projection transform dell'immagine della camera avviene nella camera fisica, mentre la perspective projection transform degli oggetti virtuali è interamente un processo computazionale.
Di seguito vengono usate le convenzioni OpenGL. Se si usano altre convenzioni, è necessaria la mappatura corrispondente degli assi di coordinate. Si supponga che gli assi del sistema di coordinate della camera siano definiti così: l'asse x punta a destra, l'asse y verso l'alto e l'asse z verso l'esterno dello schermo. Gli assi del clip coordinate system sono definiti così: l'asse x punta a destra, l'asse y verso l'alto, l'asse z verso l'esterno dello schermo e l'asse w è un asse virtuale.
A questo punto, la matrice di perspective projection transform necessaria per renderizzare l'immagine della camera è la seguente:
Qui flip indica se l'immagine è ribaltata orizzontalmente. Il valore è 1 quando è ribaltata e 0 quando non lo è. \(\theta\) è l'angolo di rotazione in senso orario dell'immagine, in radianti. \(s_x\) e \(s_y\) sono fattori di scala usati per proportional scaling o proportional filling, e variano con \(\theta\). Questa matrice di trasformazione prima scala l'immagine della camera, poi la ruota e infine la ribalta. Durante il rendering si dovrebbe usare un rettangolo che riempie lo schermo. Ad esempio, in OpenGL i vertici del rettangolo possono essere posizionati in \((-1, -1, 0)\), \((1, -1, 0)\), \((1, 1, 0)\) e \((-1, 1, 0)\), con le coordinate UV impostate nei quattro angoli corrispondenti, quindi renderizzare usando questa matrice di perspective projection.
La matrice di perspective projection necessaria per renderizzare oggetti virtuali è la seguente:
Qui \(n\) e \(f\) sono i parametri di near clipping e far clipping normalmente usati nelle matrici di perspective projection del rendering 3D. \(w\) e \(h\) sono la larghezza e l'altezza in pixel dell'immagine della camera. \(f_x\), \(f_y\), \(c_x\) e \(c_y\) sono parametri intrinseci comuni nel modello di camera, dove \(f_x\) e \(f_y\) sono le focal length in pixel, e \(c_x\) e \(c_y\) sono le posizioni in pixel del principal point. Questa projection matrix esegue in ordine le seguenti trasformazioni: la perspective projection transform degli intrinsics della camera (poiché le direzioni degli assi y e z del sistema di coordinate immagine in OpenCV sono opposte al sistema di coordinate camera OpenGL, vengono eseguite due trasformazioni di sistema di coordinate), la trasformazione dal sistema di coordinate pixel dell'immagine al sistema di coordinate rettangolo dell'immagine, la trasformazione di near clipping e far clipping, e la perspective projection transform usata durante il rendering dell'immagine della camera.
Dopo la semplificazione, si ottiene:
Dal processo precedente si vede che il rendering di solito deve essere eseguito in due passaggi: un passaggio renderizza l'immagine della camera e un passaggio renderizza gli oggetti virtuali, con gli oggetti virtuali sovrapposti all'immagine della camera.
Alcuni engine 3D rappresentano la perspective projection matrix con parametri come horizontal field of view e aspect ratio. Se non si considerano rotazione e flip e si ignora l'offset del principal point, questi parametri possono essere calcolati: l'horizontal field of view è \(\alpha=2 arctan{\frac{w}{2 f_x}}\) e l'aspect ratio è \(r=\frac{w}{h}\).
Occorre notare che in questo processo non viene considerata la distorsione della camera, perché attualmente la distorsione della camera nella maggior parte dei telefoni è molto lieve.