2013-10-06 9 views
9

Ich hatte dies ursprünglich auf den OpenCV-Foren gepostet, aber leider habe ich nicht zu viele Ansichten/Antworten bekommen, also poste ich hier mit der Hoffnung, dass jemand eine Richtung vorschlagen könnte ?OpenCV Stereo Matching/Kalibrierung

Ich benutze die Bumblebee XB3 Stereo Kamera und es hat 3 Objektive. Ich habe ungefähr drei Wochen damit verbracht, Foren, Tutorials, das Learning OpenCV-Buch und die aktuelle OpenCV-Dokumentation über die Verwendung der Stereokalibrierungs- und Stereo-Matching-Funktionalität zu lesen. Zusammenfassend ist mein Problem, dass ich eine gute Disparitätskarte erstellt habe, aber sehr schlechte Punktwolken, die schräg erscheinen und nicht repräsentativ für die tatsächliche Szene sind.

Was ich bisher getan haben:

verwendet, um die OpenCV stereo_calibration und stereo_matching Beispiele:

meine Stereokamera kalibrierte Bilder mit Schachbrett

1) Raw Szene Bilder : http://answers.opencv.org/upfiles/1380850337241986.jpg
2) Die Rohbilder korrigiert, die von der Kamera mit den Matrizen nach Kamerakalibrierungerhalten wurden: http://answers.opencv.org/upfiles/13808502665723237.png
3) generiert eine Disparität Bild aus den entzerrten Bildern Stereo Matching (SGBM)
mit: 4) Projizierte diese Unterschiede auf eine 3D-Punktwolke

Was ich bisher als Beseitigung getan zu mein Problem:

  • ich die 1. und 2. Bilder versucht haben, dann ist die 2. und 3. Linsen und schließlich die 1. und 2..
  • Ich habe erneut ausgeführt Kalibrierung meines schachbrett fängt durch Variation der Abstand (näher/weiter weg)
  • Ich habe für die Kalibrierung
  • Unterschiedlich Schachbrett Größe verwendet über 20 Stereo-Paare verwendet: Ich habe ein 9x6 Schachbrett Bild für Kalibrierung verwendet und jetzt auf die Verwendung einer 8x5 ein stattdessen
  • Ich habe versucht, die Block-Matching-sowie SGBM-Varianten und erhalten
    relativ ähnliche Ergebnisse. Getting
    bessere Ergebnisse mit SGBM bisher.
  • Ich habe variiert die Ungleichheit reicht, änderte sich die SAD Fenstergröße usw. mit wenig Verbesserung

Was ich vermute, das Problem ist:

Mein Disparitätsbild sieht relativ akzeptabel , aber der nächste Schritt ist, mit der Q-Matrix zur 3D-Punktwolke zu gehen. Ich vermute, ich kalibriere die Kameras nicht korrekt, um die richtige Q-Matrix zu erzeugen. Leider bin ich in Bezug auf das, was ich noch tun kann, um eine bessere Q-Matrix zu bekommen, in die Falle gegangen. Kann jemand bitte Wege vorschlagen?

Die andere Sache, die ich für problematisch halte, sind die Annahmen, die ich bei der Verwendung der cv :: stereoCalibrate-Funktion mache.Im Moment kalibriere ich jede Kamera einzeln, um die Kamera und die Verzerrung zu erhalten (cameraMatrix [0], distCoeffs [0] und cameraMatrix [1], distCoeffs [1]), so dass die Komplexität für die StereoCalibrate-Funktion etwas einfacher wird.

stereoCalibrate(objectPoints, imagePoints[0], imagePoints[1], 
        cameraMatrix[0], distCoeffs[0], 
        cameraMatrix[1], distCoeffs[1], 
        imageSize, R, T, E, F, 
        TermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 100, 1e-5), 
        //CV_CALIB_FIX_ASPECT_RATIO + 
        //CV_CALIB_ZERO_TANGENT_DIST + 
        //CV_CALIB_SAME_FOCAL_LENGTH + 
        CV_CALIB_RATIONAL_MODEL 
        //CV_CALIB_FIX_K3 + CV_CALIB_FIX_K4 + CV_CALIB_FIX_K5 
        ); 

Außerdem denke ich, dass es nützlich sein könnte, zu erwähnen, wie ich von Ungleichheit würde Wolke zeigen. Ich benutze OpenCVs cv :: reprojectImageTo3D und schreibe dann die Daten in eine PCL Point Cloud-Struktur. Hier ist der relevante Code:

cv::reprojectImageTo3D(imgDisparity16S, reconstructed3D, Q, false, CV_32F); 
    for (int i = 0; i < reconstructed3D.rows; i++) 
    { 
    for (int j = 0; j < reconstructed3D.cols; j++) 
    { 
     cv::Point3f cvPoint = reconstructed3D.at<cv::Point3f>(i, j); 
      //Filling in a PCL structure 
      pcl::PointXYZRGB point; 
      point.x = cvPoint.x; 
      point.y = cvPoint.y; 
      point.z = cvPoint.z; 
      point.rgb = rectified_imgRight.at<cv::Vec3b>(i,j)[0]; //Grey information 

      point_cloud_ptr->points.push_back (point); 
    } 
    } 

    point_cloud_ptr->width = (int) point_cloud_ptr->points.size(); 
    point_cloud_ptr->height = 1; 
    pcl::io::savePCDFileASCII("OpenCV-PointCloud.pts", *point_cloud_ptr); 

PS: Der Grund, warum ich wählte diese Bilder laden sind, dass die Szene etwas Beschaffenheit hat, so dass ich sagte, die Szene eine Antwort erwarten ist zu homogen. Der Bezug auf der Trennwand und der Stuhl sind sehr reich an Texturen.

paar Fragen:

Können Sie mir das Bild/Disparität Ebene helfen, zu entfernen, die einen Teil der Punktwolke zu sein scheint? Warum passiert dies?

Gibt es etwas Offensichtliches, das ich falsch mache? Ich poste meinen Code, aber er ist den OpenCV-Beispielen sehr ähnlich und ich glaube nicht, dass ich etwas kreativer mache. Ich kann, wenn es einen bestimmten Abschnitt gibt, der vielleicht etwas angeht.

In meiner naiven Meinung scheint es, dass das Ungleichheitsbild in Ordnung ist. Aber die Punktewolke ist definitiv nichts, was ich von einem relativ anständigen Ungleichheitsbild erwartet hätte, es ist viel schlimmer.

Wenn es hilft, habe ich die Q-Matrix erwähnt, die ich nach der Kamerakalibrierung erhalte, wenn etwas Offensichtliches herausspringt. Vergleicht man dies mit dem Buch Learning OpenCV, glaube ich nicht, es etwas eklatant falsch ist ...

Q: rows: 4 
    cols: 4 
    data: [ 1., 0., 0., -5.9767076110839844e+002, 0., 1., 0., 
     -5.0785438156127930e+002, 0., 0., 0., 6.8683948509213735e+002, 0., 
     0., -4.4965180874519222e+000, 0. ] 

Danke fürs Lesen und ich werde ehrlich schätzen keine Anregungen an dieser Stelle ...

+0

Ich durfte nicht mehr als 2 Links posten. Dies sind die verbleibenden: 3) Generierte ein Disparitätsbild von den korrigierten Bildern mit Stereo Matching (SGBM): http://answers.opencv.org/upfiles/13808503551344959.png 4) Projizierte diese Unterschiede zu einem 3D Punktwolke: http://answers.opencv.org/upfiles/13808503649376151.png und: http://answers.opencv.org/upfiles/13808503782809438.png – BumblebeeUser89

+0

Frage: werden Sie mit einer Punktwolke in der Kamera zufrieden sein Koordinatenrahmen?Wenn dies der Fall ist, können Sie die Point Grey-Kalibrierungsdatei verwenden, um zu erhalten, was Sie wollen (ohne mit einem Schachbrett zu kalibrieren). Die entzerrten Bilder weisen keine Linsenverzerrung auf, so dass sie bei einem Disparitätswert in die Tiefe (z = Bf/d) konvertiert werden und sie unter Verwendung der bekannten Brennweite f in Kamerakoordinaten projizieren. – killogre

Antwort

0

Ich fand ähnliche Probleme bei der Verwendung der OpenCV (v.2.4.6) 3D-Rekonstruktionsfunktion. Einige Leute, wie Martin Peris, haben wieder von selbst implementiert. http://blog.martinperis.com/2012/01/3d-reconstruction-with-opencv-and-point.html

Leider habe ich manchmal Probleme in beiden Implementierungen mit meinen Daten gefunden. Also vermute ich, dass mein Problem in diesen Fällen auf eine schlechte extrinsische Kameraparameterbeschreibung zurückzuführen ist. Vielleicht ist es auch dein Fall. : -?

PS. Um den Hintergrund loszuwerden, müssen Sie ihn segmentieren. Oder überprüfen Sie zumindest die Tiefenwerte, die größer als ein Schwellenwert sind, sobald die Rekonstruktion funktioniert. handleMissingValues ​​Flag eliminiert nur Punkte bei "unendlich" PS2. Bitte sagen Sie uns, wenn Sie dieses Problem lösen. Ich denke, es ist wertvoll für die ganze Community. Thnx

+0

Der Link ist tot, aber Internet achive hat es. –

Verwandte Themen