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:
Stereo-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.
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. –
In deinem Video hast du verschiedene Farben für unterschiedliche Disparitätswerte zugewiesen. Kannst du mir bitte sagen, wie du das gemacht hast? –
Hey Abhilesh, mein Kommentar war zu groß, also habe ich die Antwort bearbeitet, ok? Werfen Sie einen Blick in "Zweiter Teil". – ThiagoRTK