2016-07-12 13 views
0

Ich habe mehrere Bilder eines Objekts, die von derselben kalibrierten Kamera aufgenommen wurden. Sagen wir, kalibriert bedeutet sowohl intrinsische als auch extrinsische Parameter (ich kann ein Schachbrett neben das Objekt legen, so dass alle Parameter abgerufen werden können). Auf diesen Bildern kann ich passende Schlüsselpunkte mit SIFT oder SURF finden, und einige passende Algorithmen, das ist Basic OpenCV. Aber wie mache ich die 3D-Rekonstruktion dieser Punkte aus mehreren Bildern? Dies ist keine klassische Stereo-Anordnung, daher gibt es mehr als 2 Bilder mit denselben Objektpunkten, und ich möchte so viele wie möglich für erhöhte Genauigkeit verwenden.Berechnen von 3D-Koordinaten von Schlüsselpunkten in mehreren Bildern

Gibt es eingebaute in OpenCV Funktionen, die dies tun?

(Beachten Sie, dass diese off-line durchgeführt wird, die Lösung nicht schnell sein müssen, aber robust)

Antwort

0

Ich glaube, ich habe eine Lösung gefunden. Die Struktur von Bewegungsalgorithmen behandelt den Fall, dass die Kameras nicht kalibriert sind, aber in diesem Fall sind alle intrinsischen und extrinsischen Parameter bekannt.

Das Problem verschlechtert sich in eine lineare Kleinste-Quadrate-Problem:

Wir haben die Koordinaten für einen einzelnen Objektpunkt zu berechnen:

X = [x, y, z, 1]' 
C = [x, y, z]' 
X = [[C], [1]] 

Wir gegeben n Bilder, die diese Transformationsmatrizen haben :

Pi = Ki * [Ri|ti] 

Diese Matrizen werden bereits bekannt. Der Objektpunkt wird auf den Bilder projiziert bei

U = [ui, vi] 

Wir in homogenen Koordinaten schreiben kann (der Operator * stellt sowohl die Matrixmultiplikation, Skalarprodukt und Skalarmultiplikation):

[ui * wi, vi * wi, wi]' = Pi * X 

Pi = [[p11i, p12i, p13i, p14i], 
     [p21i, p22i, p23i, p24i], 
     [p31i, p32i, p33i, p34i]] 

definieren wir die folgenden:

p1i = [p11i, p12i, p13i] (the first row of Pi missing the last element) 
p2i = [p21i, p22i, p23i] (the second row of Pi missing the last element) 
p3i = [p31i, p32i, p33i] (the third row of Pi missing the last element) 

a1i = p14i 
a2i = p24i 
a3i = p34i 

Dann können wir schreiben:

Q = [x, y, z] 
wi = p3i * Q + a3i 
ui = (p1i * Q + a1i)/wi = 
    = (p1i * Q + a1i)/(p3i * Q + a3i) 
ui * p3i * Q + ui * a3i - p1i * Q - a1i = 0 
(ui * p3i - p1i) * Q = a1i - a3i 

Ebenso für vi:

(vi * p3i - p2i) * Q = a2i - a3i 

Und dies gilt auch für i = 1..n.Wir können dies in Matrixform schreiben:

G * Q = b 

G = [[u1 * p31 - p11], 
    [v1 * p31 - p21], 
    [u2 * p32 - p12], 
    [v2 * p32 - p22], 
    ...   
    [un * p3n - p1n], 
    [vn * p3n - p2n]] 

b = [[a11 - a31 * u1], 
    [a21 - a31 * v1], 
    [a12 - a32 * u2], 
    [a22 - a32 * v2], 
    ... 
    [a1n - a3n * un], 
    [a2n - a3n * vn]] 

Da G und b aus den Pi Matrizen bekannt sind, und die Bildpunkte [ui, vi], können wir die Pseudoinverse berechnen G (nennen wir es G_) und berechnen:

Q = G_ * b 
0

Ich denke, man für so genannte Structur from motion Ansätze suchen. Sie verwenden mehrere Bilder von verschiedenen Standpunkten und geben eine 3D-Rekonstruktion (z. B. eine Punktwolke) zurück. Offenbar hat OpenCV ein SfM Modul im contrib-Paket, aber ich habe keine Erfahrungen damit.

Allerdings habe ich mit bundler zu arbeiten. Es war recht unkompliziert und liefert die gesamte Information (Kamerakalibrierung und Punktpositionen) als Textdatei und Sie können die Punktwolke mit Meshlab betrachten. Bitte beachten Sie, dass SIFT-Keypoints und -Deskriptoren für den Korrespondenzaufbau verwendet werden.

+0

dank schaffte ich es selbst herauszufinden, aber Ihre Antwort war hilfreich! – icguy

+0

Sie sind willkommen, aber normalerweise können Sie Kamera-Intrinsics für SfM-Ansätze zur Verfügung stellen, um das Ergebnis zu verbessern (zumindest Bündler ist in der Lage, sie selbst zu schätzen, aber abhängig von der Anzahl der Bilder war das Ergebnis schlechter) ... deshalb dachte ich SfM ist einfacher für Sie, als ein Schachbrett neben Ihrem Objekt zu platzieren (und es so zu platzieren, dass es in jedem Bild sichtbar ist) ... – gfkri