Skip to content

Instantly share code, notes, and snippets.

@edgarriba
Created February 22, 2016 15:10
Show Gist options
  • Save edgarriba/38b3fa347107f0fbaf2e to your computer and use it in GitHub Desktop.
Save edgarriba/38b3fa347107f0fbaf2e to your computer and use it in GitHub Desktop.
External features extraction
/* Reimplementation of `AddImagesToReconstructionBuilder`
https://github.com/sweeneychris/TheiaSfM/blob/master/applications/build_reconstruction.cc#L334
Using an external local features extractor. In this case AKAZE from OpenCV.
*/
void AddImagesToReconstructionBuilder(
ReconstructionBuilder* reconstruction_builder) {
std::vector<std::string> image_files;
CHECK(theia::GetFilepathsFromWildcard(FLAGS_images, &image_files));
// Create the feature matcher.
theia::FeatureMatcherOptions matching_options;
theia::VerifyTwoViewMatchesOptions verification_options;
SetMatchingOptions(&matching_options, &verification_options);
const theia::MatchingStrategy matching_strategy =
StringToMatchingStrategyType(FLAGS_matching_strategy);
std::unique_ptr<theia::FeatureMatcher<theia::L2> > matcher =
CreateFeatureMatcher(matching_strategy, matching_options);
cv::Mat img, opencv_descs;
std::vector<cv::KeyPoint> opencv_kpts;
cv::Ptr<cv::Feature2D> extractor = cv::AKAZE::create();
std::vector<theia::Keypoint> theia_kpts;
std::vector<Eigen::VectorXf> theia_descs;
for (size_t i = 0; i < image_files.size(); ++i) {
img = cv::imread(image_files[i], cv::IMREAD_COLOR);
extractor->detectAndCompute(img, cv::Mat(), opencv_kpts, opencv_descs);
// conversion between OpenCV/Theia
opencv_kpts_to_theia(opencv_kpts, &theia_kpts);
opencv_descriptors_to_theia(opencv_descs, &theia_descs);
std::string image_name;
theia::GetFilenameFromFilepath(image_files[i], true, &image_name);
matcher->AddImage(image_name, theia_kpts, theia_descs);
LOG(INFO) << "Added Image " << image_name << " with "
<< theia_kpts.size() << " Keypoints, "
<< theia_descs.size() << " Descriptors";
}
LOG(INFO) << "Perform MATCHING!";
std::vector<theia::ImagePairMatch> image_matches;
//matcher->MatchImages(&image_matches);
// Or, with geometric verification:
matcher->MatchImagesWithGeometricVerification(
verification_options, &image_matches);
// Optionally read the intrinsics from a calibration file.
std::vector<theia::CameraIntrinsicsPrior> camera_intrinsics_prior;
ReadIntrinsicsFromCalibrationFile(image_files, &camera_intrinsics_prior);
// Write the matches out.
LOG(INFO) << "Writing matches to file: " << FLAGS_output_matches_file;
CHECK(theia::WriteMatchesAndGeometry(FLAGS_output_matches_file,
image_files,
camera_intrinsics_prior, image_matches))
<< "Could not write the matches to " << FLAGS_output_matches_file;
// Add all the views.
for (int i = 0; i < image_files.size(); i++) {
reconstruction_builder->AddImage(image_files[i]);
}
// Add the matches.
for (const auto& match : image_matches) {
CHECK(reconstruction_builder->AddTwoViewMatch(match.image1,
match.image2,
match));
}
}
@sweeneychris
Copy link

@avanindra is correct. You should build Ceres with SuiteSparse (the failing module is for position estimation) then this problem will be fixed.

@edgarriba
Copy link
Author

Suitesparse was detected during Ceres installation. Just tried to reinstall everything again to be sure but got the same log. I'm using the Global solver which fails, however with Incremental got an approximated result of the real solution.

@shenw000
Copy link

edgarriba,

Would you mind to share your code for the following functions?
opencv_kpts_to_theia(opencv_kpts, &theia_kpts);
opencv_descriptors_to_theia(opencv_descs, &theia_descs);
I need to use these functions but don't want to reinvent the wheels.... Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment