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");
55 int main(
int argc,
char * argv[])
66 for(
int i=6; i<argc; ++i)
69 std::string key = argv[i];
70 key =
uSplit(key,
'-').back();
71 if(parameters.find(key) != parameters.end())
76 std::string value = argv[i];
85 std::pair<ParametersMap::iterator, bool> inserted = parameters.insert(
ParametersPair(key, value));
86 if(inserted.second ==
false)
88 inserted.first->second = value;
106 std::string value = argv[i];
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)
132 std::pair<ParametersMap::iterator, bool> inserted = parameters.insert(
ParametersPair(key, value));
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]);
154 cv::Mat disp =
readPFM(argv[4]);
155 cv::Mat
mask = cv::imread(argv[5]);
157 if(!left.empty() && !right.empty() && !disp.empty() && !mask.empty())
159 UASSERT(left.rows == disp.rows);
160 UASSERT(left.cols == disp.cols);
161 UASSERT(disp.rows == mask.rows);
162 UASSERT(disp.cols == mask.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)
189 getline(stream, line);
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)
204 getline(stream, line);
207 getline(stream, line);
210 UINFO(
"Baseline = %f", baseline);
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);
302 UDEBUG(
"Mask = %d", mask.type());
308 float sumInliers = 0.0f;
309 float sumSubInliers = 0.0f;
310 int goodRejected = 0;
312 for(
unsigned int i=0; i<leftCorners.size(); ++i)
314 float gt = disp.at<
float>(int(rightCorners[i].y), int(leftCorners[i].x));
317 float d = leftCorners[i].x - rightCorners[i].x;
323 if(fabs(d-gt) < 1.0f)
327 cv::Point2f(leftCorners[i].x - gt, leftCorners[i].y),
328 cv::Scalar( 0, 255, 0 ));
331 cv::Point2f(leftCorners[i].x - (d<gt?d:gt), leftCorners[i].y),
332 cv::Point2f(leftCorners[i].x - (d>gt?d:gt), leftCorners[i].y),
333 cv::Scalar( 0, 0, 255 ));
336 sumInliers += fabs(d-gt);
338 if(fabs(d-gt) < 0.5
f)
341 sumSubInliers += fabs(d-gt);
344 else if(mask.at<cv::Vec3b>(
int(rightCorners[i].y),
int(leftCorners[i].x))[0] == 255)
348 cv::Point2f(leftCorners[i].x - gt, leftCorners[i].y),
349 cv::Scalar( 0, 255, 0 ));
352 cv::Point2f(leftCorners[i].x - (d<gt?d:gt), leftCorners[i].y),
353 cv::Point2f(leftCorners[i].x - (d>gt?d:gt), leftCorners[i].y),
354 cv::Scalar( 0, 0, 255 ));
362 cv::Point2f(leftCorners[i].x - gt, leftCorners[i].y),
363 cv::Scalar( 255, 0, 0 ));
366 cv::Point2f(leftCorners[i].x - (d<gt?d:gt), leftCorners[i].y),
367 cv::Point2f(leftCorners[i].x - (d>gt?d:gt), leftCorners[i].y),
368 cv::Scalar( 0, 0, 255 ));
374 else if(mask.at<cv::Vec3b>(
int(rightCorners[i].y),
int(leftCorners[i].x))[0] == 255 &&
375 rightCorners[i].x > 0.0f)
377 float d = leftCorners[i].x - rightCorners[i].x;
380 cv::Point2f(leftCorners[i].x - gt, leftCorners[i].y),
381 cv::Scalar( 0, 255, 255 ));
384 cv::Point2f(leftCorners[i].x - (d<gt?d:gt), leftCorners[i].y),
385 cv::Point2f(leftCorners[i].x - (d>gt?d:gt), leftCorners[i].y),
386 cv::Scalar( 0, 0, 255 ));
397 UINFO(
"inliers=%d (%d%%) subInliers=%d (%d%%) bad inliers=%d (%d%%) bad accepted=%d (%d%%) good rejected=%d (%d%%) bad rejected=%d (%d%%)",
399 (inliers*100)/leftCorners.size(),
401 (subInliers*100)/leftCorners.size(),
403 (badInliers*100)/leftCorners.size(),
405 (outliers*100)/leftCorners.size(),
407 (goodRejected*100)/leftCorners.size(),
409 (badRejected*100)/leftCorners.size());
410 UINFO(
"avg inliers =%f (subInliers=%f)", sumInliers/
float(inliers), sumSubInliers/
float(subInliers));
413 cv::namedWindow(
"Right", cv::WINDOW_AUTOSIZE );
414 cv::imshow(
"Right", right );
416 cv::namedWindow(
"Mask", cv::WINDOW_AUTOSIZE );
417 cv::imshow(
"Mask", mask );
419 cv::namedWindow(
"Left", cv::WINDOW_AUTOSIZE );
420 cv::imshow(
"Left", left );
GLM_FUNC_DECL genIType mask(genIType const &count)
static bool parse(const ParametersMap ¶meters, const std::string &key, bool &value)
static const std::map< std::string, std::pair< bool, std::string > > & getRemovedParameters()
double UTILITE_EXP uStr2Double(const std::string &str)
int main(int argc, char *argv[])
std::pair< std::string, std::string > ParametersPair
std::vector< cv::KeyPoint > generateKeypoints(const cv::Mat &image, const cv::Mat &mask=cv::Mat()) const
std::map< std::string, std::string > ParametersMap
Basic mathematics functions.
Some conversion functions.
static void setLevel(ULogger::Level level)
std::list< std::string > uSplit(const std::string &str, char separator= ' ')
bool uIsFinite(const T &value)
#define UASSERT(condition)
Wrappers of STL for convenient functions.
virtual std::vector< cv::Point2f > computeCorrespondences(const cv::Mat &leftImage, const cv::Mat &rightImage, const std::vector< cv::Point2f > &leftCorners, std::vector< unsigned char > &status) const
bool isValidForProjection() const
static Feature2D * create(const ParametersMap ¶meters=ParametersMap())
static void setType(Type type, const std::string &fileName=kDefaultLogFileName, bool append=true)
std::string UTILITE_EXP uReplaceChar(const std::string &str, char before, char after)
std::vector< V > uListToVector(const std::list< V > &list)
static const ParametersMap & getDefaultParameters()
ULogger class and convenient macros.
cv::Mat readPFM(const char *filename)
void uInsert(std::map< K, V > &map, const std::pair< K, V > &pair)