Come non proiettare il quadrilatero nel rettangolo?


10

tl; dr: Problema matematico nella geometria proiettiva: come si trova una matrice di telecamere 4x4 che fornisce una proiezione come illustrato di seguito, in modo che i punti A, B, C, D si trovino da qualche parte ai bordi della scatola dell'unità (ad es. dispositivo normalizzato OpenGL coordinate), e gli angoli del box unitario rientrano in un punto ragionevole lungo i raggi EA, EB, EC, ED?

(Questo potrebbe essere un caso speciale forse di omografia, prospettiva e / o collineazione. Non ha familiarità con la terminologia.)


elaborazione

Dato un ABCD quadrilatero all'interno del viewport, penso che esista una trasformazione unica (?) Che lo mappa su un rettangolo. Come si vede nell'immagine qui sotto: il quadrilatero ABCD nella finestra funge da 'finestra' fisica e se lo mappiamo su un rettangolo sembrerà distorto.

inserisci qui la descrizione dell'immagine

(la casella a destra rappresenta NDC, di cui parlerò più avanti)

L'obiettivo è ottenere rapidamente l'immagine sulla destra. Potremmo tracciare ogni punto per ottenere l'immagine (cosa che ho fatto), ma preferirei usare OpenGL o altre tecniche proiettive perché volevo approfittare di cose come la fusione, le primitive, ecc.

primo tentativo

Credo di poter risolvere il problema di trovare la matrice della fotocamera 3x4 che rende la coordinata omogenea 3 + 1 dimensionale nello spazio 3 (a sinistra) e la proietta fino alle coordinate omogenee 2 + 1 nello spazio 2 (su la destra). Si può risolvere questo usando la trasformazione lineare diretta per ottenere un sistema di equazioni Ba=0per le voci sconosciute adella matrice della telecamera e risolvere il sistema usando la scomposizione di valori singolari(SVD). Vorrei prendere i vettori EA, EB, EC, ED (dove E è il tuo occhio fisico o la fotocamera nello spazio del mondo) come punti nella pre-immagine, e (0,0), (1,0), (1 , 1), (0,1) o qualcosa del genere come punti nell'immagine post, e ogni coppia di punti darebbe alcune equazioni lineari da collegare all'SVD. La matrice risultante mapperebbe EA -> (0,0) ecc. (Supponendo che ci siano abbastanza gradi di libertà, ad esempio se la soluzione è unica, di cui non sono sicuro, vedere la nota [a].)

Ma con mio dispiacere non è così che funziona OpenGL. OpenGL non proietta direttamente 3d a 2d con una matrice 3x4. OpenGL richiede "coordinate dispositivo normalizzate" (NDC), che sono punti tridimensionali. Dopo la proiezione in NDC, viene disegnato tutto nella casella 'unit' da (-1, -1, -1,1) a (1,1,1,1); tutto all'esterno è troncato (poiché abbiamo a che fare con coordinate omogenee: qualsiasi punto (x, y, z, w) apparirà sullo schermo solo se le prime tre coordinate di (x / w, y / w, z / w , 1) si trovano nella casella unità da -1 a 1).

Quindi la domanda diventa: esiste una trasformazione ragionevole che mappa alcuni cuboidi dall'aspetto strano in coordinate omogenee (in particolare il cuboide disegnato a sinistra, con ABCD (punti anteriori) e A'B'C'D '(punti posteriori, nascosti dietro i punti anteriori)) al cubo dell'unità, ad esempio utilizzando una matrice 4x4? Come si fa?

quello che ho provato

Ho provato qualcosa di più forte: ho fatto apparire ABCD e A'B'C'D come un normale frustrazione piramidale (ad esempio gl frustrum) (cioè in questa ipotetica configurazione, l'immagine a sinistra avrebbe solo un rettangolo nero sovrapposto a esso, non un quadrilatero), e quindi ha usato la trasformazione lineare DLT / diretta per risolvere la presunta matrice 4x4. Tuttavia, quando l'ho provato, non sembravano esserci sufficienti gradi di libertà ... la matrice 4x4 risultante non ha mappato ogni vettore di input su ogni vettore di output. Durante l'utilizzo di A, B, C, D, A '(5 coppie di vettori pre-trasformazione e post-trasformazione), I / quasi / ottengo il risultato desiderato ... i vettori sono mappati correttamente, ma per esempio B', C ', D' sono mappati su (3,3,1,1) invece di (-1, -1,1,1) e sono tagliati via da OpenGL. Se provo ad aggiungere un sesto punto (6 coppie di punti per la matrice 4x4 da proiettare), la mia soluzione sembra degenerata (zero, infiniti). Di quanti gradi di libertà ho a che fare qui, ed è possibile con una matrice 4x4 mappare i soliti 4 vettori (vettori a coordinate omogenee 3 + 1) che conosciamo e amiamo?

pensieri minori casuali

Immagino che non sia possibile mappare alcun cuboide arbitrario a qualsiasi cuboide arbitrario con una matrice 4x4, anche se sono confuso perché pensavo che fosse possibile mappare qualsiasi quadrilatero convesso a qualsiasi altro quadrilatero convesso in 2d con una matrice come in , diciamo, Photoshop? ... non si può / non si può fare con una trasformazione proiettiva? E come si generalizza al 3d? ...... Dato anche il tentativo fallito di trovare una matrice 4x4, l'algebra lineare dice che non dovremmo aspettarci che una matrice NxN mappi più di N punti linearmente indipendenti su N punti bersaglio nel migliore dei casi, ma ritengo che in qualche modo omogeneo le coordinate imbrogliano perché c'è una colinearità nascosta in corso? Non credo?

un'altra soluzione?

Immagino che uno potrebbe anche fare la seguente brutta cosa, in cui usi una tipica matrice di proiezione della fotocamera frustrum, trovi i punti 2d corrispondenti agli angoli, quindi esegui una prospettiva 2D distorta, ma se ciò dovesse accadere dopo che i pixel sono stati resi (ad es. Photoshop) allora ci sarebbero problemi con la risoluzione ... forse ipoteticamente si potrebbe capire una matrice per eseguire questa trasformazione sul piano XY nello spazio NDC, quindi comporla con la normale matrice basata su frustrum?

(nota [a]: grado di libertà: ABCD può essere ulteriormente limitato per essere la post-immagine di una trasformazione proiettiva che agisce su un rettangolo, se ciò è necessario ... cioè il rettangolo nero a sinistra si potrebbe dire che sia il risultato della proiezione di un modello clipart della cornice)


1
Se cerchi Google pin d'angolo, ne otterrai alcune implementazioni
joojaa,

Risposte:


1

Penso che la soluzione stia cercando la trasformazione proiettiva che trasforma correttamente i quattro punti.

vale a dire

y=P×x

dove ex=[x0,x1,1]y=[y0y2,y1y2]

P è una matrice 3x3 con 9 voci. A causa della normalizzazione finale è unico fino al ridimensionamento, lasciando 8 gradi di libertà, che sono determinati in modo univoco dalle 8 equazioni fornite dalla corrispondenza (2 per coppia di punti).

Ora puoi usare l'algebra per farlo, o semplicemente usare OpenCV getPerspectiveTransform:).

Controlla anche le coordinate omogenee su Wikipedia per familiarizzare con il concetto.


Grazie! (L'ho risolto poco fa e ho pubblicato la soluzione proprio ora quando ho visto il tuo commento.)
ninjagecko

0

Ho risolto la mia domanda implementando la Trasformazione lineare diretta . La sezione degli esempi su Wikipedia è stata il mio caso d'uso.

Per ottenere le equazioni, collega le matrici (ad es. [x1 x2 x3 x4; x5 x6 x7 x8; x9 x10 x11 x12]) Al tuo sistema di algebra del computer preferito come SageMath, quindi risolvi l'equazione della matrice richiesta come illustrato, copia e incolla le soluzioni in termini di variabili nel tuo codice e regola la formattazione.

Si potrebbe quindi adattare la soluzione al proprio caso d'uso ridimensionando o ignorando particolari dimensioni a seconda dei casi (ad es. Ignorare la coordinata profondità / z nella matrice Coordinate dispositivo normalizzate in base al caso d'uso).

Avrai bisogno di una funzione di decomposizione SVD o di una libreria nella tua lingua.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.