1 // This file is part of OpenMVG, an Open Multiple View Geometry C++ library. 2 3 // Copyright (c) 2017 Pierre MOULON, Romain JANVIER. 4 5 // This Source Code Form is subject to the terms of the Mozilla Public 6 // License, v. 2.0. If a copy of the MPL was not distributed with this 7 // file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 9 #ifndef OPENMVG_MATCHING_IMAGE_COLLECTION_EO_ROBUST_HPP 10 #define OPENMVG_MATCHING_IMAGE_COLLECTION_EO_ROBUST_HPP 11 12 #include <limits> 13 #include <utility> 14 #include <vector> 15 16 #include "openMVG/cameras/Camera_Pinhole.hpp" 17 #include "openMVG/matching/indMatch.hpp" 18 #include "openMVG/matching_image_collection/Geometric_Filter_utils.hpp" 19 #include "openMVG/multiview/solver_essential_kernel.hpp" 20 #include "openMVG/multiview/essential.hpp" 21 #include "openMVG/robust_estimation/robust_estimator_ACRansac.hpp" 22 #include "openMVG/robust_estimation/robust_estimator_ACRansacKernelAdaptator.hpp" 23 #include "openMVG/sfm/sfm_data.hpp" 24 #include "openMVG/types.hpp" 25 26 namespace openMVG { 27 28 namespace sfm { 29 struct Regions_Provider; 30 } 31 32 namespace matching_image_collection { 33 34 //-- A contrario essential matrix estimation template functor used for filter pair of putative correspondences 35 struct GeometricFilter_EOMatrix_RA 36 { GeometricFilter_EOMatrix_RAopenMVG::matching_image_collection::GeometricFilter_EOMatrix_RA37 GeometricFilter_EOMatrix_RA 38 ( 39 double dPrecision = std::numeric_limits<double>::infinity(), 40 uint32_t iteration = 1024 41 ): 42 m_dPrecision(dPrecision), 43 m_stIteration(iteration), 44 m_E(Mat3::Identity()) 45 { 46 } 47 48 /// Robust fitting according an Orthographic Epipolar Geometry criteria 49 template<typename Regions_or_Features_ProviderT> Robust_estimationopenMVG::matching_image_collection::GeometricFilter_EOMatrix_RA50 bool Robust_estimation 51 ( 52 const sfm::SfM_Data * sfm_data, 53 const std::shared_ptr<Regions_or_Features_ProviderT> & regions_provider, 54 const Pair pairIndex, 55 const matching::IndMatches & vec_PutativeMatches, 56 matching::IndMatches & geometric_inliers 57 ) 58 { 59 geometric_inliers.clear(); 60 61 // Get back corresponding view index 62 const IndexT 63 iIndex = pairIndex.first, 64 jIndex = pairIndex.second; 65 66 //-- 67 // Reject pair with missing Intrinsic information 68 //-- 69 70 const sfm::View 71 * view_I = sfm_data->views.at(iIndex).get(), 72 * view_J = sfm_data->views.at(jIndex).get(); 73 74 // Check that valid cameras can be retrieved for the pair of views 75 const cameras::IntrinsicBase 76 * cam_I = 77 sfm_data->GetIntrinsics().count(view_I->id_intrinsic) ? 78 sfm_data->GetIntrinsics().at(view_I->id_intrinsic).get() : nullptr, 79 * cam_J = 80 sfm_data->GetIntrinsics().count(view_J->id_intrinsic) ? 81 sfm_data->GetIntrinsics().at(view_J->id_intrinsic).get() : nullptr; 82 83 if (!cam_I || !cam_J) 84 return false; 85 if (!isPinhole(cam_I->getType()) || !isPinhole(cam_J->getType())) 86 return false; 87 88 //-- 89 // Get corresponding point regions arrays 90 //-- 91 92 Mat2X xI,xJ; 93 MatchesPairToMat(pairIndex, vec_PutativeMatches, sfm_data, regions_provider, xI, xJ); 94 95 // Update precision if required (normalization from image to camera plane): 96 if (m_dPrecision != std::numeric_limits<double>::infinity()) 97 { 98 m_dPrecision = (cam_I->imagePlane_toCameraPlaneError(Square(m_dPrecision)) + 99 cam_J->imagePlane_toCameraPlaneError(Square(m_dPrecision))) / 2.; 100 } 101 102 //-- 103 // Robust estimation 104 //-- 105 106 // Define the Kernel 107 // --- using KernelType = essential::kernel::ThreePointKernel; 108 using KernelType = 109 robust::ACKernelAdaptorEssentialOrtho< 110 essential::kernel::ThreePointKernel, 111 essential::kernel::OrthographicSymmetricEpipolarDistanceError, 112 Mat3>; 113 114 const KernelType kernel( 115 (*cam_I)(xI), 116 sfm_data->GetViews().at(iIndex)->ui_width, 117 sfm_data->GetViews().at(iIndex)->ui_height, 118 (*cam_J)(xJ), 119 sfm_data->GetViews().at(jIndex)->ui_width, 120 sfm_data->GetViews().at(jIndex)->ui_height 121 ); 122 123 // Robustly estimate the model with AC-RANSAC 124 std::vector<uint32_t> vec_inliers; 125 126 const auto ACRansacOut = ACRANSAC( 127 kernel, vec_inliers, m_stIteration, &m_E, m_dPrecision); 128 129 if (vec_inliers.size() > KernelType::MINIMUM_SAMPLES * 2.5) 130 { 131 // update geometric_inliers 132 geometric_inliers.reserve(vec_inliers.size()); 133 for (const uint32_t & index : vec_inliers) 134 { 135 geometric_inliers.push_back( vec_PutativeMatches[index] ); 136 } 137 return true; 138 } 139 else 140 { 141 vec_inliers.clear(); 142 return false; 143 } 144 } 145 Geometry_guided_matchingopenMVG::matching_image_collection::GeometricFilter_EOMatrix_RA146 bool Geometry_guided_matching 147 ( 148 const sfm::SfM_Data * sfm_data, 149 const std::shared_ptr<sfm::Regions_Provider> & regions_provider, 150 const Pair pairIndex, 151 const double dDistanceRatio, 152 matching::IndMatches & matches 153 ) 154 { 155 return false; 156 } 157 158 uint32_t m_stIteration; // maximal number of iteration for robust estimation 159 double m_dPrecision; // upper_bound precision used for robust estimation 160 // 161 //-- Stored data 162 Mat3 m_E; 163 }; 164 165 } //namespace matching_image_collection 166 } // namespace openMVG 167 168 #endif //OPENMVG_MATCHING_IMAGE_COLLECTION_EO_ROBUST_HPP 169