features_matcher.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  *
00003  * Software License Agreement (BSD License)
00004  *
00005  *  Copyright (c) 2000-2008, Intel Corporation, all rights reserved.
00006  *  Copyright (c) 2009, Willow Garage Inc., all rights reserved.
00007  *  Copyright (c) 2015-2016, Jiri Horner.
00008  *  All rights reserved.
00009  *
00010  *  Redistribution and use in source and binary forms, with or without
00011  *  modification, are permitted provided that the following conditions
00012  *  are met:
00013  *
00014  *   * Redistributions of source code must retain the above copyright
00015  *     notice, this list of conditions and the following disclaimer.
00016  *   * Redistributions in binary form must reproduce the above
00017  *     copyright notice, this list of conditions and the following
00018  *     disclaimer in the documentation and/or other materials provided
00019  *     with the distribution.
00020  *   * Neither the name of the author nor the names of its
00021  *     contributors may be used to endorse or promote products derived
00022  *     from this software without specific prior written permission.
00023  *
00024  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00026  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00027  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00028  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00029  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00030  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00031  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00032  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00034  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00035  *  POSSIBILITY OF SUCH DAMAGE.
00036  *
00037  *********************************************************************/
00038 
00039 #include <combine_grids/features_matcher.h>
00040 
00041 #include <combine_grids/estimate_rigid_transform.h>
00042 
00043 #include <opencv2/core/utility.hpp>
00044 #include <opencv2/video/tracking.hpp>
00045 
00046 #include <ros/console.h>
00047 #include <ros/assert.h>
00048 
00049 namespace combine_grids
00050 {
00051 namespace internal
00052 {
00053 /* modified implementation of match from BestOf2NearestMatcher */
00054 void AffineBestOf2NearestMatcher::match(
00055     const cv::detail::ImageFeatures &features1,
00056     const cv::detail::ImageFeatures &features2,
00057     cv::detail::MatchesInfo &matches_info)
00058 {
00059   (*impl_)(features1, features2, matches_info);
00060 
00061   ROS_DEBUG("AffineMatcher: have %lu matches", matches_info.matches.size());
00062 
00063   // Check if it makes sense to find homography
00064   if (matches_info.matches.size() < static_cast<size_t>(num_matches_thresh1_))
00065     return;
00066 
00067   // Construct point-point correspondences for homography estimation
00068   // Points are centered s.t. image center is (0,0). This is similar to other
00069   // matchers a shows better results in practice (numerical stability?).
00070   cv::Mat src_points(1, static_cast<int>(matches_info.matches.size()),
00071                      CV_32FC2);
00072   cv::Mat dst_points(1, static_cast<int>(matches_info.matches.size()),
00073                      CV_32FC2);
00074   for (size_t i = 0; i < matches_info.matches.size(); ++i) {
00075     const cv::DMatch &m = matches_info.matches[i];
00076 
00077     cv::Point2f p = features1.keypoints[static_cast<size_t>(m.queryIdx)].pt;
00078     p.x -= features1.img_size.width * 0.5f;
00079     p.y -= features1.img_size.height * 0.5f;
00080     src_points.at<cv::Point2f>(0, static_cast<int>(i)) = p;
00081 
00082     p = features2.keypoints[static_cast<size_t>(m.trainIdx)].pt;
00083     p.x -= features2.img_size.width * 0.5f;
00084     p.y -= features2.img_size.height * 0.5f;
00085     dst_points.at<cv::Point2f>(0, static_cast<int>(i)) = p;
00086   }
00087 
00088   // Find pair-wise motion
00089   // this is my special modified version of estimateRigidTransform
00090   matches_info.H = estimateRigidTransform(src_points, dst_points,
00091                                           matches_info.inliers_mask, false);
00092   ROS_DEBUG_STREAM("estimate:\n" << matches_info.H);
00093 
00094   if (matches_info.H.empty()) {
00095     // could not find trasformation
00096     matches_info.confidence = 0;
00097     matches_info.num_inliers = 0;
00098     return;
00099   }
00100 
00101   // extend H to represent linear tranformation in homogeneous coordinates
00102   matches_info.H.push_back(cv::Mat::zeros(1, 3, CV_64F));
00103   matches_info.H.at<double>(2, 2) = 1;
00104 
00105   /* TODO: should we handle determinant ~ 0 (can it happen due to agressive
00106    * scaling?) */
00107 
00108   // Find number of inliers
00109   matches_info.num_inliers = 0;
00110   for (size_t i = 0; i < matches_info.inliers_mask.size(); ++i)
00111     if (matches_info.inliers_mask[i])
00112       matches_info.num_inliers++;
00113 
00114   ROS_DEBUG("num_inliers %d", matches_info.num_inliers);
00115 
00116   // These coeffs are from paper M. Brown and D. Lowe. "Automatic Panoramic
00117   // Image Stitching using Invariant Features"
00118   matches_info.confidence =
00119       matches_info.num_inliers / (8 + 0.3 * matches_info.matches.size());
00120 
00121   /* we don't want any cuttof for merging maps. TODO: allow to set this in
00122    * constructor. */
00123   // Set zero confidence to remove matches between too close images, as they
00124   // don't provide additional information anyway. The threshold was set
00125   // experimentally.
00126   // matches_info.confidence =
00127   // matches_info.confidence > 3. ? 0. : matches_info.confidence;
00128 
00129   /* Unlike other matchers it makes no sense to rerun estimation on liers only.
00130    * estimateRigidTransform already did this for us. So we are done here. */
00131 }
00132 
00133 }  // namespace internal
00134 }  // namespace combine_grids


map_merge
Author(s): Jiri Horner
autogenerated on Sun Mar 26 2017 03:48:10