Correzione della distorsione trapezoidale mediante punti 3D di Kinect


15

Con XNA, sto visualizzando un semplice rettangolo che viene proiettato sul pavimento. Il proiettore può essere posizionato in una posizione arbitraria. Ovviamente, il rettangolo proiettato viene distorto in base alla posizione e all'angolo del proiettore. Un Kinect scruta il pavimento alla ricerca dei quattro angoli. Ora il mio obiettivo è quello di trasformare il rettangolo originale in modo tale che la proiezione non sia più distorta sostanzialmente pre-deformando il rettangolo.

Il mio primo approccio è stato quello di fare tutto in 2D: prima calcolare una trasformazione prospettica (usando OpenCV warpPerspective()) dai punti scansionati ai punti del rettangolo interno e applicare l'inverso al rettangolo. Sembrava funzionare ma era troppo lento perché non poteva essere riprodotto sulla GPU.

Il secondo approccio era di fare tutto in 3D per utilizzare le funzionalità di rendering di XNA. In primo luogo, visualizzerei un piano, scansionerei i suoi angoli con Kinect e mapperei i punti 3D ricevuti sul piano originale. Teoricamente, potrei applicare l'inverso della trasformazione prospettica al piano, come ho fatto nell'approccio 2D. Tuttavia, poiché XNA funziona con una matrice di visualizzazione e proiezione, non posso semplicemente chiamare una funzione come warpPerspective()e ottenere il risultato desiderato. Avrei bisogno di calcolare i nuovi parametri per la vista della telecamera e la matrice di proiezione.

Domanda: è possibile calcolare questi parametri e dividerli in due matrici (vista e proiezione)? In caso contrario, c'è un altro approccio che potrei usare?


1
XNA usa una matrice View e Projection, ma penso che il risultato finale = vector * view * proiezioni. Perché non provare a visualizzare una matrice di identità e a proiettare la matrice di prospettiva inversa e vedere se funziona? (Non sono sicuro al 100% che sia esattamente quello che succede)
Roy T.

1
Come hai calcolato esattamente una trasformazione prospettica warpPespective? Non ho familiarità con OpenCV, ma leggendo il documento sembra che questa funzione applichi solo una prospettiva a un'immagine. O sono confuso? Ad ogni modo, forse aggiungere ulteriori dettagli sulla tua prima implementazione sarebbe di aiuto.
Laurent Couvidou,

Potresti dare un'occhiata alla libreria PCL ( pointclouds.org ). La conversione dell'immagine di profondità dal Kinect ti dà una nuvola di punti con la telecamera all'origine, che punta lungo l'asse z. È quindi possibile utilizzare ransac o un altro algoritmo per cercare l'aereo.
Exilyth,

Risposte:


1

Poiché l'algebra vettoriale è compatibile con la GPU, è possibile utilizzare normalizzazioni e prodotti punto per trovare i quattro angoli del piano originale come segue:

inserisci qui la descrizione dell'immagine

Dato il punto del proiettore (P), il punto proiettato (B), un punto arbitrario sul piano che contiene il rettangolo distorto (Q) e il vettore normale a quel piano (n), il punto di intersezione (A) del linea da P a B, e il piano è dato da

s = -dot_product(n, P - Q) / dot_product(n, normalized(B - P)) 
A = P + s * normalized(B-P)

Fonte http://geomalgorithms.com/a05-_intersect-1.html sezione Intersezione piano-linea

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.