40 #include <opencv2/imgproc/types_c.h>
49 "evalStereo.exe left.png right.png calib.txt disp.pfm mask.png [Parameters]\n"
50 "Example (with http://vision.middlebury.edu/stereo datasets):\n"
51 " $ ./rtabmap-stereoEval im0.png im1.png calib.txt disp0GT.pfm mask0nocc.png -Kp/DetectorStrategy 6 -Stereo/WinSize 5 -Stereo/MaxLevel 2 -Kp/WordsPerImage 1000 -Stereo/OpticalFlow false -Stereo/Iterations 5\n\n");
66 for(
int i=6;
i<argc; ++
i)
71 if(parameters.find(
key) != parameters.end())
86 if(inserted.second ==
false)
88 inserted.first->second =
value;
116 if(oldIter->second.first)
118 key = oldIter->second.second;
119 UWARN(
"Parameter migration from \"%s\" to \"%s\" (value=%s).",
120 oldIter->first.c_str(), oldIter->second.second.c_str(),
value.c_str());
122 else if(oldIter->second.second.empty())
124 UERROR(
"Parameter \"%s\" doesn't exist anymore.", oldIter->first.c_str());
128 UERROR(
"Parameter \"%s\" doesn't exist anymore, check this similar parameter \"%s\".", oldIter->first.c_str(), oldIter->second.second.c_str());
130 if(oldIter->second.first)
133 if(inserted.second ==
false)
135 inserted.first->second =
value;
146 printf(
"Unrecognized option : %s\n",
argv[
i]);
150 UINFO(
"Loading files...");
152 cv::Mat left = cv::imread(
argv[1]);
153 cv::Mat right = cv::imread(
argv[2]);
157 if(!left.empty() && !right.empty() && !disp.empty() && !
mask.empty())
159 UASSERT(left.rows == disp.rows);
160 UASSERT(left.cols == disp.cols);
180 std::string calibFile =
argv[3];
181 std::ifstream
stream(calibFile.c_str());
185 UINFO(
"Loading calibration... (%s)", calibFile.c_str());
186 std::vector<cv::Mat>
K(2);
187 for(
int i=0;
i<2; ++
i)
193 UINFO(
"K[%d] = %s",
i, line.c_str());
195 UASSERT(valuesStr.size() == 9);
196 K[
i] = cv::Mat(3,3,CV_64FC1);
197 for(
unsigned int j=0;
j<valuesStr.size(); ++
j)
214 CameraModel(
K[0].at<double>(0,0),
K[0].at<double>(1,1),
K[0].at<double>(0,2),
K[0].at<double>(1,2)),
215 CameraModel(
K[1].at<double>(0,0),
K[1].at<double>(1,1),
K[1].at<double>(0,2),
K[1].at<double>(1,2),
Transform::getIdentity(), -
baseline/
K[1].at<double>(0,0)));
219 UINFO(
"Processing...");
223 if(left.channels() == 3)
225 cv::cvtColor(left, leftMono, CV_BGR2GRAY);
232 if(right.channels() == 3)
234 cv::cvtColor(right, rightMono, CV_BGR2GRAY);
247 std::vector<cv::KeyPoint> kpts;
253 timeKpts =
timer.ticks();
255 std::vector<cv::Point2f> leftCorners(kpts.size());
256 cv::KeyPoint::convert(kpts, leftCorners);
257 int subPixWinSize = 0;
258 int subPixIterations = 0;
259 double subPixEps = 0;
261 Parameters::parse(parameters, Parameters::kKpSubPixIterations(), subPixIterations);
263 if(subPixWinSize > 0 && subPixIterations > 0)
265 UDEBUG(
"cv::cornerSubPix() begin");
266 cv::cornerSubPix(leftMono, leftCorners,
267 cv::Size( subPixWinSize, subPixWinSize ),
269 cv::TermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, subPixIterations, subPixEps ) );
270 UDEBUG(
"cv::cornerSubPix() end");
273 timeSubPixel =
timer.ticks();
276 std::vector<unsigned char> status;
277 std::vector<cv::Point2f> rightCorners;
279 bool opticalFlow =
false;
288 stereo =
new Stereo(parameters);
298 timeStereo =
timer.ticks();
300 UINFO(
"Time: kpts:%f s, subpix=%f s, stereo=%f s", timeKpts, timeSubPixel, timeStereo);
307 float sumInliers = 0.0f;
308 float sumSubInliers = 0.0f;
309 int goodRejected = 0;
311 for(
unsigned int i=0;
i<leftCorners.size(); ++
i)
313 float gt = disp.at<
float>(
int(rightCorners[
i].
y),
int(leftCorners[
i].
x));
316 float d = leftCorners[
i].x - rightCorners[
i].x;
322 if(
fabs(
d-gt) < 1.0f)
326 cv::Point2f(leftCorners[
i].
x - gt, leftCorners[
i].
y),
327 cv::Scalar( 0, 255, 0 ));
330 cv::Point2f(leftCorners[
i].
x - (
d<gt?
d:gt), leftCorners[
i].
y),
331 cv::Point2f(leftCorners[
i].
x - (
d>gt?
d:gt), leftCorners[
i].
y),
332 cv::Scalar( 0, 0, 255 ));
335 sumInliers +=
fabs(
d-gt);
340 sumSubInliers +=
fabs(
d-gt);
343 else if(
mask.at<cv::Vec3b>(
int(rightCorners[
i].y),
int(leftCorners[
i].x))[0] == 255)
347 cv::Point2f(leftCorners[
i].
x - gt, leftCorners[
i].
y),
348 cv::Scalar( 0, 255, 0 ));
351 cv::Point2f(leftCorners[
i].
x - (
d<gt?
d:gt), leftCorners[
i].
y),
352 cv::Point2f(leftCorners[
i].
x - (
d>gt?
d:gt), leftCorners[
i].
y),
353 cv::Scalar( 0, 0, 255 ));
361 cv::Point2f(leftCorners[
i].
x - gt, leftCorners[
i].
y),
362 cv::Scalar( 255, 0, 0 ));
365 cv::Point2f(leftCorners[
i].
x - (
d<gt?
d:gt), leftCorners[
i].
y),
366 cv::Point2f(leftCorners[
i].
x - (
d>gt?
d:gt), leftCorners[
i].
y),
367 cv::Scalar( 0, 0, 255 ));
377 else if(
mask.at<cv::Vec3b>(
int(rightCorners[
i].y),
int(leftCorners[
i].x))[0] == 255 &&
378 rightCorners[
i].x > 0.0f)
380 float d = leftCorners[
i].x - rightCorners[
i].x;
385 cv::Point2f(leftCorners[
i].
x - gt, leftCorners[
i].
y),
386 cv::Scalar( 0, 255, 255 ));
389 cv::Point2f(leftCorners[
i].
x - (
d<gt?
d:gt), leftCorners[
i].
y),
390 cv::Point2f(leftCorners[
i].
x - (
d>gt?
d:gt), leftCorners[
i].
y),
391 cv::Scalar( 0, 0, 255 ));
407 UINFO(
"good accepted=%d (%d%%) bad accepted=%d (%d%%) good rejected=%d (%d%%) bad rejected=%d (%d%%)",
409 (inliers*100)/leftCorners.size(),
411 (badInliers*100)/leftCorners.size(),
413 (goodRejected*100)/leftCorners.size(),
415 (badRejected*100)/leftCorners.size());
416 UINFO(
"avg inliers =%f (subInliers=%f)", sumInliers/
float(inliers), sumSubInliers/
float(subInliers));
419 cv::namedWindow(
"Right", cv::WINDOW_AUTOSIZE );
420 cv::imshow(
"Right", right );
422 cv::namedWindow(
"Mask", cv::WINDOW_AUTOSIZE );
423 cv::imshow(
"Mask",
mask );
425 cv::namedWindow(
"Left", cv::WINDOW_AUTOSIZE );
426 cv::imshow(
"Left", left );