Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <combine_grids/estimate_transform.h>
00038
00039 #include <cmath>
00040
00041 #include <opencv2/core/utility.hpp>
00042
00043 #include <ros/console.h>
00044 #include <ros/assert.h>
00045
00046 #include <combine_grids/features_matcher.h>
00047 #include <combine_grids/transform_estimator.h>
00048
00049 namespace combine_grids
00050 {
00051 namespace internal
00052 {
00053 size_t opencvEstimateTransform(const std::vector<cv::Mat>& images,
00054 std::vector<cv::Mat>& final_transforms,
00055 double confidence)
00056 {
00057 std::vector<cv::detail::ImageFeatures> image_features;
00058 std::vector<cv::detail::MatchesInfo> pairwise_matches;
00059 std::vector<cv::detail::CameraParams> transforms;
00060 std::vector<int> matched_indices;
00061 cv::Ptr<cv::detail::FeaturesFinder> finder =
00062 cv::makePtr<cv::detail::OrbFeaturesFinder>();
00063 cv::Ptr<cv::detail::FeaturesMatcher> matcher =
00064 cv::makePtr<internal::AffineBestOf2NearestMatcher>();
00065 cv::Ptr<cv::detail::Estimator> estimator =
00066 cv::makePtr<internal::AffineBasedEstimator>();
00067
00068 if (images.size() < 2) {
00069 return 0;
00070 }
00071
00072
00073 ROS_DEBUG("computing features");
00074 image_features.reserve(images.size());
00075 for (const cv::Mat& image : images) {
00076 image_features.emplace_back();
00077 (*finder)(image, image_features.back());
00078 }
00079 finder->collectGarbage();
00080
00081
00082
00083 ROS_DEBUG("pairwise matching features");
00084 (*matcher)(image_features, pairwise_matches);
00085 matcher->collectGarbage();
00086
00087
00088
00089 matched_indices = cv::detail::leaveBiggestComponent(
00090 image_features, pairwise_matches, static_cast<float>(confidence));
00091
00092
00093 ROS_DEBUG("estimating final transform");
00094
00095 if (!(*estimator)(image_features, pairwise_matches, transforms)) {
00096 return 0;
00097 }
00098
00099 ROS_ASSERT(matched_indices.size() == transforms.size());
00100
00101 final_transforms.clear();
00102 final_transforms.resize(images.size());
00103 size_t i = 0;
00104 for (auto& transform : transforms) {
00105 if (!transform.R.empty()) {
00106 ROS_DEBUG("TRANSFORM: trans x: %f, trans y %f, rot: %f\n",
00107 transform.R.at<double>(0, 2), transform.R.at<double>(1, 2),
00108 std::atan2(transform.R.at<double>(0, 1),
00109 transform.R.at<double>(1, 1)));
00110 }
00111
00112 final_transforms[i] = transform.R;
00113 ++i;
00114 }
00115
00116 ROS_ASSERT(final_transforms.size() == images.size());
00117
00118 return transforms.size();
00119 }
00120 }
00121 }