/* ************************************************************************* */ TEST( dataSet, writeBALfromValues_Dubrovnik){ ///< Read a file using the unit tested readBAL const string filenameToRead = findExampleDataFile("dubrovnik-3-7-pre"); SfM_data readData; readBAL(filenameToRead, readData); Pose3 poseChange = Pose3(Rot3::ypr(-M_PI/10, 0., -M_PI/10), gtsam::Point3(0.3,0.1,0.3)); Values value; for(size_t i=0; i < readData.number_cameras(); i++){ // for each camera Key poseKey = symbol('x',i); Pose3 pose = poseChange.compose(readData.cameras[i].pose()); value.insert(poseKey, pose); } for(size_t j=0; j < readData.number_tracks(); j++){ // for each point Key pointKey = P(j); Point3 point = poseChange.transform_from( readData.tracks[j].p ); value.insert(pointKey, point); } // Write values and readData to a file const string filenameToWrite = createRewrittenFileName(filenameToRead); writeBALfromValues(filenameToWrite, readData, value); // Read the file we wrote SfM_data writtenData; readBAL(filenameToWrite, writtenData); // Check that the reprojection errors are the same and the poses are correct // Check number of things EXPECT_LONGS_EQUAL(3,writtenData.number_cameras()); EXPECT_LONGS_EQUAL(7,writtenData.number_tracks()); const SfM_Track& track0 = writtenData.tracks[0]; EXPECT_LONGS_EQUAL(3,track0.number_measurements()); // Check projection of a given point EXPECT_LONGS_EQUAL(0,track0.measurements[0].first); const SfM_Camera& camera0 = writtenData.cameras[0]; Point2 expected = camera0.project(track0.p), actual = track0.measurements[0].second; EXPECT(assert_equal(expected,actual,12)); Pose3 expectedPose = camera0.pose(); Key poseKey = symbol('x',0); Pose3 actualPose = value.at<Pose3>(poseKey); EXPECT(assert_equal(expectedPose,actualPose, 1e-7)); Point3 expectedPoint = track0.p; Key pointKey = P(0); Point3 actualPoint = value.at<Point3>(pointKey); EXPECT(assert_equal(expectedPoint,actualPoint, 1e-6)); }
/* ************************************************************************* */ TEST( dataSet, writeBAL_Dubrovnik) { ///< Read a file using the unit tested readBAL const string filenameToRead = findExampleDataFile("dubrovnik-3-7-pre"); SfM_data readData; readBAL(filenameToRead, readData); // Write readData to file filenameToWrite const string filenameToWrite = createRewrittenFileName(filenameToRead); CHECK(writeBAL(filenameToWrite, readData)); // Read what we wrote SfM_data writtenData; CHECK(readBAL(filenameToWrite, writtenData)); // Check that what we read is the same as what we wrote EXPECT(assert_equal(readData.number_cameras(),writtenData.number_cameras())); EXPECT(assert_equal(readData.number_tracks(),writtenData.number_tracks())); for (size_t i = 0; i < readData.number_cameras(); i++){ PinholeCamera<Cal3Bundler> expectedCamera = writtenData.cameras[i]; PinholeCamera<Cal3Bundler> actualCamera = readData.cameras[i]; EXPECT(assert_equal(expectedCamera,actualCamera)); } for (size_t j = 0; j < readData.number_tracks(); j++){ // check point SfM_Track expectedTrack = writtenData.tracks[j]; SfM_Track actualTrack = readData.tracks[j]; Point3 expectedPoint = expectedTrack.p; Point3 actualPoint = actualTrack.p; EXPECT(assert_equal(expectedPoint,actualPoint)); // check rgb Point3 expectedRGB = Point3( expectedTrack.r, expectedTrack.g, expectedTrack.b ); Point3 actualRGB = Point3( actualTrack.r, actualTrack.g, actualTrack.b); EXPECT(assert_equal(expectedRGB,actualRGB)); // check measurements for (size_t k = 0; k < actualTrack.number_measurements(); k++){ EXPECT(assert_equal(expectedTrack.measurements[k].first,actualTrack.measurements[k].first)); EXPECT(assert_equal(expectedTrack.measurements[k].second,actualTrack.measurements[k].second)); } } }
/* ************************************************************************* */ TEST( dataSet, Balbianello) { ///< The structure where we will save the SfM data const string filename = findExampleDataFile("Balbianello"); SfM_data mydata; CHECK(readBundler(filename, mydata)); // Check number of things EXPECT_LONGS_EQUAL(5,mydata.number_cameras()); EXPECT_LONGS_EQUAL(544,mydata.number_tracks()); const SfM_Track& track0 = mydata.tracks[0]; EXPECT_LONGS_EQUAL(3,track0.number_measurements()); // Check projection of a given point EXPECT_LONGS_EQUAL(0,track0.measurements[0].first); const SfM_Camera& camera0 = mydata.cameras[0]; Point2 expected = camera0.project(track0.p), actual = track0.measurements[0].second; EXPECT(assert_equal(expected,actual,1)); }
/* ************************************************************************* */ int main (int argc, char* argv[]) { // Find default file, but if an argument is given, try loading a file string filename = findExampleDataFile("dubrovnik-3-7-pre"); if (argc>1) filename = string(argv[1]); // Load the SfM data from file SfM_data mydata; assert(readBAL(filename, mydata)); cout << boost::format("read %1% tracks on %2% cameras\n") % mydata.number_tracks() % mydata.number_cameras(); // Create a factor graph NonlinearFactorGraph graph; // We share *one* noiseModel between all projection factors noiseModel::Isotropic::shared_ptr noise = noiseModel::Isotropic::Sigma(2, 1.0); // one pixel in u and v // Add measurements to the factor graph size_t j = 0; BOOST_FOREACH(const SfM_Track& track, mydata.tracks) { BOOST_FOREACH(const SfM_Measurement& m, track.measurements) { size_t i = m.first; Point2 uv = m.second; graph.push_back(MyFactor(uv, noise, C(i), P(j))); // note use of shorthand symbols C and P } j += 1; } // Add a prior on pose x1. This indirectly specifies where the origin is. // and a prior on the position of the first landmark to fix the scale graph.push_back(PriorFactor<SfM_Camera>(C(0), mydata.cameras[0], noiseModel::Isotropic::Sigma(9, 0.1))); graph.push_back(PriorFactor<Point3> (P(0), mydata.tracks[0].p, noiseModel::Isotropic::Sigma(3, 0.1))); // Create initial estimate Values initial; size_t i = 0; j = 0; BOOST_FOREACH(const SfM_Camera& camera, mydata.cameras) initial.insert(C(i++), camera); BOOST_FOREACH(const SfM_Track& track, mydata.tracks) initial.insert(P(j++), track.p); /* Optimize the graph and print results */ Values result; try { LevenbergMarquardtParams params; params.setVerbosity("ERROR"); LevenbergMarquardtOptimizer lm(graph, initial, params); result = lm.optimize(); } catch (exception& e) { cout << e.what(); } cout << "final error: " << graph.error(result) << endl; return 0; }
/* ************************************************************************* */ int main (int argc, char* argv[]) { // Find default file, but if an argument is given, try loading a file string filename = findExampleDataFile("dubrovnik-3-7-pre"); if (argc>1) filename = string(argv[1]); // Load the SfM data from file SfM_data mydata; readBAL(filename, mydata); cout << boost::format("read %1% tracks on %2% cameras\n") % mydata.number_tracks() % mydata.number_cameras(); // Create a factor graph NonlinearFactorGraph graph; // We share *one* noiseModel between all projection factors noiseModel::Isotropic::shared_ptr noise = noiseModel::Isotropic::Sigma(2, 1.0); // one pixel in u and v // Add measurements to the factor graph size_t j = 0; BOOST_FOREACH(const SfM_Track& track, mydata.tracks) { BOOST_FOREACH(const SfM_Measurement& m, track.measurements) { size_t i = m.first; Point2 uv = m.second; graph.push_back(MyFactor(uv, noise, C(i), P(j))); // note use of shorthand symbols C and P } j += 1; } // Add a prior on pose x1. This indirectly specifies where the origin is. // and a prior on the position of the first landmark to fix the scale graph.push_back(PriorFactor<SfM_Camera>(C(0), mydata.cameras[0], noiseModel::Isotropic::Sigma(9, 0.1))); graph.push_back(PriorFactor<Point3> (P(0), mydata.tracks[0].p, noiseModel::Isotropic::Sigma(3, 0.1))); // Create initial estimate Values initial; size_t i = 0; j = 0; BOOST_FOREACH(const SfM_Camera& camera, mydata.cameras) initial.insert(C(i++), camera); BOOST_FOREACH(const SfM_Track& track, mydata.tracks) initial.insert(P(j++), track.p); /** --------------- COMPARISON -----------------------**/ /** ----------------------------------------------------**/ LevenbergMarquardtParams params_using_COLAMD, params_using_METIS; try { params_using_METIS.setVerbosity("ERROR"); gttic_(METIS_ORDERING); params_using_METIS.ordering = Ordering::Create(Ordering::METIS, graph); gttoc_(METIS_ORDERING); params_using_COLAMD.setVerbosity("ERROR"); gttic_(COLAMD_ORDERING); params_using_COLAMD.ordering = Ordering::Create(Ordering::COLAMD, graph); gttoc_(COLAMD_ORDERING); } catch (exception& e) { cout << e.what(); } // expect they have different ordering results if(params_using_COLAMD.ordering == params_using_METIS.ordering) { cout << "COLAMD and METIS produce the same ordering. " << "Problem here!!!" << endl; } /* Optimize the graph with METIS and COLAMD and time the results */ Values result_METIS, result_COLAMD; try { gttic_(OPTIMIZE_WITH_METIS); LevenbergMarquardtOptimizer lm_METIS(graph, initial, params_using_METIS); result_METIS = lm_METIS.optimize(); gttoc_(OPTIMIZE_WITH_METIS); gttic_(OPTIMIZE_WITH_COLAMD); LevenbergMarquardtOptimizer lm_COLAMD(graph, initial, params_using_COLAMD); result_COLAMD = lm_COLAMD.optimize(); gttoc_(OPTIMIZE_WITH_COLAMD); } catch (exception& e) { cout << e.what(); } { // printing the result cout << "COLAMD final error: " << graph.error(result_COLAMD) << endl; cout << "METIS final error: " << graph.error(result_METIS) << endl; cout << endl << endl; cout << "Time comparison by solving " << filename << " results:" << endl; cout << boost::format("%1% point tracks and %2% cameras\n") \ % mydata.number_tracks() % mydata.number_cameras() \ << endl; tictoc_print_(); } return 0; }