0

Ich habe versucht, den Code zu verwenden, um die Disparität zu finden, die in der Verbindung angegeben wird: link
Die Disparitätskarte scheint jedoch in einigen Bereichen falsch zu sein. Einige Objekte fern der Kamera erscheinen heller als die näheren Objekte. Ich habe versucht, die tatsächliche Tiefe zu berechnen, indem ich den Disparitätswert mit der Kalibrierungsmatrix Q multipliziere. Die berechnete Tiefe ist weit entfernt von den realen gemessenen Werten (um 20-25 cm). Ich bin zuversichtlich, dass die Matrix Q korrekt ist, da mein korrigiertes Bild gut zu sein scheint. Mein quadratischer Größenwert für die Kalibrierung war ebenfalls genau (0,05 Meter). Meine Disparität Bilder angehängt:
enter image description hereStereo-Karte mit Postfilterung

Dies ist der zusätzliche Code zur Berechnung der tatsächlichen Tiefe aus dem gefilterten Disparitätsbild in filtered_disp_vis gespeichert.

fs1["Q"] >> Q; 
Mat Image; 
Mat V = Mat(4, 1, CV_64FC1); 
Mat pos = Mat(4, 1, CV_64FC1); 
vector<Point3d> points; 
//float fMaxDistance = static_cast<float>((1./Q.at<double>(3, 2)) * 
Q.at<double>(2, 3)); 
//filtered_disp_vis.convertTo(filtered_disp_vis, CV_64FC1, 1.0/16.0, 0.0); 
//imshow("filtered disparity", filtered_disp_vis); 
// outputDisparityValue is single 16-bit value from disparityMap 
// DISP_SCALE = 16 
//float fDisparity = outputDisparityValue/
(float)StereoMatcher::DISP_SCALE; 
//float fDistance = fMaxDistance/fDisparity; 
reprojectImageTo3D(filtered_disp_vis, Image, Q, false, CV_32F); 
//cout << Image; 
for (int i = 0; i < filtered_disp_vis.cols; i++) 
{ 
for (int j = 0; j < filtered_disp_vis.rows; j++) 
{ 
int d = filtered_disp_vis.at<uchar>(j, i); 
//filtered_disp_vis.convertTo(filtered_disp_vis, CV_32F, 1.0/16.0, 0.0); 
//int l = img_left.at<uchar>(j, i); 
//cout << "(" << j << "," << i << ")" << "=" << d; 
//out << endl; 
// if low disparity, then ignore 
/*if (d < 2) { 
continue; 
}*/ 
// V is the vector to be multiplied to Q to get 
// the 3D homogenous coordinates of the image point 
V.at<double>(0, 0) = (double)(i); 
V.at<double>(1, 0) = (double)(j); 
V.at<double>(2, 0) = (double)d; 
V.at<double>(3, 0) = 1.; 
pos = Q * V; // 3D homogeneous coordinate 
double X = pos.at<double>(0, 0)/pos.at<double>(3, 0); 
double Y = pos.at<double>(1, 0)/pos.at<double>(3, 0); 
double Z = pos.at<double>(2, 0)/pos.at<double>(3, 0); 

if (i == 446 && j == 362) 
{ 
cout << "(" << j << "," << i << ")" << " = "; 

cout << X << " " << Y << " " << Z << " " << d; 
cout << endl; 
} 

Mat point3d_cam = Mat(3, 1, CV_64FC1); 
point3d_cam.at<double>(0, 0) = X; 
point3d_cam.at<double>(1, 0) = Y; 
point3d_cam.at<double>(2, 0) = Z; 
// transform 3D point from camera frame to robot frame 
//Mat point3d_robot = XR * point3d_cam + XT; 
points.push_back(Point3d(point3d_cam)); 
} 

Wohin gehe ich falsch? Alle Änderungen an meinem Snippet oder andere Empfehlungen, um richtige Disparitätskarten mit genauen Tiefenwerten zu erhalten, werden geschätzt.

Antwort

0

Ich kann in Ihrer Frage noch keinen Kommentar hinzufügen (weil minimale Reputation). Also werde ich hier kommentieren:

1 - Haben Sie versucht, ein Paar Frames aus dem KITTI-Datensatz nur mit der Post-Filterung? Wenn ja, ist das Ergebnis auch schlecht geworden?

2 - Wenn mit KITTI Datensatz in Ordnung war, so kann das Problem mit Ihrer Kalibrierung sein. Wenden Sie nach der Stereokalibrierung und der Entzerrung unverzerrt an (für beide Kameras kalibrieren)?

* undistort:


Zweiter Teil (ich versuchte es in Reaktion auf Ihren Kommentar zu setzen, aber meine Antwort war zu groß für das Kommentarfeld ...) = P

Tut mir leid die Verzögerung, aber ich war in den letzten Tagen ziemlich beschäftigt. Also, gehen wir in Teilen:

1) Ich verwendete filtered_disp_vis.

2) Wenn mit KITTI ist in Ordnung, so ist das Problem wahrscheinlich mit Ihren Kameras oder der Berichtigung. Welche Art von Kameras verwendest du? Stehen Ihre Kameras still?

2.1) Früher habe ich einfache Webcams (Rolling-Shutter-System) benutzt, aber meistens sehen die Ergebnisse schlecht aus. Das Ideal für Stereo Vision sind Kameras mit dem Global Shutter System.

3) Für verschiedene Farben habe ich "applyColorMap" von OpenCV verwendet.


Dritter Teil (zu lange wieder):

a) Nun, sieht wie folgt aus Kamerasensor Rolling Shutter ist, aber ich bin mir nicht sicher ... Kann funktioniert, aber wenn Sie möchten, Um Ihre Kamera in Bewegung zu halten, werden Sie Probleme haben. Versuchen Sie nicht, die Kameras während der Kalibrierung zu halten, versuchen Sie eine Oberfläche anzubringen und lassen Sie sie stehen.Hier hat schöne Tipps zur Kalibrierung: camera calibration

b)Es ist nicht in Echtzeit, aber es ist so schnell wie die CPU kann. Ich nehme einfach die Frames mit VideoCapture, und während die Frames weiter kommen, gehe ich zu cv :: Mat innerhalb einer "while" -Schleife.

cv::Mat imgOne, imgTwo; 

VideoCapture videoOne("path/To/The/Frames/%10d.png"); 
VideoCapture videoTwo("path/To/The/FramesTwo/%10d.png"); 

while(1){ 
    videoOne >> imgOne; 
    videoTwo >> imgTwo; 

    //rest of code. 
} 

c) Ich habe keine 3D-Rekonstruktion durchführen.

d) Mit Vec3b, um eine Position zu nehmen, und uchar, um Werte in jedem Kanal zu nehmen. Ich habe keine zusätzlichen Transformationen durchgeführt.

+0

1) Oh ja, der KITTI-Datensatz funktioniert ordnungsgemäß. Haben Sie filtered_disp oder filtered_disp_viz verwendet, um auf den Disparitätswert bei jedem Pixel zuzugreifen? 2) Nun, ich habe alle von Ihnen aufgelisteten Schritte zur Kalibrierung verwendet, und das unverzerrte Bild scheint auch in Ordnung zu sein. –

+0

In deinem Video hast du verschiedene Farben für unterschiedliche Disparitätswerte zugewiesen. Kannst du mir bitte sagen, wie du das gemacht hast? –

+0

Hey Abhilesh, mein Kommentar war zu groß, also habe ich die Antwort bearbeitet, ok? Werfen Sie einen Blick in "Zweiter Teil". – ThiagoRTK