8

Sto sviluppando un'applicazione per iPhone usando opencv. Devo utilizzare il metodo solvePnPRansac:crea opencv camera matrix per iPhone 5 solvepnp

http://opencv.willowgarage.com/documentation/cpp/camera_calibration_and_3d_reconstruction.html

Per questo metodo ho bisogno di fornire una matrice fotocamera:
__ __
| fx 0 cx |
| 0 cy cy |
| _0 0 1 _ |

dove cx e cy rappresentano le posizioni dei pixel centrali dell'immagine e fx e fy rappresentano lunghezze focali, ma questa è tutta la documentazione che dice. Non sono sicuro di cosa fornire queste lunghezze focali. L'iPhone 5 ha una lunghezza focale di 4,1 mm, ma non credo che questo valore sia utilizzabile così com'è.

ho controllato un altro sito web:

http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html

che mostra come OpenCV crea matrici della fotocamera. Qui afferma che le lunghezze focali sono misurate in unità pixel.

ho controllato un altro sito:

http://www.velocityreviews.com/forums/t500283-focal-length-in-pixels.html

(circa a metà) si dice che la lunghezza focale può essere convertita da unità di millimetri di pixel usando l'equazione: fx = fy = focalMM * pixelDensity/25.4;

Un altro link che ho trovato afferma che fx = focalMM * width/(sensorSizeMM); fy = focalMM * length/(sensorSizeMM);

Non sono sicuro di queste equazioni e di come creare correttamente questa matrice.

Qualsiasi aiuto, consiglio, o link su come creare una matrice fotocamera accurata (in particolare per l'iPhone 5) sarebbe molto apprezzato,

Isaac

P.S. Penso che (fx/fy) o (fy/fx) potrebbe essere uguale al rapporto di aspetto della fotocamera, ma potrebbe essere completamente sbagliato.

UPDATE:

Pixel coordinates to 3D line (opencv)

utilizzando questo link, io riesco a capire come vogliono fx e fy essere formattati perché lo usano per scalare angoli relativi alla loro distanza dal centro. pertanto, fx e fy sono probabilmente in pixel/(lunghezza unitaria) ma non sono ancora sicuro di quale debba essere questa lunghezza unitaria, può essere arbitraria fintanto che xey sono scalati l'uno rispetto all'altro?

risposta

10

È possibile ottenere una stima iniziale (approssimativa) della lunghezza focale in pixel dividendo la lunghezza focale in mm della larghezza di un pixel del sensore della videocamera (CCD, CMOS, qualunque sia).

È possibile ottenere il primo dal manuale della fotocamera o leggerlo dall'intestazione EXIF ​​di un'immagine scattata alla massima risoluzione.Scoprire quest'ultimo è un po 'più complicato: si può guardare all'interwebs la scheda tecnica del sensore, se si conosce il produttore e il numero di modello, oppure si può semplicemente dividere la larghezza complessiva della sua area sensibile per il numero di pixel sul lato.

In assenza di altre informazioni, di solito è sicuro assumere che i pixel siano quadrati (es. la matrice della telecamera è zero). Inoltre, le coordinate pixel del punto principale (cx, cy) sono solitamente difficili da stimare con precisione senza un calibratore di calibrazione progettato con cura, e una procedura di calibrazione eseguita con attenzione (perché sono intrinsecamente confuse con la traduzione della telecamera parallela all'immagine aereo). Quindi è meglio impostarli uguali al centro geometrico geometrico dell'immagine, a meno che non si sappia che l'immagine è stata ritagliata in modo asimmetrico.

Pertanto, il modello di fotocamera più semplice ha un solo parametro sconosciuto, la lunghezza focale f = fx = fy.

Parola di consiglio: nella vostra applicazione è solitamente più conveniente portare in giro l'angolo di campo orizzontale (o verticale), piuttosto che la lunghezza focale in pixel. Questo perché il FOV è invariante rispetto al ridimensionamento dell'immagine.

+0

Grazie per la vostra risposta, l'ho trovato informativo e molto utile. Ancora una domanda veloce. Dato l'angolo del campo visivo, ho trovato online che fy = fx = cx/(tan ((orizzontaleAngle)/2)) è questa la formula che consigli? – Isaac

+0

inoltre, posso ancora ottenere un vettore relativo alla mia macchina fotografica in questo modo se costruisco il mio fx in questo modo: http://stackoverflow.com/questions/3107771/pixel-coordinates-to-3d-line-opencv?rq = 1 – Isaac

+0

upvote per indicare il FoV è vantaggioso come parametro dal momento che è indipendente dalla scala – hAcKnRoCk

6

La "lunghezza focale" si sta trattando qui è semplicemente un fattore di scala da oggetti nel mondo di pixel della fotocamera, utilizzato nel modello foro stenopeico (Wikipedia link). È per questo che le sue unità sono pixel/unità di lunghezza. Per una data f, un oggetto di dimensioni L a distanza (perpendicolare alla telecamera) z, sarebbe f * L/z pixel.

Quindi, si potrebbe calcolare la lunghezza focale inserendo un oggetto di dimensioni note ad una distanza nota dalla tua macchina fotografica e misurandone le dimensioni nell'immagine. Puoi anche assumere il punto centrale t è il centro dell'immagine. Non si deve assolutamente ignorare la distorsione della lente (parametro dist_coef in solvePnPRansac).

In pratica, il modo migliore per ottenere la matrice della telecamera e i coefficienti di distorsione è utilizzare uno strumento di calibrazione della fotocamera. Puoi scaricare e utilizzare il software camera_calib MRPT dal this link, c'è anche un video tutorial here. Se si utilizza MATLAB, andare per il Camera Calibration Toolbox.

+0

Grazie per la risposta, penso che semplicemente registrerò una scacchiera con la fotocamera iphone 5 e userò il secondo link che hai inviato. Pensi che ci potrebbe essere una matrice camera premessa e coefficiente di distorsione per l'iPhone 5? – Isaac

+3

@Isaac: non conosco nessuna matrice di fotocamera premade per Iphone 5, ma potresti pubblicare il risultato della calibrazione per il tuo ;-) – Milo

4

Ecco una tabella con le specifiche delle macchine fotografiche per iPhone 4 e 5. il calcolo è:

double f = 4.1; 
double resX = (double)(sourceImage.cols); 
double resY = (double)(sourceImage.rows); 
double sensorSizeX = 4.89; 
double sensorSizeY = 3.67; 
double fx = f * resX/sensorSizeX; 
double fy = f * resY/sensorSizeY; 
double cx = resX/2.; 
double cy = resY/2.; 
+1

citazione necessaria. –

1

Prova questa:

func getCamMatrix()->(Float, Float, Float, Float) 
{ 

    let format:AVCaptureDeviceFormat? = deviceInput?.device.activeFormat 
    let fDesc:CMFormatDescriptionRef = format!.formatDescription 

    let dim:CGSize = CMVideoFormatDescriptionGetPresentationDimensions(fDesc, true, true) 

    // dim = dimensioni immagine finale 
    let cx:Float = Float(dim.width)/2.0; 
    let cy:Float = Float(dim.height)/2.0; 

    let HFOV : Float = format!.videoFieldOfView 
    let VFOV : Float = ((HFOV)/cx)*cy 

    let fx:Float = abs(Float(dim.width)/(2 * tan(HFOV/180 * Float(M_PI)/2))); 
    let fy:Float = abs(Float(dim.height)/(2 * tan(VFOV/180 * Float(M_PI)/2))); 

    return (fx, fy, cx, cy) 
} 
1

Vecchio filo, problema attuale.

Come Milo e Isaac menzionati dopo la risposta di Milo, sembra che ci sia nessun params "comuni" disponibili per, ad esempio, l'iPhone 5.

Per quello che vale, qui è il risultato di una corsa con la strumento MRPT calibrazione, con un buon vecchio iPhone 5:

[CAMERA_PARAMS] 
resolution=[3264 2448] 
cx=1668.87585 
cy=1226.19712 
fx=3288.47697 
fy=3078.59787 
dist=[-7.416752e-02 1.562157e+00 1.236471e-03 1.237955e-03 -5.378571e+00] 

Average err. of reprojection: 1.06726 pixels (OpenCV error=1.06726) 

Nota che dist significa distorsione qui.

Sto conducendo esperimenti su un progetto di giocattoli, con questi parametri --- tipo di ok.Se li usi sul tuo progetto, tieni presente che potrebbero non essere abbastanza buoni per iniziare. Il migliore sarà seguire la raccomandazione di Milo con i tuoi dati personali. Lo strumento MRPT è abbastanza facile da usare, con la scacchiera che forniscono. Spero che questo aiuti a iniziare!