Come posso proiettare in senso inverso i punti 2D in 3D?

Ho 4 punti 2D nello spazio dello schermo, e ho bisogno di ritrasmetterli di nuovo nello spazio 3D. So che ognuno dei 4 punti è un angolo di un rettangolo rigido ruotato in 3D, e conosco la dimensione del rettangolo. Come posso ottenere le coordinate 3D da questo?

Non sto usando alcuna API particolare e non ho una matrice di proiezione esistente. Sto solo cercando la matematica di base per fare questo. Certamente non ci sono abbastanza dati per convertire un singolo punto 2D in 3D senza altri riferimenti, ma immagino che se tu avessi 4 punti, sai che sono tutti ad angolo retto l’uno sull’altro sullo stesso piano, e tu conosci la distanza tra loro, dovresti essere in grado di capirlo da lì. Sfortunatamente non riesco a capire come.

Questo potrebbe cadere sotto l’ombrello della fotogrammetria, ma le ricerche su google che non mi hanno portato a nessuna informazione utile.

Bene, sono venuto qui cercando una risposta e non ho trovato nulla di semplice e diretto, quindi sono andato avanti e ho fatto la cosa stupida ma efficace (e relativamente semplice): l’ottimizzazione Monte Carlo.

In parole povere, l’algoritmo è il seguente: Perturbare casualmente la matrice di proiezione finché non proietta le coordinate 3D conosciute sulle coordinate 2D conosciute.

Ecco una foto di Thomas the Tank Engine:

Thomas the Tank Engine

Diciamo che usiamo GIMP per trovare le coordinate 2D di quello che pensiamo sia un quadrato sul piano terreno (indipendentemente dal fatto che sia davvero un quadrato dipende dal tuo giudizio sulla profondità):

Con un contorno del quadrato

Ottengo quattro punti nell’immagine 2D: (318, 247) , (326, 312) , (418, 241) e (452, 303) .

Per convenzione, diciamo che questi punti devono corrispondere ai punti 3D: (0, 0, 0) , (0, 0, 1) , (1, 0, 0) e (1, 0, 1) . In altre parole, un quadrato unitario nel piano y = 0.

La proiezione di ciascuna di queste coordinate 3D in 2D viene eseguita moltiplicando il vettore 4D [x, y, z, 1] con una matrice di proiezione 4×4, quindi dividendo le componenti x e y per z per ottenere effettivamente la correzione prospettica. Questo è più o meno ciò che gluProject () fa, eccetto gluProject() prende in considerazione anche il viewport corrente e prende in considerazione una matrice modelview separata (possiamo solo supporre che la matrice modelview sia la matrice id quadro). È molto utile consultare la documentazione di gluProject() perché in realtà voglio una soluzione che gluProject() per OpenGL, ma attenzione che nella formula manca la divisione per z nella formula.

Ricorda, l’algoritmo deve iniziare con una matrice di proiezione e perturbarla casualmente fino a dare la proiezione che vogliamo. Quindi, quello che faremo è proiettare ciascuno dei quattro punti 3D e vedere quanto vicino si arriva ai punti 2D che volevamo. Se le nostre perturbazioni casuali fanno sì che i punti 2D proiettati si avvicinino a quelli che abbiamo contrassegnato sopra, allora manteniamo quella matrice come un miglioramento rispetto alla nostra iniziale (o precedente) ipotesi.

Definiamo i nostri punti:

 # Known 2D coordinates of our rectangle i0 = Point2(318, 247) i1 = Point2(326, 312) i2 = Point2(418, 241) i3 = Point2(452, 303) # 3D coordinates corresponding to i0, i1, i2, i3 r0 = Point3(0, 0, 0) r1 = Point3(0, 0, 1) r2 = Point3(1, 0, 0) r3 = Point3(1, 0, 1) 

Abbiamo bisogno di iniziare con una matrice, la matrice di id quadro sembra una scelta naturale:

 mat = [ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1], ] 

Abbiamo bisogno di implementare effettivamente la proiezione (che è fondamentalmente una moltiplicazione di matrice):

 def project(p, mat): x = mat[0][0] * px + mat[0][1] * py + mat[0][2] * pz + mat[0][3] * 1 y = mat[1][0] * px + mat[1][1] * py + mat[1][2] * pz + mat[1][3] * 1 w = mat[3][0] * px + mat[3][1] * py + mat[3][2] * pz + mat[3][3] * 1 return Point(720 * (x / w + 1) / 2., 576 - 576 * (y / w + 1) / 2.) 

Questo è fondamentalmente ciò che gluProject() fa, 720 e 576 sono rispettivamente la larghezza e l’altezza dell’immagine (cioè il viewport), e sottraiamo da 576 al conteggio per il fatto che contiamo le coordinate y dall’alto, mentre OpenGL tipicamente conta loro dal basso. Noterai che non stiamo calcolando z, perché non ne abbiamo davvero bisogno qui (anche se potrebbe essere utile assicurarsi che rientri nell’intervallo che OpenGL usa per il buffer di profondità).

Ora abbiamo bisogno di una funzione per valutare quanto siamo vicini alla soluzione corretta. Il valore restituito da questa funzione è ciò che useremo per verificare se una matrice è migliore di un’altra. Ho scelto di andare per sum delle distanze al quadrato, cioè:

 # The squared distance between two points a and b def norm2(a, b): dx = bx - ax dy = by - ay return dx * dx + dy * dy def evaluate(mat): c0 = project(r0, mat) c1 = project(r1, mat) c2 = project(r2, mat) c3 = project(r3, mat) return norm2(i0, c0) + norm2(i1, c1) + norm2(i2, c2) + norm2(i3, c3) 

Per perturbare la matrice, selezioniamo semplicemente un elemento da perturbare di una quantità casuale all’interno di un intervallo:

 def perturb(amount): from copy import deepcopy from random import randrange, uniform mat2 = deepcopy(mat) mat2[randrange(4)][randrange(4)] += uniform(-amount, amount) 

(Vale la pena notare che la nostra funzione project() realtà non usa mat[2] , poiché non calcoliamo z, e poiché tutte le nostre coordinate y sono 0 i valori mat[*][1] sono irrilevanti come Bene, potremmo usare questo fatto e non provare mai a perturbare quei valori, il che darebbe una piccola accelerazione, ma questo è lasciato come esercizio …)

Per comodità, aggiungiamo una funzione che fa la maggior parte dell’approssimazione chiamando perturb() più e più volte su quale sia la migliore matrice che abbiamo trovato finora:

 def approximate(mat, amount, n=100000): est = evaluate(mat) for i in xrange(n): mat2 = perturb(mat, amount) est2 = evaluate(mat2) if est2 < est: mat = mat2 est = est2 return mat, est 

Ora tutto ciò che resta da fare è eseguirlo ...:

 for i in xrange(100): mat = approximate(mat, 1) mat = approximate(mat, .1) 

Trovo che questo dia già una risposta abbastanza precisa. Dopo aver corso per un po ', la matrice che ho trovato era:

 [ [1.0836000765696232, 0, 0.16272110011060575, -0.44811064935115597], [0.09339193527789781, 1, -0.7990570384334473, 0.539087345090207 ], [0, 0, 1, 0 ], [0.06700844759602216, 0, -0.8333379578853196, 3.875290562060915 ], ] 

con un errore di circa 2.6e-5 . (Notate come gli elementi che abbiamo detto non sono stati usati nel calcolo non sono stati effettivamente modificati dalla nostra matrice iniziale, perché la modifica di queste voci non cambierebbe il risultato della valutazione e quindi il cambiamento non verrebbe mai portato avanti).

Possiamo passare la matrice in OpenGL usando glLoadMatrix() (ma ricordati di trasporla prima, e ricorda di caricare la tua matrice modelview con la matrice id quadro):

 def transpose(m): return [ [m[0][0], m[1][0], m[2][0], m[3][0]], [m[0][1], m[1][1], m[2][1], m[3][1]], [m[0][2], m[1][2], m[2][2], m[3][2]], [m[0][3], m[1][3], m[2][3], m[3][3]], ] glLoadMatrixf(transpose(mat)) 

Ora possiamo ad esempio tradurre lungo l'asse z per ottenere diverse posizioni lungo le tracce:

 glTranslate(0, 0, frame) frame = frame + 1 glBegin(GL_QUADS) glVertex3f(0, 0, 0) glVertex3f(0, 0, 1) glVertex3f(1, 0, 1) glVertex3f(1, 0, 0) glEnd() 

Con traduzione 3D

Di sicuro questo non è molto elegante da un punto di vista matematico; non si ottiene un'equazione di forma chiusa che si può semplicemente colbind i numeri e ottenere una risposta diretta (e accurata). TUTTAVIA, ti consente di aggiungere ulteriori vincoli senza doversi preoccupare di complicare le equazioni; per esempio, se volessimo incorporare anche l'altezza, potremmo usare quell'angolo della casa e dire (nella nostra funzione di valutazione) che la distanza dal terreno al tetto dovrebbe essere così-e-così, e ricominciare l'algoritmo. Quindi sì, è una specie di forza bruta, ma funziona e funziona bene.

Choo choo!

Questo è il problema classico per la realtà aumentata basata su marker.

Si dispone di un indicatore quadrato (codice a barre 2D) e si desidera trovare la sua posa (traslazione e rotazione in relazione alla telecamera), dopo aver individuato i quattro bordi dell’indicatore. Panoramica-Picture

Non sono a conoscenza degli ultimi contributi al campo, ma almeno fino a un punto (2009) l’RPP avrebbe dovuto sovraperformare POSIT che è menzionato sopra (ed è davvero un approccio classico per questo) Vedi i link, anche loro fornire fonte.

(PS – So che è un argomento un po ‘vecchio, ma comunque, il post potrebbe essere utile a qualcuno)

D. DeMenthon ha escogitato un algoritmo per calcolare la posa di un object (la sua posizione e l’orientamento nello spazio) da punti caratteristica in un’immagine 2D quando si conosce il modello dell’object – questo è il tuo problema esatto :

Descriviamo un metodo per trovare la posa di un object da una singola immagine. Supponiamo di poter rilevare e abbinare nell’immagine quattro o più punti caratteristica non complanari dell’object e che conosciamo la loro geometria relativa sull’object.

L’algoritmo è noto come Posit ed è descritto nell’articolo classico “Model-Based Object Pose in 25 Lines of Code” (disponibile sul suo sito Web , sezione 4).

Link diretto all’articolo: http://www.cfar.umd.edu/~daniel/daniel_papersfordownload/Pose25Lines.pdf Implementazione OpenCV: http://opencv.willowgarage.com/wiki/Posit

L’idea è di approssimare ripetutamente la proiezione prospettica con una proiezione ortogonale ridimensionata fino a raggiungere una posa accurata.

Per il mio motore OpenGL, il seguente snip convertirà le coordinate del mouse / schermo in coordinate del mondo 3D. Leggi gli annunci per una descrizione reale di ciò che sta accadendo.

 / * FUNCTION: YCamera :: CalculateWorldCoordinates
      ARGOMENTI: x coordinata x mouse
                       y coordinata y mouse
                       vec dove memorizzare le coordinate
      RITORNO: n / a
      DESCRIZIONE: Converti le coordinate del mouse in coordinate del mondo
 * /

void YCamera :: CalculateWorldCoordinates(float x, float y, YVector3 *vec) { // START GLint viewport[4]; GLdouble mvmatrix[16], projmatrix[16];

 GLint real_y; GLdouble mx, my, mz; glGetIntegerv(GL_VIEWPORT, viewport); glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix); glGetDoublev(GL_PROJECTION_MATRIX, projmatrix); real_y = viewport[3] - (GLint) y - 1; // viewport[3] is height of window in pixels gluUnProject((GLdouble) x, (GLdouble) real_y, 1.0, mvmatrix, projmatrix, viewport, &mx, &my, &mz); /* 'mouse' is the point where mouse projection reaches FAR_PLANE. World coordinates is intersection of line(camera->mouse) with plane(z=0) (see LaMothe 306) Equation of line in 3D: (x-x0)/a = (y-y0)/b = (z-z0)/c Intersection of line with plane: z = 0 x-x0 = a(z-z0)/c <=> x = x0+a(0-z0)/c <=> x = x0 -a*z0/c y = y0 - b*z0/c */ double lx = fPosition.x - mx; double ly = fPosition.y - my; double lz = fPosition.z - mz; double sum = lx*lx + ly*ly + lz*lz; double normal = sqrt(sum); double z0_c = fPosition.z / (lz/normal); vec->x = (float) (fPosition.x - (lx/normal)*z0_c); vec->y = (float) (fPosition.y - (ly/normal)*z0_c); vec->z = 0.0f; 

}

Dallo spazio 2-D ci saranno 2 rettangoli validi che possono essere costruiti. Senza conoscere la proiezione della matrice originale, non si saprà quale è corretta. È lo stesso del problema “scatola”: vedi due quadrati, uno dentro l’altro, con i 4 vertici interni collegati ai 4 rispettivi vertici esterni. Stai guardando una scatola dall’alto verso il basso o dal basso verso l’alto?

Detto questo, stai cercando una matrice T di trasformazione in cui …

{{x1, y1, z1}, {x2, y2, z2}, {x3, y3, z3}, {x4, y4, z4}} x T = {{x1, y1}, {x2, y2}, { x3, y3}, {x4, y4}}

(4 x 3) x T = (4 x 2)

Quindi T deve essere una matrice (3 x 2). Quindi abbiamo 6 incognite.

Ora costruisci un sistema di vincoli su T e risolvi con Simplex. Per build i vincoli, sai che una linea che passa attraverso i primi due punti deve essere parallela alla linea che passa ai secondi due punti. Sai che una linea che passa attraverso i punti 1 e 3 deve essere parallela alle linee che passano attraverso i punti 2 e 4. Sai che una linea che passa per 1 e 2 deve essere ortogonale a una linea che passa attraverso i punti 2 e 3. Sai che la lunghezza della linea da 1 e 2 deve essere uguale alla lunghezza della linea da 3 e 4. Si sa che la lunghezza della linea da 1 e 3 deve essere uguale alla lunghezza della linea da 2 e 4.

Per renderlo ancora più semplice, conosci il rettangolo, quindi conosci la lunghezza di tutti i lati.

Questo dovrebbe darti molti vincoli per risolvere questo problema.

Naturalmente, per tornare indietro, puoi trovare T-inverse.

@Rob: Sì, ci sono un numero infinito di proiezioni, ma non un numero infinito di progetti in cui i punti devono soddisfare i requisiti di un rettangolo.

@nlucaroni: Sì, questo è risolvibile solo se hai quattro punti nella proiezione. Se il rettangolo proietta a soli 2 punti (cioè il piano del rettangolo è ortogonale alla superficie di proiezione), allora questo non può essere risolto.

Hmmm … dovrei andare a casa e scrivere questo gioiellino. Sembra divertente.

aggiornamenti:

  1. Esiste un numero infinito di proiezioni a meno che non si risolva uno dei punti. Se ti aggiusti sui punti del rettangolo originale, allora ci sono due possibili rettangoli originali.

Supponendo che i punti siano effettivamente parte di un rettangolo, sto dando un’idea generica:

Trova due punti con inter-distanza massima: questi probabilmente definiscono una diagonale (eccezione: casi speciali in cui il rettangolo è quasi paralell al piano YZ, a sinistra per lo studente). Chiamali A, C. Calcola gli angoli BAD, BCD. Questi, rispetto agli angoli retti, ti danno l’orientamento nello spazio 3d. Per scoprire la distanza z, devi correlare i lati proiettati ai lati conosciuti e poi, in base al metodo di proiezione 3d (è 1 / z?) Sei sulla buona strada per sapere le distanze.

Per seguire l’approccio di Rons: puoi trovare i tuoi valori z se sai come hai ruotato il tuo rettangolo.

Il trucco è trovare la matrice proiettiva che ha fatto la proiezione. Fortunatamente questo è ansible e anche economico da fare. La matematica pertinente può essere trovata nel documento “Mappature proiettive per la deformazione dell’immagine” di Paul Heckbert.

http://pages.cs.wisc.edu/~dyer/cs766/readings/heckbert-proj.pdf

In questo modo puoi recuperare la parte omogenea di ogni vertice che è stata persa durante la proiezione.

Ora ti rimangono ancora quattro linee anziché punti (come ha spiegato Ron). Dal momento che conosci la dimensione del tuo rettangolo originale, tuttavia, nulla è perso. Ora puoi colbind i dati dal metodo di Ron e dall’approccio 2D in un risolutore di equazioni lineari e risolvere per z. Ottieni esattamente i valori z di ogni vertice in questo modo.

Nota: funziona solo perché:

  1. La forma originale era un rettangolo
  2. Conosci la dimensione esatta del rettangolo nello spazio 3D.

È davvero un caso speciale.

Spero che aiuti, Nils

La proiezione che hai sulla superficie 2D ha infiniti rettangoli 3D che proietteranno sulla stessa forma 2D.

Pensaci in questo modo: hai quattro punti 3D che compongono il rettangolo 3D. Chiamali (x0, y0, z0), (x1, y1, z1), (x2, y2, z2) e (x3, y3, z3). Quando proiettate questi punti sul piano xy, eliminate le coordinate z: (x0, y0), (x1, y1), (x2, y2), (x3, y3).

Ora, vuoi proiettare nello spazio 3D, devi decodificare ciò che erano z0, .., z3. Ma qualsiasi insieme di coordinate z che a) mantengano la stessa distanza xy tra i punti e b) mantengano la forma di un rettangolo. Quindi, qualsiasi membro di questo set (infinito) farà: {(z0 + i, z1 + i, z2 + i, z3 + i) | io <- R}.

Modifica @Jarrett: Immagina di aver risolto questo problema e di aver trovato un rettangolo nello spazio 3D. Ora, immagina di far scorrere quel rettangolo su e giù per l’asse z. Quella quantità infinita di rettangoli tradotti ha tutti la stessa proiezione xy. Come sai di aver trovato quello “giusto”?

Edit # 2: Va bene, questo è da un commento che ho fatto su questa domanda – un approccio più intuitivo al ragionamento su questo.

Immagina di tenere un pezzo di carta sopra la tua scrivania. Far finta che ogni angolo della carta abbia un puntatore laser senza peso ad esso collegato che punta verso la scrivania. La carta è l’object 3D e i puntatori laser puntati sulla scrivania sono la proiezione 2D.

Ora, come si può sapere quanto è alto fuori dalla scrivania il foglio guardando solo i puntini del puntatore laser?

Non puoi Sposta la carta verso l’alto e il basso. I puntatori laser continueranno a brillare sugli stessi punti sulla scrivania, indipendentemente dall’altezza della carta.

Trovare le coordinate z nella proiezione inversa è come cercare di trovare l’altezza della carta in base ai punti del puntatore laser sulla sola scrivania.

Quando proietti da 3D a 2D perdi informazioni.

Nel caso semplice di un singolo punto, la proiezione inversa ti darebbe un raggio infinito attraverso lo spazio 3d.

Generalmente la ricostruzione stereoscopica inizia con due immagini 2D e proietta entrambe in 3D. Quindi cerca un’intersezione tra i due raggi 3D prodotti.

La proiezione può assumere forms diverse. Ortogonale o prospettiva. Immagino che stai assumendo la proiezione ortogonale?

Nel tuo caso, supponendo che tu avessi la matrice originale, avresti 4 raggi nello spazio 3D. Saresti quindi in grado di limitare il problema con le dimensioni del rettangolo 3D e tentare di risolverlo.

La soluzione non sarà unica in quanto una rotazione attorno ad entrambi gli assi che è parallela al piano di proiezione 2d sarà ambigua in direzione. In altre parole, se l’immagine 2d è perpendicolare all’asse z, ruotare il rettangolo 3D in senso orario o antiorario attorno all’asse x produrrebbe la stessa immagine. Allo stesso modo per l’asse y.

Nel caso in cui il piano del rettangolo sia parallelo all’asse z hai ancora più soluzioni.

Poiché non si dispone della matrice di proiezione originale, un’ulteriore ambiguità viene introdotta da un fattore di ridimensionamento arbitario esistente in qualsiasi proiezione. Non è ansible distinguere tra un ridimensionamento nella proiezione e una traslazione in 3d nella direzione dell’asse z. Questo non è un problema se sei interessato solo alle posizioni relative dei 4 punti nello spazio 3d quando sono collegati tra loro e non al piano della proiezione 2d.

In una proiezione prospettica le cose diventano più difficili …

Se si conosce che la forma è un rettangolo in un piano, è ansible limitare ulteriormente il problema. Certamente non puoi capire “quale” piano, quindi puoi scegliere che giace sul piano dove z = 0 e uno degli angoli è su x = y = 0, e i bordi sono paralleli all’asse x / y.

I punti in 3d sono quindi {0,0,0}, {w, 0,0}, {w, h, 0} e {0, h, 0}. Sono abbastanza sicuro che non si troverà la dimensione assoluta, quindi solo il rapporto w / h è significativo, quindi questo è uno sconosciuto.

Rispetto a questo piano, la telecamera deve essere in qualche punto cx, cy, cz nello spazio, deve puntare in una direzione nx, ny, nz (un vettore di lunghezza uno quindi uno di questi è ridondante) e avere un focus_length / image_width fattore di w. Questi numeri si trasformano in una matrice di proiezione 3×3.

Ciò fornisce un totale di 7 incognite: w / h, cx, cy, cz, nx, ny e w.

Hai un totale di 8 note: le 4 x + y coppie.

Quindi questo può essere risolto.

Il prossimo passo è usare Matlab o Mathmatica.

Prenderò il mio libro di Algebra lineare quando torno a casa se nessuno risponde. Ma @ DG, non tutte le matrici sono invertibili. Le matrici singolari non sono invertibili (quando determinante = 0). Ciò accadrà sempre, poiché una matrice di proiezione deve avere autovalori di 0 e 1, ed essere quadrata (poiché è idempotente, quindi p ^ 2 = p).

Un semplice esempio è, [[0 1] [0 1]] dal determinante = 0, e quella è una proiezione sulla linea x = y!

Grazie a @Vegard per una risposta eccellente. Ho pulito un po ‘il codice:

 import pandas as pd import numpy as np class Point2: def __init__(self,x,y): self.x = x self.y = y class Point3: def __init__(self,x,y,z): self.x = x self.y = y self.z = z # Known 2D coordinates of our rectangle i0 = Point2(318, 247) i1 = Point2(326, 312) i2 = Point2(418, 241) i3 = Point2(452, 303) # 3D coordinates corresponding to i0, i1, i2, i3 r0 = Point3(0, 0, 0) r1 = Point3(0, 0, 1) r2 = Point3(1, 0, 0) r3 = Point3(1, 0, 1) mat = [ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1], ] def project(p, mat): #print mat x = mat[0][0] * px + mat[0][1] * py + mat[0][2] * pz + mat[0][3] * 1 y = mat[1][0] * px + mat[1][1] * py + mat[1][2] * pz + mat[1][3] * 1 w = mat[3][0] * px + mat[3][1] * py + mat[3][2] * pz + mat[3][3] * 1 return Point2(720 * (x / w + 1) / 2., 576 - 576 * (y / w + 1) / 2.) # The squared distance between two points a and b def norm2(a, b): dx = bx - ax dy = by - ay return dx * dx + dy * dy def evaluate(mat): c0 = project(r0, mat) c1 = project(r1, mat) c2 = project(r2, mat) c3 = project(r3, mat) return norm2(i0, c0) + norm2(i1, c1) + norm2(i2, c2) + norm2(i3, c3) def perturb(mat, amount): from copy import deepcopy from random import randrange, uniform mat2 = deepcopy(mat) mat2[randrange(4)][randrange(4)] += uniform(-amount, amount) return mat2 def approximate(mat, amount, n=1000): est = evaluate(mat) for i in xrange(n): mat2 = perturb(mat, amount) est2 = evaluate(mat2) if est2 < est: mat = mat2 est = est2 return mat, est for i in xrange(1000): mat,est = approximate(mat, 1) print mat print est 

La chiamata approssimativa con .1 non ha funzionato per me, quindi l'ho tolto. L'ho eseguito anche per un po ', e l'ultima volta che ho controllato era a

 [[0.7576315397559887, 0, 0.11439449272592839, -0.314856490473439], [0.06440497208710227, 1, -0.5607502645413118, 0.38338196981556827], [0, 0, 1, 0], [0.05421620936883742, 0, -0.5673977598434641, 2.693116299312736]] 

con un errore intorno a 0.02.

Sì, Monte Carlo funziona, ma ho trovato una soluzione migliore per questo problema. Questo codice funziona perfettamente (e usa OpenCV):

 Cv2.CalibrateCamera(new List>() { points3d }, new List>() { points2d }, new Size(height, width), cameraMatrix, distCoefs, out rvecs, out tvecs, CalibrationFlags.ZeroTangentDist | CalibrationFlags.FixK1 | CalibrationFlags.FixK2 | CalibrationFlags.FixK3); 

Questa funzione prende in considerazione i punti 3d e 2d, le dimensioni dello schermo e restituisce la rotazione (rvecs [0]), la traduzione (tvecs [0]) e la matrice dei valori intrinseci della telecamera. È tutto ciò di cui hai bisogno