From 2ab770645427c7c57bc4989f09f1650056e5c152 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Mon, 18 May 2015 09:34:48 +0200 Subject: [PATCH 01/52] Typo fix --- src/openMVG/geometry/pose3.hpp | 2 +- src/software/SfM/SfM_GlobalPipeline.py.in | 2 +- src/software/SfM/SfM_SequentialPipeline.py.in | 2 +- src/software/SfM/tutorial_demo.py.in | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/openMVG/geometry/pose3.hpp b/src/openMVG/geometry/pose3.hpp index bc58733337..f4fae44280 100644 --- a/src/openMVG/geometry/pose3.hpp +++ b/src/openMVG/geometry/pose3.hpp @@ -13,7 +13,7 @@ namespace openMVG { namespace geometry { -// Define a 3D Pose as a 3D transform : [R|C] t = -RC +// Define a 3D Pose as a 3D transform: [R|C] t = -RC class Pose3 { protected: diff --git a/src/software/SfM/SfM_GlobalPipeline.py.in b/src/software/SfM/SfM_GlobalPipeline.py.in index d6469f208d..e41cc66482 100644 --- a/src/software/SfM/SfM_GlobalPipeline.py.in +++ b/src/software/SfM/SfM_GlobalPipeline.py.in @@ -45,7 +45,7 @@ if not os.path.exists(output_dir): if not os.path.exists(matches_dir): os.mkdir(matches_dir) -print ("1. Intrisics analysis") +print ("1. Intrinsics analysis") pIntrisics = subprocess.Popen( [os.path.join(OPENMVG_SFM_BIN, "openMVG_main_SfMInit_ImageListing"), "-i", input_dir, "-o", matches_dir, "-d", camera_file_params] ) pIntrisics.wait() diff --git a/src/software/SfM/SfM_SequentialPipeline.py.in b/src/software/SfM/SfM_SequentialPipeline.py.in index 7b8cafe52b..8f34ef9685 100644 --- a/src/software/SfM/SfM_SequentialPipeline.py.in +++ b/src/software/SfM/SfM_SequentialPipeline.py.in @@ -45,7 +45,7 @@ if not os.path.exists(output_dir): if not os.path.exists(matches_dir): os.mkdir(matches_dir) -print ("1. Intrisics analysis") +print ("1. Intrinsics analysis") pIntrisics = subprocess.Popen( [os.path.join(OPENMVG_SFM_BIN, "openMVG_main_SfMInit_ImageListing"), "-i", input_dir, "-o", matches_dir, "-d", camera_file_params] ) pIntrisics.wait() diff --git a/src/software/SfM/tutorial_demo.py.in b/src/software/SfM/tutorial_demo.py.in index b1fc6e28e6..3f4326f569 100644 --- a/src/software/SfM/tutorial_demo.py.in +++ b/src/software/SfM/tutorial_demo.py.in @@ -44,7 +44,7 @@ camera_file_params = os.path.join(CAMERA_SENSOR_WIDTH_DIRECTORY, "cameraGenerate if not os.path.exists(matches_dir): os.mkdir(matches_dir) -print ("1. Intrisics analysis") +print ("1. Intrinsics analysis") pIntrisics = subprocess.Popen( [os.path.join(OPENMVG_SFM_BIN, "openMVG_main_SfMInit_ImageListing"), "-i", input_dir, "-o", matches_dir, "-d", camera_file_params, "-c", "3"] ) pIntrisics.wait() From 9d3f41affaf33f20f233eebbe3461ebed6a7a937 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Mon, 18 May 2015 09:35:18 +0200 Subject: [PATCH 02/52] fix removed track count display. --- .../sfm/pipelines/global/sfm_global_engine_relative_motions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp b/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp index 0410908496..aaac1022b3 100644 --- a/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp +++ b/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp @@ -338,7 +338,7 @@ bool GlobalSfMReconstructionEngine_RelativeMotions::Compute_Initial_Structure() structure_estimator.triangulate(_sfm_data); std::cout << "\n#removed tracks (invalid triangulation): " << - IndexT(_sfm_data.getLandmarks().size()) - trackCountBefore << std::endl; + trackCountBefore - IndexT(_sfm_data.getLandmarks().size()) << std::endl; std::cout << std::endl << " Triangulation took (s): " << timer.elapsed() << std::endl; // Export initial structure From cbbb7b81543b713acb2ff22644e61f6fc7ddb61f Mon Sep 17 00:00:00 2001 From: pmoulon Date: Mon, 18 May 2015 09:36:18 +0200 Subject: [PATCH 03/52] Typo fix --- src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp | 4 ++-- src/openMVG/sfm/sfm_data_io_baf.hpp | 2 +- src/openMVG/sfm/sfm_data_triangulation.hpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp b/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp index cdde259855..6d9b56adc5 100644 --- a/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp +++ b/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp @@ -477,7 +477,7 @@ bool SequentialSfMReconstructionEngine::MakeInitialPair3D(const Pair & current_p _sfm_data.structure[trackId] = landmarks[trackId]; } else { - // Remove this observation fro the scene tracking data + // Remove this observation from the scene tracking data _map_tracks[trackId].erase(I); _map_tracks[trackId].erase(J); if (_map_tracks[trackId].size() < 2) { @@ -541,7 +541,7 @@ bool SequentialSfMReconstructionEngine::MakeInitialPair3D(const Pair & current_p htmlFileStream << _htmlDocStream->getDoc(); } } - return true; + return !_sfm_data.structure.empty(); } double SequentialSfMReconstructionEngine::ComputeResidualsHistogram(Histogram * histo) diff --git a/src/openMVG/sfm/sfm_data_io_baf.hpp b/src/openMVG/sfm/sfm_data_io_baf.hpp index da67e1ffc0..a003757c70 100644 --- a/src/openMVG/sfm/sfm_data_io_baf.hpp +++ b/src/openMVG/sfm/sfm_data_io_baf.hpp @@ -54,7 +54,7 @@ static bool Save_BAF( for (Poses::const_iterator iterPose = poses.begin(); iterPose != poses.end(); ++iterPose) { - // [Rotation row major 3x3; camera center 3x1] + // [Rotation col major 3x3; camera center 3x1] const double * rotation = iterPose->second.rotation().data(); std::copy(rotation, rotation+9, std::ostream_iterator(stream, " ")); const double * center = iterPose->second.center().data(); diff --git a/src/openMVG/sfm/sfm_data_triangulation.hpp b/src/openMVG/sfm/sfm_data_triangulation.hpp index d288fee68a..2e32cf8031 100644 --- a/src/openMVG/sfm/sfm_data_triangulation.hpp +++ b/src/openMVG/sfm/sfm_data_triangulation.hpp @@ -26,7 +26,7 @@ struct SfM_Data_Structure_Computation_Basis :_bConsoleVerbose(bConsoleVerbose) { } - + virtual void triangulate(SfM_Data & sfm_data) const = 0; }; From 9ab82dd057de46253e35233e5e2926a3dfd4961d Mon Sep 17 00:00:00 2001 From: pmoulon Date: Mon, 18 May 2015 10:33:57 +0200 Subject: [PATCH 04/52] Do not longer use auto_ptr that is deprecated. --- src/openMVG/graph/graph_builder.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openMVG/graph/graph_builder.hpp b/src/openMVG/graph/graph_builder.hpp index 2dd343a79f..79ac6d32a3 100644 --- a/src/openMVG/graph/graph_builder.hpp +++ b/src/openMVG/graph/graph_builder.hpp @@ -24,12 +24,12 @@ struct indexedGraph GraphT g; map_Size_t_Node map_size_t_to_node; // Original image index to graph node - std::auto_ptr map_nodeMapIndex; // Association of data to graph Node + std::unique_ptr map_nodeMapIndex; // Association of data to graph Node template indexedGraph(const IterablePairs & pairs) { - map_nodeMapIndex = std::auto_ptr( new map_NodeMapIndex(g) ); + map_nodeMapIndex.reset( new map_NodeMapIndex(g) ); //A-- Compute the number of node we need std::set setNodes; From 1090b2be52445e8746b0d4b3c39c948f41a58846 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Mon, 18 May 2015 10:35:54 +0200 Subject: [PATCH 05/52] Add isPinhole and IsPoseAndIntrinsicDefined(const View*) functions in order to simplify view and camera manipulations. --- .../main_computeMatchesCasHas.cpp | 10 ++-- src/openMVG/cameras/Camera_Common.hpp | 5 ++ src/openMVG/sfm/sfm_data.hpp | 15 +++++- src/openMVG/sfm/sfm_data_filters.hpp | 14 +----- src/openMVG/sfm/sfm_data_filters_frustum.cpp | 20 ++++---- src/openMVG/sfm/sfm_report.hpp | 8 +--- src/software/SfM/main_ComputeMatches.cpp | 12 ++--- src/software/SfM/main_openMVG2CMPMVS.cpp | 19 ++++---- src/software/SfM/main_openMVG2MESHLAB.cpp | 9 ++-- src/software/SfM/main_openMVG2PMVS.cpp | 47 +++++++------------ src/software/SfMViewer/main.cpp | 12 ++--- 11 files changed, 70 insertions(+), 101 deletions(-) diff --git a/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp b/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp index 4c4a97647f..c0e4c18b44 100644 --- a/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp +++ b/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp @@ -362,14 +362,10 @@ int main(int argc, char **argv) if (sfm_data.getIntrinsics().count(v->id_intrinsic)) { const IntrinsicBase * ptrIntrinsic = sfm_data.getIntrinsics().find(v->id_intrinsic)->second.get(); - switch (ptrIntrinsic->getType()) + if (isPinhole(ptrIntrinsic->getType())) { - case PINHOLE_CAMERA: - case PINHOLE_CAMERA_RADIAL1: - case PINHOLE_CAMERA_RADIAL3: - const Pinhole_Intrinsic * ptrPinhole = (const Pinhole_Intrinsic*)(ptrIntrinsic); - map_K[cpt] = ptrPinhole->K(); - break; + const Pinhole_Intrinsic * ptrPinhole = (const Pinhole_Intrinsic*)(ptrIntrinsic); + map_K[cpt] = ptrPinhole->K(); } } } diff --git a/src/openMVG/cameras/Camera_Common.hpp b/src/openMVG/cameras/Camera_Common.hpp index cc74407033..28fee77df2 100644 --- a/src/openMVG/cameras/Camera_Common.hpp +++ b/src/openMVG/cameras/Camera_Common.hpp @@ -23,4 +23,9 @@ static bool isValid(EINTRINSIC eintrinsic) return eintrinsic > PINHOLE_CAMERA_START && eintrinsic < PINHOLE_CAMERA_END; } +static bool isPinhole(EINTRINSIC eintrinsic) +{ + return eintrinsic > PINHOLE_CAMERA_START && eintrinsic < PINHOLE_CAMERA_END; +} + #endif // OPENMVG_CAMERAS_COMMON_HPP diff --git a/src/openMVG/sfm/sfm_data.hpp b/src/openMVG/sfm/sfm_data.hpp index 3c59abb533..7a99850237 100644 --- a/src/openMVG/sfm/sfm_data.hpp +++ b/src/openMVG/sfm/sfm_data.hpp @@ -39,6 +39,8 @@ struct SfM_Data Poses poses; /// Considered camera intrinsics (indexed by view.id_cam) Intrinsics intrinsics; + /// Structure (3D points with their 2D observations) + Landmarks structure; /// Root Views path std::string s_root_path; @@ -51,8 +53,17 @@ struct SfM_Data const Intrinsics & getIntrinsics() const {return intrinsics;} const Landmarks & getLandmarks() const {return structure;} - /// Structure (3D points with their 2D observations) - Landmarks structure; + /// Check if the View have defined intrinsic and pose + bool IsPoseAndIntrinsicDefined(const View * view) const + { + if (view == NULL) return false; + return ( + view->id_intrinsic != UndefinedIndexT && + view->id_pose != UndefinedIndexT && + intrinsics.find(view->id_intrinsic) != intrinsics.end() && + poses.find(view->id_pose) != poses.end()); + } + }; } // namespace openMVG diff --git a/src/openMVG/sfm/sfm_data_filters.hpp b/src/openMVG/sfm/sfm_data_filters.hpp index 758c6bc544..a831b19098 100644 --- a/src/openMVG/sfm/sfm_data_filters.hpp +++ b/src/openMVG/sfm/sfm_data_filters.hpp @@ -23,19 +23,9 @@ static std::set Get_Valid_Views it != sfm_data.getViews().end(); ++it) { const View * v = it->second.get(); - const IndexT id_view = v->id_view; - const IndexT id_intrinsic = v->id_intrinsic; - const IndexT id_pose = v->id_pose; - - bool bDefined = - id_intrinsic != UndefinedIndexT && - sfm_data.getIntrinsics().find(id_intrinsic) != sfm_data.getIntrinsics().end() && - id_pose != UndefinedIndexT && - sfm_data.getPoses().find(id_pose) != sfm_data.getPoses().end(); - - if (bDefined) + if (sfm_data.IsPoseAndIntrinsicDefined(v)) { - valid_idx.insert(id_view); + valid_idx.insert(v->id_view); } } return valid_idx; diff --git a/src/openMVG/sfm/sfm_data_filters_frustum.cpp b/src/openMVG/sfm/sfm_data_filters_frustum.cpp index 828cf4ce19..b6eb94f1f6 100644 --- a/src/openMVG/sfm/sfm_data_filters_frustum.cpp +++ b/src/openMVG/sfm/sfm_data_filters_frustum.cpp @@ -35,12 +35,14 @@ void Frustum_Filter::initFrustum(const SfM_Data & sfm_data) it != z_near_z_far_perView.end(); ++it) { const View * view = sfm_data.getViews().at(it->first).get(); - Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); + if (!sfm_data.IsPoseAndIntrinsicDefined(view)) + continue; + Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); + if (!isPinhole(iterIntrinsic->second.get()->getType())) + continue; - if (iterPose == sfm_data.getPoses().end() || - iterIntrinsic == sfm_data.getIntrinsics().end()) - continue; + Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); const Pose3 & pose = iterPose->second; const Pinhole_Intrinsic * cam = dynamic_cast(iterIntrinsic->second.get()); @@ -199,11 +201,10 @@ void Frustum_Filter::init_z_near_z_far_depth(const SfM_Data & sfm_data, const IndexT id_view = iterO->first; const Observation & ob = iterO->second; const View * view = sfm_data.getViews().at(id_view).get(); - Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); - Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); - if (iterPose == sfm_data.getPoses().end() || iterIntrinsic == sfm_data.getIntrinsics().end()) + if (!sfm_data.IsPoseAndIntrinsicDefined(view)) continue; + Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); const Pose3 & pose = iterPose->second; const double z = pose.depth(X); NearFarPlanesT::iterator itZ = z_near_z_far_perView.find(id_view); @@ -227,10 +228,7 @@ void Frustum_Filter::init_z_near_z_far_depth(const SfM_Data & sfm_data, it != sfm_data.getViews().end(); ++it) { const View * view = it->second.get(); - Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); - Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); - - if (iterPose == sfm_data.getPoses().end() || iterIntrinsic == sfm_data.getIntrinsics().end()) + if (!sfm_data.IsPoseAndIntrinsicDefined(view)) continue; z_near_z_far_perView[view->id_view] = std::make_pair(zNear, zFar); } diff --git a/src/openMVG/sfm/sfm_report.hpp b/src/openMVG/sfm/sfm_report.hpp index 0451e05a76..fc5b6b48aa 100644 --- a/src/openMVG/sfm/sfm_report.hpp +++ b/src/openMVG/sfm/sfm_report.hpp @@ -94,14 +94,8 @@ static bool Generate_SfM_Report << sColBegin << id_view << sColEnd << sColBegin + stlplus::basename_part(v->s_Img_path) + sColEnd; - bool bDefined = - id_intrinsic != UndefinedIndexT && - sfm_data.getIntrinsics().find(id_intrinsic) != sfm_data.getIntrinsics().end() && - id_pose != UndefinedIndexT && - sfm_data.getPoses().find(id_pose) != sfm_data.getPoses().end(); - // IdView | basename | #Observations | residuals min | residual median | residual max - if (bDefined) + if (sfm_data.IsPoseAndIntrinsicDefined(v)) { const std::vector & residuals = residuals_per_view.at(id_view); if (!residuals.empty()) diff --git a/src/software/SfM/main_ComputeMatches.cpp b/src/software/SfM/main_ComputeMatches.cpp index f8269a9dda..821b6896eb 100644 --- a/src/software/SfM/main_ComputeMatches.cpp +++ b/src/software/SfM/main_ComputeMatches.cpp @@ -341,15 +341,11 @@ int main(int argc, char **argv) if (sfm_data.getIntrinsics().count(v->id_intrinsic)) { const IntrinsicBase * ptrIntrinsic = sfm_data.getIntrinsics().find(v->id_intrinsic)->second.get(); - switch (ptrIntrinsic->getType()) + if (isPinhole(ptrIntrinsic->getType())) { - case PINHOLE_CAMERA: - case PINHOLE_CAMERA_RADIAL1: - case PINHOLE_CAMERA_RADIAL3: - const Pinhole_Intrinsic * ptrPinhole = (const Pinhole_Intrinsic*)(ptrIntrinsic); - map_K[cpt] = ptrPinhole->K(); - break; - } + const Pinhole_Intrinsic * ptrPinhole = (const Pinhole_Intrinsic*)(ptrIntrinsic); + map_K[cpt] = ptrPinhole->K(); + } } } diff --git a/src/software/SfM/main_openMVG2CMPMVS.cpp b/src/software/SfM/main_openMVG2CMPMVS.cpp index 048ffdc519..e23a49e359 100644 --- a/src/software/SfM/main_openMVG2CMPMVS.cpp +++ b/src/software/SfM/main_openMVG2CMPMVS.cpp @@ -49,14 +49,12 @@ bool exportToCMPMVSFormat( iter != sfm_data.getViews().end(); ++iter, ++my_progress_bar) { const View * view = iter->second.get(); - Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); - Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); - - if (iterPose == sfm_data.getPoses().end() || - iterIntrinsic == sfm_data.getIntrinsics().end()) - continue; + if (!sfm_data.IsPoseAndIntrinsicDefined(view)) + continue; // We have a valid view with a corresponding camera & pose + Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); + Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); const Mat34 P = iterIntrinsic->second.get()->get_projective_equivalent(iterPose->second); std::ostringstream os; os << std::setw(5) << std::setfill('0') << count << "_P"; @@ -77,12 +75,11 @@ bool exportToCMPMVSFormat( iter != sfm_data.getViews().end(); ++iter, ++my_progress_bar) { const View * view = iter->second.get(); - Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); - Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); + if (!sfm_data.IsPoseAndIntrinsicDefined(view)) + continue; - if (iterPose == sfm_data.getPoses().end() || - iterIntrinsic == sfm_data.getIntrinsics().end()) - continue; + Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); + Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); // We have a valid view with a corresponding camera & pose const std::string srcImage = stlplus::create_filespec(sfm_data.s_root_path, view->s_Img_path); diff --git a/src/software/SfM/main_openMVG2MESHLAB.cpp b/src/software/SfM/main_openMVG2MESHLAB.cpp index e88dce016c..fc125c2ff3 100644 --- a/src/software/SfM/main_openMVG2MESHLAB.cpp +++ b/src/software/SfM/main_openMVG2MESHLAB.cpp @@ -83,12 +83,11 @@ int main(int argc, char **argv) iter != sfm_data.getViews().end(); ++iter) { const View * view = iter->second.get(); - Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); - Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); + if (!sfm_data.IsPoseAndIntrinsicDefined(view)) + continue; - if (iterPose == sfm_data.getPoses().end() || - iterIntrinsic == sfm_data.getIntrinsics().end()) - continue; + Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); + Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); // We have a valid view with a corresponding camera & pose const std::string srcImage = stlplus::create_filespec(sfm_data.s_root_path, view->s_Img_path); diff --git a/src/software/SfM/main_openMVG2PMVS.cpp b/src/software/SfM/main_openMVG2PMVS.cpp index d444fcd7d6..70cf1e3987 100644 --- a/src/software/SfM/main_openMVG2PMVS.cpp +++ b/src/software/SfM/main_openMVG2PMVS.cpp @@ -61,12 +61,11 @@ bool exportToPMVSFormat( iter != sfm_data.getViews().end(); ++iter, ++my_progress_bar) { const View * view = iter->second.get(); - Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); - Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); + if (!sfm_data.IsPoseAndIntrinsicDefined(view)) + continue; - if (iterPose == sfm_data.getPoses().end() || - iterIntrinsic == sfm_data.getIntrinsics().end()) - continue; + Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); + Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); // We have a valid view with a corresponding camera & pose const Mat34 P = iterIntrinsic->second.get()->get_projective_equivalent(iterPose->second); @@ -89,12 +88,11 @@ bool exportToPMVSFormat( iter != sfm_data.getViews().end(); ++iter, ++my_progress_bar) { const View * view = iter->second.get(); - Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); - Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); + if (!sfm_data.IsPoseAndIntrinsicDefined(view)) + continue; - if (iterPose == sfm_data.getPoses().end() || - iterIntrinsic == sfm_data.getIntrinsics().end()) - continue; + Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); + Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); map_viewIdToContiguous[view->id_view] = count; // We have a valid view with a corresponding camera & pose @@ -218,12 +216,8 @@ bool exportToBundlerFormat( iter != sfm_data.getViews().end(); ++iter) { const View * view = iter->second.get(); - Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); - Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); - - if (iterPose == sfm_data.getPoses().end() || - iterIntrinsic == sfm_data.getIntrinsics().end()) - continue; + if (!sfm_data.IsPoseAndIntrinsicDefined(view)) + continue; ++validCameraCount; } @@ -237,25 +231,20 @@ bool exportToBundlerFormat( iter != sfm_data.getViews().end(); ++iter) { const View * view = iter->second.get(); - Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); - Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); + if (!sfm_data.IsPoseAndIntrinsicDefined(view)) + continue; - if (iterPose == sfm_data.getPoses().end() || - iterIntrinsic == sfm_data.getIntrinsics().end()) - continue; + Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); + Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); // Must export focal, k1, k2, R, t Mat3 D; D.fill(0.0); D .diagonal() = Vec3(1., -1., -1.); // mapping between our pinhole and Bundler convention - double k1 = 0.0, k2 = 0.0; // distortion already removed + const double k1 = 0.0, k2 = 0.0; // distortion already removed - switch(iterIntrinsic->second.get()->getType()) - { - case PINHOLE_CAMERA: - case PINHOLE_CAMERA_RADIAL1: - case PINHOLE_CAMERA_RADIAL3: + if(isPinhole(iterIntrinsic->second.get()->getType())) { const Pinhole_Intrinsic * cam = dynamic_cast(iterIntrinsic->second.get()); const double focal = cam->focal(); @@ -271,8 +260,8 @@ bool exportToBundlerFormat( osList << stlplus::basename_part(view->s_Img_path) + "." + stlplus::extension_part(view->s_Img_path) << " 0 " << focal << os.widen('\n'); } - break; - default: + else + { std::cerr << "Unsupported camera model for Bundler export." << std::endl; return false; } diff --git a/src/software/SfMViewer/main.cpp b/src/software/SfMViewer/main.cpp index cc3c404771..8412f1e9f4 100644 --- a/src/software/SfMViewer/main.cpp +++ b/src/software/SfMViewer/main.cpp @@ -233,9 +233,7 @@ static void draw(void) const View * view = sfm_data.getViews().at(vec_cameras[i_cam]).get(); const Pose3 pose = sfm_data.getPoses().at(view->id_pose); const IntrinsicBase * cam = sfm_data.getIntrinsics().at(view->id_intrinsic).get(); - if (cam->getType() == PINHOLE_CAMERA || - cam->getType() == PINHOLE_CAMERA_RADIAL1 || - cam->getType() == PINHOLE_CAMERA_RADIAL3 ) + if (isPinhole(cam->getType())) { const Pinhole_Intrinsic * camPinhole = dynamic_cast(cam); @@ -361,12 +359,8 @@ int main(int argc, char *argv[]) { iter != sfm_data.getViews().end(); ++iter) { const View * view = iter->second.get(); - Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); - Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); - - if (iterPose == sfm_data.getPoses().end() || - iterIntrinsic == sfm_data.getIntrinsics().end()) - continue; + if (!sfm_data.IsPoseAndIntrinsicDefined(view)) + continue; vec_cameras.push_back(iter->first); } From a7c7b8ee15d817769028f8cd02f8225af2c0ce83 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Mon, 18 May 2015 14:26:01 +0200 Subject: [PATCH 06/52] translations averaging solver should use SPARSE_NORMAL_CHOLESKY. #295 --- src/openMVG/multiview/translation_averaging_solver.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/openMVG/multiview/translation_averaging_solver.cpp b/src/openMVG/multiview/translation_averaging_solver.cpp index c9b5e5d238..459b1fb101 100644 --- a/src/openMVG/multiview/translation_averaging_solver.cpp +++ b/src/openMVG/multiview/translation_averaging_solver.cpp @@ -129,8 +129,7 @@ bool solve_translations_problem( options.max_num_iterations = max_iterations; options.function_tolerance = function_tolerance; options.parameter_tolerance = parameter_tolerance; - options.linear_solver_type = ceres::ITERATIVE_SCHUR; - options.preconditioner_type = ceres::SCHUR_JACOBI; + options.linear_solver_type = ceres::SPARSE_NORMAL_CHOLESKY; Solver::Summary summary; Solve(options, &problem, &summary); From 6d749925216ee0a6aceadff0081735d9a9fdf96f Mon Sep 17 00:00:00 2001 From: pmoulon Date: Mon, 18 May 2015 15:27:06 +0200 Subject: [PATCH 07/52] [SfM] Obtain view pose thanks a function. #296 --- .../main_computeMatchesCasHas.cpp | 24 +- .../GlobalSfM_translation_averaging.cpp | 12 +- .../sfm/pipelines/global/global_SfM_test.cpp | 12 +- .../sfm_global_engine_relative_motions.cpp | 34 +- src/openMVG/sfm/pipelines/pipelines_test.hpp | 10 +- .../pipelines/sequential/sequential_SfM.cpp | 104 +- .../sequential/sequential_SfM_test.cpp | 8 +- .../sfm/pipelines/sfm_features_provider.hpp | 12 +- .../sfm/pipelines/sfm_matches_provider.hpp | 2 +- .../sfm/pipelines/sfm_regions_provider.hpp | 12 +- .../structure_estimator.hpp | 24 +- src/openMVG/sfm/sfm_data.hpp | 15 +- src/openMVG/sfm/sfm_data_BA_test.cpp | 10 +- src/openMVG/sfm/sfm_data_filters.hpp | 13 +- src/openMVG/sfm/sfm_data_filters_frustum.cpp | 22 +- src/openMVG/sfm/sfm_data_io.cpp | 8 +- src/openMVG/sfm/sfm_data_io_baf.hpp | 14 +- src/openMVG/sfm/sfm_data_io_ply.hpp | 8 +- src/openMVG/sfm/sfm_data_triangulation.hpp | 16 +- src/openMVG/sfm/sfm_report.hpp | 24 +- src/openMVG/version.hpp | 2 +- src/software/SfM/main_ComputeFeatures.cpp | 2 +- .../SfM/main_ComputeFeatures_OpenCV.cpp | 2 +- src/software/SfM/main_ComputeMatches.cpp | 22 +- .../SfM/main_ComputeSfM_DataColor.cpp | 20 +- .../main_ComputeStructureFromKnownPoses.cpp | 2 +- src/software/SfM/main_FrustumFiltering.cpp | 4 +- src/software/SfM/main_IncrementalSfM.cpp | 4 +- src/software/SfM/main_evalQuality.cpp | 4 +- src/software/SfM/main_exportMatches.cpp | 4 +- src/software/SfM/main_exportTracks.cpp | 6 +- src/software/SfM/main_openMVG2CMPMVS.cpp | 20 +- src/software/SfM/main_openMVG2MESHLAB.cpp | 10 +- src/software/SfM/main_openMVG2PMVS.cpp | 45 +- src/software/SfMViewer/main.cpp | 22 +- .../colorHarmonizeEngineGlobal.cpp | 1180 ++++++++--------- 36 files changed, 869 insertions(+), 864 deletions(-) diff --git a/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp b/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp index c0e4c18b44..c9526a7a72 100644 --- a/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp +++ b/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp @@ -216,7 +216,7 @@ int main(int argc, char **argv) std::cout << "\n\n - EXTRACT FEATURES - " << std::endl; Image imageGray; - C_Progress_display my_progress_bar( sfm_data.getViews().size() ); + C_Progress_display my_progress_bar( sfm_data.GetViews().size() ); for(Views::const_iterator iterViews = sfm_data.views.begin(); iterViews != sfm_data.views.end(); ++iterViews, ++my_progress_bar) @@ -253,11 +253,11 @@ int main(int argc, char **argv) // List views as a vector of filenames & imagesizes (alias) std::vector vec_fileNames; - vec_fileNames.reserve(sfm_data.getViews().size()); + vec_fileNames.reserve(sfm_data.GetViews().size()); std::vector > vec_imagesSize; - vec_imagesSize.reserve(sfm_data.getViews().size()); - for (Views::const_iterator iter = sfm_data.getViews().begin(); - iter != sfm_data.getViews().end(); + vec_imagesSize.reserve(sfm_data.GetViews().size()); + for (Views::const_iterator iter = sfm_data.GetViews().begin(); + iter != sfm_data.GetViews().end(); ++iter) { const View * v = iter->second.get(); @@ -292,10 +292,10 @@ int main(int argc, char **argv) Pair_Set pairs; switch (ePairmode) { - case PAIR_EXHAUSTIVE: pairs = exhaustivePairs(sfm_data.getViews().size()); break; - case PAIR_CONTIGUOUS: pairs = contiguousWithOverlap(sfm_data.getViews().size(), iMatchingVideoMode); break; + case PAIR_EXHAUSTIVE: pairs = exhaustivePairs(sfm_data.GetViews().size()); break; + case PAIR_CONTIGUOUS: pairs = contiguousWithOverlap(sfm_data.GetViews().size(), iMatchingVideoMode); break; case PAIR_FROM_FILE: - if(!loadPairs(sfm_data.getViews().size(), sPredefinedPairList, pairs)) + if(!loadPairs(sfm_data.GetViews().size(), sPredefinedPairList, pairs)) { return EXIT_FAILURE; }; @@ -354,14 +354,14 @@ int main(int argc, char **argv) // Build the intrinsic parameter map for each view std::map map_K; size_t cpt = 0; - for (Views::const_iterator iter = sfm_data.getViews().begin(); - iter != sfm_data.getViews().end(); + for (Views::const_iterator iter = sfm_data.GetViews().begin(); + iter != sfm_data.GetViews().end(); ++iter, ++cpt) { const View * v = iter->second.get(); - if (sfm_data.getIntrinsics().count(v->id_intrinsic)) + if (sfm_data.GetIntrinsics().count(v->id_intrinsic)) { - const IntrinsicBase * ptrIntrinsic = sfm_data.getIntrinsics().find(v->id_intrinsic)->second.get(); + const IntrinsicBase * ptrIntrinsic = sfm_data.GetIntrinsics().find(v->id_intrinsic)->second.get(); if (isPinhole(ptrIntrinsic->getType())) { const Pinhole_Intrinsic * ptrPinhole = (const Pinhole_Intrinsic*)(ptrIntrinsic); diff --git a/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp b/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp index ac2e6440e7..7106c52b19 100644 --- a/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp +++ b/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp @@ -466,14 +466,14 @@ void GlobalSfM_Translation_AveragingSolver::ComputePutativeTranslation_EdgesCove vec_global_KR_Triplet[1] = (map_globalR.at(J)); vec_global_KR_Triplet[2] = (map_globalR.at(K)); - const View * view_I = sfm_data.getViews().at(I).get(); - const View * view_J = sfm_data.getViews().at(J).get(); - const View * view_K = sfm_data.getViews().at(K).get(); + const View * view_I = sfm_data.GetViews().at(I).get(); + const View * view_J = sfm_data.GetViews().at(J).get(); + const View * view_K = sfm_data.GetViews().at(K).get(); // update pixel precision (from image to camera coordinate system, since features are normalized) - const Pinhole_Intrinsic* cam_I = dynamic_cast(sfm_data.getIntrinsics().at(view_I->id_intrinsic).get()); - const Pinhole_Intrinsic* cam_J = dynamic_cast(sfm_data.getIntrinsics().at(view_J->id_intrinsic).get()); - const Pinhole_Intrinsic* cam_K = dynamic_cast(sfm_data.getIntrinsics().at(view_K->id_intrinsic).get()); + const Pinhole_Intrinsic* cam_I = dynamic_cast(sfm_data.GetIntrinsics().at(view_I->id_intrinsic).get()); + const Pinhole_Intrinsic* cam_J = dynamic_cast(sfm_data.GetIntrinsics().at(view_J->id_intrinsic).get()); + const Pinhole_Intrinsic* cam_K = dynamic_cast(sfm_data.GetIntrinsics().at(view_K->id_intrinsic).get()); if (cam_I == NULL || cam_J == NULL || cam_K == NULL) { continue; diff --git a/src/openMVG/sfm/pipelines/global/global_SfM_test.cpp b/src/openMVG/sfm/pipelines/global/global_SfM_test.cpp index aa18f51662..af703c6286 100644 --- a/src/openMVG/sfm/pipelines/global/global_SfM_test.cpp +++ b/src/openMVG/sfm/pipelines/global/global_SfM_test.cpp @@ -74,8 +74,8 @@ TEST(GLOBAL_SFM, RotationAveragingL2_TranslationAveragingL1) { const double dResidual = RMSE(sfmEngine.Get_SfM_Data()); std::cout << "RMSE residual: " << dResidual << std::endl; EXPECT_TRUE( dResidual < 0.5); - EXPECT_TRUE( sfmEngine.Get_SfM_Data().getPoses().size() == nviews); - EXPECT_TRUE( sfmEngine.Get_SfM_Data().getLandmarks().size() == npoints); + EXPECT_TRUE( sfmEngine.Get_SfM_Data().GetPoses().size() == nviews); + EXPECT_TRUE( sfmEngine.Get_SfM_Data().GetLandmarks().size() == npoints); } TEST(GLOBAL_SFM, RotationAveragingL1_TranslationAveragingL1) { @@ -125,8 +125,8 @@ TEST(GLOBAL_SFM, RotationAveragingL1_TranslationAveragingL1) { const double dResidual = RMSE(sfmEngine.Get_SfM_Data()); std::cout << "RMSE residual: " << dResidual << std::endl; EXPECT_TRUE( dResidual < 0.5); - EXPECT_TRUE( sfmEngine.Get_SfM_Data().getPoses().size() == nviews); - EXPECT_TRUE( sfmEngine.Get_SfM_Data().getLandmarks().size() == npoints); + EXPECT_TRUE( sfmEngine.Get_SfM_Data().GetPoses().size() == nviews); + EXPECT_TRUE( sfmEngine.Get_SfM_Data().GetLandmarks().size() == npoints); } TEST(GLOBAL_SFM, RotationAveragingL2_TranslationAveragingL2) { @@ -176,8 +176,8 @@ TEST(GLOBAL_SFM, RotationAveragingL2_TranslationAveragingL2) { const double dResidual = RMSE(sfmEngine.Get_SfM_Data()); std::cout << "RMSE residual: " << dResidual << std::endl; EXPECT_TRUE( dResidual < 0.5); - EXPECT_TRUE( sfmEngine.Get_SfM_Data().getPoses().size() == nviews); - EXPECT_TRUE( sfmEngine.Get_SfM_Data().getLandmarks().size() == npoints); + EXPECT_TRUE( sfmEngine.Get_SfM_Data().GetPoses().size() == nviews); + EXPECT_TRUE( sfmEngine.Get_SfM_Data().GetLandmarks().size() == npoints); } diff --git a/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp b/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp index aaac1022b3..6adbcb8b36 100644 --- a/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp +++ b/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp @@ -38,7 +38,7 @@ GlobalSfMReconstructionEngine_RelativeMotions::GlobalSfMReconstructionEngine_Rel _htmlDocStream->pushInfo( "Dataset info:"); _htmlDocStream->pushInfo( "Views count: " + - htmlDocument::toString( sfm_data.getViews().size()) + "
"); + htmlDocument::toString( sfm_data.GetViews().size()) + "
"); } // Set default motion Averaging methods @@ -66,8 +66,8 @@ void GlobalSfMReconstructionEngine_RelativeMotions::SetFeaturesProvider(Features iter != _normalized_features_provider->feats_per_view.end(); ++iter) { // get the related view & camera intrinsic and compute the corresponding bearing vectors - const View * view = _sfm_data.getViews().at(iter->first).get(); - const std::shared_ptr cam = _sfm_data.getIntrinsics().find(view->id_intrinsic)->second; + const View * view = _sfm_data.GetViews().at(iter->first).get(); + const std::shared_ptr cam = _sfm_data.GetIntrinsics().find(view->id_intrinsic)->second; for (PointFeatures::iterator iterPt = iter->second.begin(); iterPt != iter->second.end(); ++iterPt) { @@ -149,10 +149,10 @@ bool GlobalSfMReconstructionEngine_RelativeMotions::Process() { os.str(""); os << "-------------------------------" << "
" - << "-- View count: " << _sfm_data.getViews().size() << "
" - << "-- Intrinsic count: " << _sfm_data.getIntrinsics().size() << "
" - << "-- Pose count: " << _sfm_data.getPoses().size() << "
" - << "-- Track count: " << _sfm_data.getLandmarks().size() << "
" + << "-- View count: " << _sfm_data.GetViews().size() << "
" + << "-- Intrinsic count: " << _sfm_data.GetIntrinsics().size() << "
" + << "-- Pose count: " << _sfm_data.GetPoses().size() << "
" + << "-- Track count: " << _sfm_data.GetLandmarks().size() << "
" << "-------------------------------" << "
"; _htmlDocStream->pushInfo(os.str()); } @@ -333,12 +333,12 @@ bool GlobalSfMReconstructionEngine_RelativeMotions::Compute_Initial_Structure() openMVG::Timer timer; - const IndexT trackCountBefore = _sfm_data.getLandmarks().size(); + const IndexT trackCountBefore = _sfm_data.GetLandmarks().size(); SfM_Data_Structure_Computation_Blind structure_estimator(true); structure_estimator.triangulate(_sfm_data); std::cout << "\n#removed tracks (invalid triangulation): " << - trackCountBefore - IndexT(_sfm_data.getLandmarks().size()) << std::endl; + trackCountBefore - IndexT(_sfm_data.GetLandmarks().size()) << std::endl; std::cout << std::endl << " Triangulation took (s): " << timer.elapsed() << std::endl; // Export initial structure @@ -453,8 +453,8 @@ void GlobalSfMReconstructionEngine_RelativeMotions::Compute_Relative_Rotations(R const View * view_J = _sfm_data.views[J].get(); // Check that valid camera are existing for the pair index - if (_sfm_data.getIntrinsics().find(view_I->id_intrinsic) == _sfm_data.getIntrinsics().end() || - _sfm_data.getIntrinsics().find(view_J->id_intrinsic) == _sfm_data.getIntrinsics().end()) + if (_sfm_data.GetIntrinsics().find(view_I->id_intrinsic) == _sfm_data.GetIntrinsics().end() || + _sfm_data.GetIntrinsics().find(view_J->id_intrinsic) == _sfm_data.GetIntrinsics().end()) continue; const IndMatches & vec_matchesInd = _matches_provider->_pairWise_matches.find(current_pair)->second; @@ -466,8 +466,8 @@ void GlobalSfMReconstructionEngine_RelativeMotions::Compute_Relative_Rotations(R x2.col(k) = _normalized_features_provider->feats_per_view[J][vec_matchesInd[k]._j].coords().cast(); } - const IntrinsicBase * cam_I = _sfm_data.getIntrinsics().at(view_I->id_intrinsic).get(); - const IntrinsicBase * cam_J = _sfm_data.getIntrinsics().at(view_J->id_intrinsic).get(); + const IntrinsicBase * cam_I = _sfm_data.GetIntrinsics().at(view_I->id_intrinsic).get(); + const IntrinsicBase * cam_J = _sfm_data.GetIntrinsics().at(view_J->id_intrinsic).get(); if ( !isValid(cam_I->getType()) || !isValid(cam_J->getType())) { continue; @@ -496,10 +496,10 @@ void GlobalSfMReconstructionEngine_RelativeMotions::Compute_Relative_Rotations(R { // Refine the defined scene SfM_Data tiny_scene; - tiny_scene.views.insert(*_sfm_data.getViews().find(view_I->id_view)); - tiny_scene.views.insert(*_sfm_data.getViews().find(view_J->id_view)); - tiny_scene.intrinsics.insert(*_sfm_data.getIntrinsics().find(view_I->id_intrinsic)); - tiny_scene.intrinsics.insert(*_sfm_data.getIntrinsics().find(view_J->id_intrinsic)); + tiny_scene.views.insert(*_sfm_data.GetViews().find(view_I->id_view)); + tiny_scene.views.insert(*_sfm_data.GetViews().find(view_J->id_view)); + tiny_scene.intrinsics.insert(*_sfm_data.GetIntrinsics().find(view_I->id_intrinsic)); + tiny_scene.intrinsics.insert(*_sfm_data.GetIntrinsics().find(view_J->id_intrinsic)); // Init poses const Pose3 & Pose_I = tiny_scene.poses[view_I->id_pose] = Pose3(Mat3::Identity(), Vec3::Zero()); diff --git a/src/openMVG/sfm/pipelines/pipelines_test.hpp b/src/openMVG/sfm/pipelines/pipelines_test.hpp index aa476c382e..90486c3d2f 100644 --- a/src/openMVG/sfm/pipelines/pipelines_test.hpp +++ b/src/openMVG/sfm/pipelines/pipelines_test.hpp @@ -64,17 +64,17 @@ static double RMSE(const SfM_Data & sfm_data) { // Compute residuals for each observation std::vector vec; - for(Landmarks::const_iterator iterTracks = sfm_data.getLandmarks().begin(); - iterTracks != sfm_data.getLandmarks().end(); + for(Landmarks::const_iterator iterTracks = sfm_data.GetLandmarks().begin(); + iterTracks != sfm_data.GetLandmarks().end(); ++iterTracks) { const Observations & obs = iterTracks->second.obs; for(Observations::const_iterator itObs = obs.begin(); itObs != obs.end(); ++itObs) { - const View * view = sfm_data.getViews().find(itObs->first)->second.get(); - const Pose3 & pose = sfm_data.getPoses().find(view->id_pose)->second; - const std::shared_ptr intrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic)->second; + const View * view = sfm_data.GetViews().find(itObs->first)->second.get(); + const Pose3 pose = sfm_data.GetPoseOrDie(view); + const std::shared_ptr intrinsic = sfm_data.GetIntrinsics().find(view->id_intrinsic)->second; const Vec2 residual = intrinsic->residual(pose, iterTracks->second.X, itObs->second.x); //std::cout << residual << " "; vec.push_back( residual(0) ); diff --git a/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp b/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp index 6d9b56adc5..2e86041a8a 100644 --- a/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp +++ b/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp @@ -48,11 +48,11 @@ SequentialSfMReconstructionEngine::SequentialSfMReconstructionEngine( _htmlDocStream->pushInfo( "Dataset info:"); _htmlDocStream->pushInfo( "Views count: " + - htmlDocument::toString( sfm_data.getViews().size()) + "
"); + htmlDocument::toString( sfm_data.GetViews().size()) + "
"); } // Init remaining image list - for (Views::const_iterator itV = sfm_data.getViews().begin(); - itV != sfm_data.getViews().end(); ++itV) + for (Views::const_iterator itV = sfm_data.GetViews().begin(); + itV != sfm_data.GetViews().end(); ++itV) { _set_remainingViewId.insert(itV->second.get()->id_view); } @@ -123,9 +123,9 @@ bool SequentialSfMReconstructionEngine::Process() { //-- Display some statistics std::cout << "\n\n-------------------------------" << "\n" << "-- Structure from Motion (statistics):\n" - << "-- #Camera calibrated: " << _sfm_data.getPoses().size() - << " from " << _sfm_data.getViews().size() << " input images.\n" - << "-- #Tracks, #3D points: " << _sfm_data.getLandmarks().size() << "\n" + << "-- #Camera calibrated: " << _sfm_data.GetPoses().size() + << " from " << _sfm_data.GetViews().size() << " input images.\n" + << "-- #Tracks, #3D points: " << _sfm_data.GetLandmarks().size() << "\n" << "-------------------------------" << "\n"; Histogram h; @@ -143,9 +143,9 @@ bool SequentialSfMReconstructionEngine::Process() { os.str(""); os << "-------------------------------" << "
" << "-- Structure from Motion (statistics):
" - << "-- #Camera calibrated: " << _sfm_data.getPoses().size() - << " from " <<_sfm_data.getViews().size() << " input images.
" - << "-- #Tracks, #3D points: " << _sfm_data.getLandmarks().size() << "
" + << "-- #Camera calibrated: " << _sfm_data.GetPoses().size() + << " from " <<_sfm_data.GetViews().size() << " input images.
" + << "-- #Tracks, #3D points: " << _sfm_data.GetLandmarks().size() << "
" << "-------------------------------" << "
"; _htmlDocStream->pushInfo(os.str()); @@ -184,13 +184,13 @@ bool SequentialSfMReconstructionEngine::ChooseInitialPair(Pair & initialPairInde << "---------------------------------------------------\n" << std::endl; - // List valid View that support valid intrinsic + // List Views that support valid intrinsic std::set valid_views; - for (Views::const_iterator it = _sfm_data.getViews().begin(); - it != _sfm_data.getViews().end(); ++it) + for (Views::const_iterator it = _sfm_data.GetViews().begin(); + it != _sfm_data.GetViews().end(); ++it) { const View * v = it->second.get(); - if( _sfm_data.getIntrinsics().find(v->id_intrinsic) != _sfm_data.getIntrinsics().end()) + if( _sfm_data.GetIntrinsics().find(v->id_intrinsic) != _sfm_data.GetIntrinsics().end()) valid_views.insert(v->id_view); } @@ -326,13 +326,13 @@ bool SequentialSfMReconstructionEngine::MakeInitialPair3D(const Pair & current_p const size_t J = max(current_pair.first, current_pair.second); // a. Assert we have valid pinhole cameras - const View * view_I = _sfm_data.getViews().at(I).get(); - const Intrinsics::const_iterator iterIntrinsic_I = _sfm_data.getIntrinsics().find(view_I->id_intrinsic); - const View * view_J = _sfm_data.getViews().at(J).get(); - const Intrinsics::const_iterator iterIntrinsic_J = _sfm_data.getIntrinsics().find(view_J->id_intrinsic); + const View * view_I = _sfm_data.GetViews().at(I).get(); + const Intrinsics::const_iterator iterIntrinsic_I = _sfm_data.GetIntrinsics().find(view_I->id_intrinsic); + const View * view_J = _sfm_data.GetViews().at(J).get(); + const Intrinsics::const_iterator iterIntrinsic_J = _sfm_data.GetIntrinsics().find(view_J->id_intrinsic); - if (iterIntrinsic_I == _sfm_data.getIntrinsics().end() || - iterIntrinsic_J == _sfm_data.getIntrinsics().end() ) + if (iterIntrinsic_I == _sfm_data.GetIntrinsics().end() || + iterIntrinsic_J == _sfm_data.GetIntrinsics().end() ) { return false; } @@ -393,10 +393,10 @@ bool SequentialSfMReconstructionEngine::MakeInitialPair3D(const Pair & current_p { // Refine the defined scene SfM_Data tiny_scene; - tiny_scene.views.insert(*_sfm_data.getViews().find(view_I->id_view)); - tiny_scene.views.insert(*_sfm_data.getViews().find(view_J->id_view)); - tiny_scene.intrinsics.insert(*_sfm_data.getIntrinsics().find(view_I->id_intrinsic)); - tiny_scene.intrinsics.insert(*_sfm_data.getIntrinsics().find(view_J->id_intrinsic)); + tiny_scene.views.insert(*_sfm_data.GetViews().find(view_I->id_view)); + tiny_scene.views.insert(*_sfm_data.GetViews().find(view_J->id_view)); + tiny_scene.intrinsics.insert(*_sfm_data.GetIntrinsics().find(view_I->id_intrinsic)); + tiny_scene.intrinsics.insert(*_sfm_data.GetIntrinsics().find(view_J->id_intrinsic)); // Init poses const Pose3 & Pose_I = tiny_scene.poses[view_I->id_pose] = Pose3(Mat3::Identity(), Vec3::Zero()); @@ -448,8 +448,8 @@ bool SequentialSfMReconstructionEngine::MakeInitialPair3D(const Pair & current_p _set_remainingViewId.erase(view_J->id_view); // List inliers and save them - for (Landmarks::const_iterator iter = tiny_scene.getLandmarks().begin(); - iter != tiny_scene.getLandmarks().end(); ++iter) + for (Landmarks::const_iterator iter = tiny_scene.GetLandmarks().begin(); + iter != tiny_scene.GetLandmarks().end(); ++iter) { const IndexT trackId = iter->first; const Landmark & landmark = iter->second; @@ -549,16 +549,16 @@ double SequentialSfMReconstructionEngine::ComputeResidualsHistogram(Histogram vec_residuals; vec_residuals.reserve(_sfm_data.structure.size()); - for(Landmarks::const_iterator iterTracks = _sfm_data.getLandmarks().begin(); - iterTracks != _sfm_data.getLandmarks().end(); ++iterTracks) + for(Landmarks::const_iterator iterTracks = _sfm_data.GetLandmarks().begin(); + iterTracks != _sfm_data.GetLandmarks().end(); ++iterTracks) { const Observations & obs = iterTracks->second.obs; for(Observations::const_iterator itObs = obs.begin(); itObs != obs.end(); ++itObs) { - const View * view = _sfm_data.getViews().find(itObs->first)->second.get(); - const Pose3 & pose = _sfm_data.getPoses().find(view->id_pose)->second; - const std::shared_ptr intrinsic = _sfm_data.getIntrinsics().find(view->id_intrinsic)->second; + const View * view = _sfm_data.GetViews().find(itObs->first)->second.get(); + const Pose3 pose = _sfm_data.GetPoseOrDie(view); + const std::shared_ptr intrinsic = _sfm_data.GetIntrinsics().find(view->id_intrinsic)->second; const Vec2 residual = intrinsic->residual(pose, iterTracks->second.X, itObs->second.x); vec_residuals.push_back( fabs(residual(0)) ); vec_residuals.push_back( fabs(residual(1)) ); @@ -578,7 +578,7 @@ double SequentialSfMReconstructionEngine::ComputeResidualsHistogram(Histogram reconstructed_trackId; - std::transform(_sfm_data.getLandmarks().begin(), _sfm_data.getLandmarks().end(), + std::transform(_sfm_data.GetLandmarks().begin(), _sfm_data.GetLandmarks().end(), std::inserter(reconstructed_trackId, reconstructed_trackId.begin()), RetrieveKey() ); @@ -724,7 +724,7 @@ bool SequentialSfMReconstructionEngine::Resection(size_t viewIndex) // b. intersects the track list with the reconstructed std::set reconstructed_trackId; - std::transform(_sfm_data.getLandmarks().begin(), _sfm_data.getLandmarks().end(), + std::transform(_sfm_data.GetLandmarks().begin(), _sfm_data.GetLandmarks().end(), std::inserter(reconstructed_trackId, reconstructed_trackId.begin()), RetrieveKey() ); @@ -750,14 +750,14 @@ bool SequentialSfMReconstructionEngine::Resection(size_t viewIndex) Mat pt2D( 2, set_trackIdForResection.size()); Mat pt3D( 3, set_trackIdForResection.size()); - const View * view_I = _sfm_data.getViews().at(viewIndex).get(); + const View * view_I = _sfm_data.GetViews().at(viewIndex).get(); // Look if intrinsic data is known or not bool bKnownIntrinsic = true; Mat3 K = Mat3::Identity(); - const Intrinsics::const_iterator iterIntrinsic_I = _sfm_data.getIntrinsics().find(view_I->id_intrinsic); + const Intrinsics::const_iterator iterIntrinsic_I = _sfm_data.GetIntrinsics().find(view_I->id_intrinsic); Pinhole_Intrinsic * cam_I = NULL; - if (iterIntrinsic_I == _sfm_data.getIntrinsics().end()) + if (iterIntrinsic_I == _sfm_data.GetIntrinsics().end()) { bKnownIntrinsic = false; } @@ -780,7 +780,7 @@ bool SequentialSfMReconstructionEngine::Resection(size_t viewIndex) iterfeatId != vec_featIdForResection.end(); ++iterfeatId, ++iterTrackId, ++cpt) { - pt3D.col(cpt) = _sfm_data.getLandmarks().at(*iterTrackId).X; + pt3D.col(cpt) = _sfm_data.GetLandmarks().at(*iterTrackId).X; const Vec2 feat = _features_provider->feats_per_view[viewIndex][*iterfeatId].coords().cast(); if (bKnownIntrinsic) @@ -846,7 +846,7 @@ bool SequentialSfMReconstructionEngine::Resection(size_t viewIndex) // Create a SfM_DataScene with one camera and the 3D points SfM_Data tiny_scene; - tiny_scene.views[view_I->id_view] = _sfm_data.getViews().at(viewIndex); + tiny_scene.views[view_I->id_view] = _sfm_data.GetViews().at(viewIndex); tiny_scene.poses[view_I->id_pose] = Pose3(R_, -R_.transpose() * t_); if (bKnownIntrinsic) { @@ -857,8 +857,8 @@ bool SequentialSfMReconstructionEngine::Resection(size_t viewIndex) if (view_I->id_intrinsic == UndefinedIndexT) { // Update id_intrinsic to a valid value - View * view_I = _sfm_data.getViews().at(viewIndex).get(); - view_I->id_intrinsic = _sfm_data.getIntrinsics().size(); + View * view_I = _sfm_data.GetViews().at(viewIndex).get(); + view_I->id_intrinsic = _sfm_data.GetIntrinsics().size(); } // Create the new camera intrinsic group switch (_camType) @@ -926,8 +926,8 @@ bool SequentialSfMReconstructionEngine::Resection(size_t viewIndex) for (std::set::const_iterator iterTrackId = set_trackIdForResection.begin(); iterTrackId != set_trackIdForResection.end(); ++iterTrackId, ++iterfeatId, ++cpt) { - const IntrinsicBase * intrinsic = _sfm_data.getIntrinsics().at(view_I->id_intrinsic).get(); - const Pose3 & pose = _sfm_data.getPoses().at(view_I->id_pose); + const IntrinsicBase * intrinsic = _sfm_data.GetIntrinsics().at(view_I->id_intrinsic).get(); + const Pose3 pose = _sfm_data.GetPoseOrDie(view_I); const Vec3 X = pt3D.col(cpt); const Vec2 x = _features_provider->feats_per_view[viewIndex][*iterfeatId].coords().cast(); const Vec2 residual = intrinsic->residual(pose, X, x); @@ -938,7 +938,7 @@ bool SequentialSfMReconstructionEngine::Resection(size_t viewIndex) _sfm_data.structure[*iterTrackId].obs[viewIndex] = Observation(x, *iterfeatId); } else { - // Remove this observation fro the scene tracking data + // Remove this observation from the scene tracking data _map_tracks[*iterTrackId].erase(viewIndex); if (_map_tracks[*iterTrackId].size() < 2) { _map_tracks.erase(*iterTrackId); @@ -984,12 +984,12 @@ bool SequentialSfMReconstructionEngine::Resection(size_t viewIndex) if (!vec_tracksToAdd.empty()) { - const View * view_1 = _sfm_data.getViews().at(I).get(); - const View * view_2 = _sfm_data.getViews().at(J).get(); - const IntrinsicBase * cam_1 = _sfm_data.getIntrinsics().at(view_1->id_intrinsic).get(); - const IntrinsicBase * cam_2 = _sfm_data.getIntrinsics().at(view_2->id_intrinsic).get(); - const Pose3 pose_1 = _sfm_data.getPoses().at(view_1->id_pose); - const Pose3 pose_2 = _sfm_data.getPoses().at(view_2->id_pose); + const View * view_1 = _sfm_data.GetViews().at(I).get(); + const View * view_2 = _sfm_data.GetViews().at(J).get(); + const IntrinsicBase * cam_1 = _sfm_data.GetIntrinsics().at(view_1->id_intrinsic).get(); + const IntrinsicBase * cam_2 = _sfm_data.GetIntrinsics().at(view_2->id_intrinsic).get(); + const Pose3 pose_1 = _sfm_data.GetPoseOrDie(view_1); + const Pose3 pose_2 = _sfm_data.GetPoseOrDie(view_2); const Mat34 P1 = cam_1->get_projective_equivalent(pose_1); const Mat34 P2 = cam_2->get_projective_equivalent(pose_2); @@ -1041,7 +1041,7 @@ bool SequentialSfMReconstructionEngine::Resection(size_t viewIndex) } std::cout << "--Triangulated 3D points [" << I << "-" << J <<"]: " << "\t #Validated/#Possible: " << new_track_count << "/" << vec_index.size() << std::endl - <<" #3DPoint for the entire scene: " << _sfm_data.getLandmarks().size() << std::endl; + <<" #3DPoint for the entire scene: " << _sfm_data.GetLandmarks().size() << std::endl; } } } @@ -1052,7 +1052,7 @@ bool SequentialSfMReconstructionEngine::Resection(size_t viewIndex) void SequentialSfMReconstructionEngine::BundleAdjustment() { Bundle_Adjustment_Ceres::BA_options options; - if (_sfm_data.getPoses().size() > 100) + if (_sfm_data.GetPoses().size() > 100) { options._preconditioner_type = ceres::JACOBI; options._linear_solver_type = ceres::SPARSE_SCHUR; diff --git a/src/openMVG/sfm/pipelines/sequential/sequential_SfM_test.cpp b/src/openMVG/sfm/pipelines/sequential/sequential_SfM_test.cpp index 85403c132a..5525b1cf24 100644 --- a/src/openMVG/sfm/pipelines/sequential/sequential_SfM_test.cpp +++ b/src/openMVG/sfm/pipelines/sequential/sequential_SfM_test.cpp @@ -74,8 +74,8 @@ TEST(SEQUENTIAL_SFM, Known_Intrinsics) { const double dResidual = RMSE(sfmEngine.Get_SfM_Data()); std::cout << "RMSE residual: " << dResidual << std::endl; EXPECT_TRUE( dResidual < 0.5); - EXPECT_TRUE( sfmEngine.Get_SfM_Data().getPoses().size() == nviews); - EXPECT_TRUE( sfmEngine.Get_SfM_Data().getLandmarks().size() == npoints); + EXPECT_TRUE( sfmEngine.Get_SfM_Data().GetPoses().size() == nviews); + EXPECT_TRUE( sfmEngine.Get_SfM_Data().GetLandmarks().size() == npoints); } // Test a scene where only the two first camera have known intrinsics @@ -135,8 +135,8 @@ TEST(SEQUENTIAL_SFM, Partially_Known_Intrinsics) { const double dResidual = RMSE(sfmEngine.Get_SfM_Data()); std::cout << "RMSE residual: " << dResidual << std::endl; EXPECT_TRUE( dResidual < 0.5); - EXPECT_TRUE( sfmEngine.Get_SfM_Data().getPoses().size() == nviews); - EXPECT_TRUE( sfmEngine.Get_SfM_Data().getLandmarks().size() == npoints); + EXPECT_TRUE( sfmEngine.Get_SfM_Data().GetPoses().size() == nviews); + EXPECT_TRUE( sfmEngine.Get_SfM_Data().GetLandmarks().size() == npoints); } /* ************************************************************************* */ diff --git a/src/openMVG/sfm/pipelines/sfm_features_provider.hpp b/src/openMVG/sfm/pipelines/sfm_features_provider.hpp index e01e1f8203..f72434fc5e 100644 --- a/src/openMVG/sfm/pipelines/sfm_features_provider.hpp +++ b/src/openMVG/sfm/pipelines/sfm_features_provider.hpp @@ -30,13 +30,13 @@ struct Features_Provider const std::string & feat_directory, std::unique_ptr& image_describer) { - C_Progress_display my_progress_bar( sfm_data.getViews().size(), + C_Progress_display my_progress_bar( sfm_data.GetViews().size(), std::cout, "\n- Features Loading -\n" ); // Read for each view the corresponding features and store them as PointFeatures std::unique_ptr regions; image_describer->Allocate(regions); - for (Views::const_iterator iter = sfm_data.getViews().begin(); - iter != sfm_data.getViews().end(); ++iter, ++my_progress_bar) + for (Views::const_iterator iter = sfm_data.GetViews().begin(); + iter != sfm_data.GetViews().end(); ++iter, ++my_progress_bar) { const std::string sImageName = stlplus::create_filespec(sfm_data.s_root_path, iter->second.get()->s_Img_path); const std::string basename = stlplus::basename_part(sImageName); @@ -58,12 +58,12 @@ struct Features_Provider const std::string & feat_directory, std::unique_ptr& region_type) { - C_Progress_display my_progress_bar( sfm_data.getViews().size(), + C_Progress_display my_progress_bar( sfm_data.GetViews().size(), std::cout, "\n- Features Loading -\n" ); // Read for each view the corresponding features and store them as PointFeatures std::unique_ptr regions(region_type->EmptyClone()); - for (Views::const_iterator iter = sfm_data.getViews().begin(); - iter != sfm_data.getViews().end(); ++iter, ++my_progress_bar) + for (Views::const_iterator iter = sfm_data.GetViews().begin(); + iter != sfm_data.GetViews().end(); ++iter, ++my_progress_bar) { const std::string sImageName = stlplus::create_filespec(sfm_data.s_root_path, iter->second.get()->s_Img_path); const std::string basename = stlplus::basename_part(sImageName); diff --git a/src/openMVG/sfm/pipelines/sfm_matches_provider.hpp b/src/openMVG/sfm/pipelines/sfm_matches_provider.hpp index 97827aa882..482e59bfd2 100644 --- a/src/openMVG/sfm/pipelines/sfm_matches_provider.hpp +++ b/src/openMVG/sfm/pipelines/sfm_matches_provider.hpp @@ -34,7 +34,7 @@ struct Matches_Provider } // Filter to keep only the one defined in SfM_Data { - const Views & views = sfm_data.getViews(); + const Views & views = sfm_data.GetViews(); matching::PairWiseMatches matches_saved; for (matching::PairWiseMatches::const_iterator iter = _pairWise_matches.begin(); iter != _pairWise_matches.end(); diff --git a/src/openMVG/sfm/pipelines/sfm_regions_provider.hpp b/src/openMVG/sfm/pipelines/sfm_regions_provider.hpp index 28cd6e008d..000c1e2888 100644 --- a/src/openMVG/sfm/pipelines/sfm_regions_provider.hpp +++ b/src/openMVG/sfm/pipelines/sfm_regions_provider.hpp @@ -30,11 +30,11 @@ struct Regions_Provider const std::string & feat_directory, std::unique_ptr& image_describer) { - C_Progress_display my_progress_bar( sfm_data.getViews().size(), + C_Progress_display my_progress_bar( sfm_data.GetViews().size(), std::cout, "\n- Regions Loading -\n"); // Read for each view the corresponding regions and store them - for (Views::const_iterator iter = sfm_data.getViews().begin(); - iter != sfm_data.getViews().end(); ++iter, ++my_progress_bar) + for (Views::const_iterator iter = sfm_data.GetViews().begin(); + iter != sfm_data.GetViews().end(); ++iter, ++my_progress_bar) { const std::string sImageName = stlplus::create_filespec(sfm_data.s_root_path, iter->second.get()->s_Img_path); const std::string basename = stlplus::basename_part(sImageName); @@ -60,11 +60,11 @@ struct Regions_Provider const std::string & feat_directory, std::unique_ptr& region_type) { - C_Progress_display my_progress_bar( sfm_data.getViews().size(), + C_Progress_display my_progress_bar( sfm_data.GetViews().size(), std::cout, "\n- Regions Loading -\n"); // Read for each view the corresponding regions and store them - for (Views::const_iterator iter = sfm_data.getViews().begin(); - iter != sfm_data.getViews().end(); ++iter, ++my_progress_bar) + for (Views::const_iterator iter = sfm_data.GetViews().begin(); + iter != sfm_data.GetViews().end(); ++iter, ++my_progress_bar) { const std::string sImageName = stlplus::create_filespec(sfm_data.s_root_path, iter->second.get()->s_Img_path); const std::string basename = stlplus::basename_part(sImageName); diff --git a/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.hpp b/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.hpp index 729eaf82a4..e9d08d61f5 100644 --- a/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.hpp +++ b/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.hpp @@ -89,19 +89,19 @@ class SfM_Data_Structure_Estimation_From_Known_Poses // - by considering geometric error and descriptor distance ratio. std::vector vec_corresponding_indexes; - const View * viewL = sfm_data.getViews().at(it->first).get(); - const Poses::const_iterator iterPoseL = sfm_data.getPoses().find(viewL->id_pose); - const Intrinsics::const_iterator iterIntrinsicL = sfm_data.getIntrinsics().find(viewL->id_intrinsic); - const View * viewR = sfm_data.getViews().at(it->second).get(); - const Poses::const_iterator iterPoseR = sfm_data.getPoses().find(viewR->id_pose); - const Intrinsics::const_iterator iterIntrinsicR = sfm_data.getIntrinsics().find(viewR->id_intrinsic); + const View * viewL = sfm_data.GetViews().at(it->first).get(); + const Pose3 poseL = sfm_data.GetPoseOrDie(viewL); + const Intrinsics::const_iterator iterIntrinsicL = sfm_data.GetIntrinsics().find(viewL->id_intrinsic); + const View * viewR = sfm_data.GetViews().at(it->second).get(); + const Pose3 poseR = sfm_data.GetPoseOrDie(viewR); + const Intrinsics::const_iterator iterIntrinsicR = sfm_data.GetIntrinsics().find(viewR->id_intrinsic); Mat xL, xR; PointsToMat(iterIntrinsicL->second.get(), regions_provider->regions_per_view.at(it->first)->GetRegionsPositions(), xL); PointsToMat(iterIntrinsicR->second.get(), regions_provider->regions_per_view.at(it->second)->GetRegionsPositions(), xR); - const Mat34 P_L = iterIntrinsicL->second.get()->get_projective_equivalent(iterPoseL->second); - const Mat34 P_R = iterIntrinsicR->second.get()->get_projective_equivalent(iterPoseR->second); + const Mat34 P_L = iterIntrinsicL->second.get()->get_projective_equivalent(poseL); + const Mat34 P_R = iterIntrinsicR->second.get()->get_projective_equivalent(poseR); const Mat3 F_lr = F_from_P(P_L, P_R); const double thresholdF = 4.0; @@ -115,7 +115,7 @@ class SfM_Data_Structure_Estimation_From_Known_Poses Square(thresholdF), Square(0.8), vec_corresponding_indexes); #else - const Vec3 epipole2 = epipole_from_P(P_R, iterPoseL->second); + const Vec3 epipole2 = epipole_from_P(P_R, poseL); const features::Regions * regions = regions_provider->regions_per_view.at(it->first).get(); if (regions->IsScalar()) @@ -253,9 +253,9 @@ class SfM_Data_Structure_Estimation_From_Known_Poses for (tracks::submapTrack::const_iterator iter = subTrack.begin(); iter != subTrack.end(); ++iter) { const size_t imaIndex = iter->first; const size_t featIndex = iter->second; - const View * view = sfm_data.getViews().at(imaIndex).get(); - const IntrinsicBase * cam = sfm_data.getIntrinsics().at(view->id_intrinsic).get(); - const Pose3 & pose = sfm_data.poses.at(view->id_pose); + const View * view = sfm_data.GetViews().at(imaIndex).get(); + const IntrinsicBase * cam = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); + const Pose3 pose = sfm_data.GetPoseOrDie(view); const Vec2 pt = regions_provider->regions_per_view.at(imaIndex)->GetRegionPosition(featIndex); trianObj.add(cam->get_projective_equivalent(pose), cam->get_ud_pixel(pt)); } diff --git a/src/openMVG/sfm/sfm_data.hpp b/src/openMVG/sfm/sfm_data.hpp index 7a99850237..223ddfccb0 100644 --- a/src/openMVG/sfm/sfm_data.hpp +++ b/src/openMVG/sfm/sfm_data.hpp @@ -23,7 +23,7 @@ typedef Hash_Map > Views; /// Define a collection of Pose (indexed by View::id_pose) typedef Hash_Map Poses; -/// Define a collection of IntrinsicParameter (indexed by View::id_intrinsic) +/// Define a collection of IntrinsicParameter (indexed by View::id_intrinsic) typedef Hash_Map > Intrinsics; /// Define a collection of landmarks are indexed by their TrackId @@ -48,10 +48,10 @@ struct SfM_Data //-- // Accessors //-- - const Views & getViews() const {return views;} - const Poses & getPoses() const {return poses;} - const Intrinsics & getIntrinsics() const {return intrinsics;} - const Landmarks & getLandmarks() const {return structure;} + const Views & GetViews() const {return views;} + const Poses & GetPoses() const {return poses;} + const Intrinsics & GetIntrinsics() const {return intrinsics;} + const Landmarks & GetLandmarks() const {return structure;} /// Check if the View have defined intrinsic and pose bool IsPoseAndIntrinsicDefined(const View * view) const @@ -64,6 +64,11 @@ struct SfM_Data poses.find(view->id_pose) != poses.end()); } + /// Get the pose associated to a view + const Pose3 GetPoseOrDie(const View * view) const + { + return poses.at(view->id_pose); + } }; } // namespace openMVG diff --git a/src/openMVG/sfm/sfm_data_BA_test.cpp b/src/openMVG/sfm/sfm_data_BA_test.cpp index 7ef586c686..f1eea4d894 100644 --- a/src/openMVG/sfm/sfm_data_BA_test.cpp +++ b/src/openMVG/sfm/sfm_data_BA_test.cpp @@ -94,17 +94,17 @@ double RMSE(const SfM_Data & sfm_data) { // Compute residuals for each observation std::vector vec; - for(Landmarks::const_iterator iterTracks = sfm_data.getLandmarks().begin(); - iterTracks != sfm_data.getLandmarks().end(); + for(Landmarks::const_iterator iterTracks = sfm_data.GetLandmarks().begin(); + iterTracks != sfm_data.GetLandmarks().end(); ++iterTracks) { const Observations & obs = iterTracks->second.obs; for(Observations::const_iterator itObs = obs.begin(); itObs != obs.end(); ++itObs) { - const View * view = sfm_data.getViews().find(itObs->first)->second.get(); - const Pose3 & pose = sfm_data.getPoses().find(view->id_pose)->second; - const std::shared_ptr intrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic)->second; + const View * view = sfm_data.GetViews().find(itObs->first)->second.get(); + const Pose3 pose = sfm_data.GetPoseOrDie(view); + const std::shared_ptr intrinsic = sfm_data.GetIntrinsics().find(view->id_intrinsic)->second; const Vec2 residual = intrinsic->residual(pose, iterTracks->second.X, itObs->second.x); vec.push_back( residual(0) ); vec.push_back( residual(1) ); diff --git a/src/openMVG/sfm/sfm_data_filters.hpp b/src/openMVG/sfm/sfm_data_filters.hpp index a831b19098..491d82df72 100644 --- a/src/openMVG/sfm/sfm_data_filters.hpp +++ b/src/openMVG/sfm/sfm_data_filters.hpp @@ -9,6 +9,7 @@ #define OPENMVG_SFM_DATA_FILTERS_HPP #include "openMVG/stl/stl.hpp" +#include namespace openMVG { @@ -19,8 +20,8 @@ static std::set Get_Valid_Views ) { std::set valid_idx; - for (Views::const_iterator it = sfm_data.getViews().begin(); - it != sfm_data.getViews().end(); ++it) + for (Views::const_iterator it = sfm_data.GetViews().begin(); + it != sfm_data.GetViews().end(); ++it) { const View * v = it->second.get(); if (sfm_data.IsPoseAndIntrinsicDefined(v)) @@ -140,8 +141,8 @@ static bool eraseMissingPoses(SfM_Data & sfm_data, const IndexT min_points_per_p // Count the observation poses occurence Hash_Map map_PoseId_Count; // Init with 0 count (in order to be able to remove non referenced elements) - for (Poses::const_iterator itPoses = sfm_data.getPoses().begin(); - itPoses != sfm_data.getPoses().end(); ++itPoses) + for (Poses::const_iterator itPoses = sfm_data.GetPoses().begin(); + itPoses != sfm_data.GetPoses().end(); ++itPoses) { map_PoseId_Count[itPoses->first] = 0; } @@ -155,7 +156,7 @@ static bool eraseMissingPoses(SfM_Data & sfm_data, const IndexT min_points_per_p itObs != obs.end(); ++itObs) { const IndexT ViewId = itObs->first; - const View * v = sfm_data.getViews().at(ViewId).get(); + const View * v = sfm_data.GetViews().at(ViewId).get(); if (map_PoseId_Count.count(v->id_pose)) map_PoseId_Count[v->id_pose] += 1; else @@ -194,7 +195,7 @@ static bool eraseObservationsWithMissingPoses(SfM_Data & sfm_data, const IndexT while (itObs != obs.end()) { const IndexT ViewId = itObs->first; - const View * v = sfm_data.getViews().at(ViewId).get(); + const View * v = sfm_data.GetViews().at(ViewId).get(); if (pose_Index.count(v->id_pose) == 0) { itObs = obs.erase(itObs); diff --git a/src/openMVG/sfm/sfm_data_filters_frustum.cpp b/src/openMVG/sfm/sfm_data_filters_frustum.cpp index b6eb94f1f6..73d58729a4 100644 --- a/src/openMVG/sfm/sfm_data_filters_frustum.cpp +++ b/src/openMVG/sfm/sfm_data_filters_frustum.cpp @@ -34,17 +34,15 @@ void Frustum_Filter::initFrustum(const SfM_Data & sfm_data) for (NearFarPlanesT::const_iterator it = z_near_z_far_perView.begin(); it != z_near_z_far_perView.end(); ++it) { - const View * view = sfm_data.getViews().at(it->first).get(); + const View * view = sfm_data.GetViews().at(it->first).get(); if (!sfm_data.IsPoseAndIntrinsicDefined(view)) continue; - - Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); + Intrinsics::const_iterator iterIntrinsic = sfm_data.GetIntrinsics().find(view->id_intrinsic); if (!isPinhole(iterIntrinsic->second.get()->getType())) continue; - Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); + const Pose3 pose = sfm_data.GetPoseOrDie(view); - const Pose3 & pose = iterPose->second; const Pinhole_Intrinsic * cam = dynamic_cast(iterIntrinsic->second.get()); if (cam == NULL) continue; @@ -190,8 +188,8 @@ void Frustum_Filter::init_z_near_z_far_depth(const SfM_Data & sfm_data, const bool bComputed_Z = (zNear == -1. && zFar == -1.) && !sfm_data.structure.empty(); if (bComputed_Z) // Compute the near & far planes from the structure and view observations { - for (Landmarks::const_iterator itL = sfm_data.getLandmarks().begin(); - itL != sfm_data.getLandmarks().end(); ++itL) + for (Landmarks::const_iterator itL = sfm_data.GetLandmarks().begin(); + itL != sfm_data.GetLandmarks().end(); ++itL) { const Landmark & landmark = itL->second; const Vec3 & X = landmark.X; @@ -200,12 +198,12 @@ void Frustum_Filter::init_z_near_z_far_depth(const SfM_Data & sfm_data, { const IndexT id_view = iterO->first; const Observation & ob = iterO->second; - const View * view = sfm_data.getViews().at(id_view).get(); + const View * view = sfm_data.GetViews().at(id_view).get(); if (!sfm_data.IsPoseAndIntrinsicDefined(view)) continue; - Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); - const Pose3 & pose = iterPose->second; + Intrinsics::const_iterator iterIntrinsic = sfm_data.GetIntrinsics().find(view->id_intrinsic); + const Pose3 pose = sfm_data.GetPoseOrDie(view); const double z = pose.depth(X); NearFarPlanesT::iterator itZ = z_near_z_far_perView.find(id_view); if (itZ != z_near_z_far_perView.end()) @@ -224,8 +222,8 @@ void Frustum_Filter::init_z_near_z_far_depth(const SfM_Data & sfm_data, else { // Init the same near & far limit for all the valid views - for (Views::const_iterator it = sfm_data.getViews().begin(); - it != sfm_data.getViews().end(); ++it) + for (Views::const_iterator it = sfm_data.GetViews().begin(); + it != sfm_data.GetViews().end(); ++it) { const View * view = it->second.get(); if (!sfm_data.IsPoseAndIntrinsicDefined(view)) diff --git a/src/openMVG/sfm/sfm_data_io.cpp b/src/openMVG/sfm/sfm_data_io.cpp index baefefa8bd..c24e4e4aa8 100644 --- a/src/openMVG/sfm/sfm_data_io.cpp +++ b/src/openMVG/sfm/sfm_data_io.cpp @@ -24,18 +24,18 @@ bool ValidIds(const SfM_Data & sfm_data, ESfM_Data flags_part) const bool bCheck_Extrinsic = (flags_part & EXTRINSICS) == EXTRINSICS; std::set set_id_intrinsics; - transform(sfm_data.getIntrinsics().begin(), sfm_data.getIntrinsics().end(), + transform(sfm_data.GetIntrinsics().begin(), sfm_data.GetIntrinsics().end(), std::inserter(set_id_intrinsics, set_id_intrinsics.begin()), std::RetrieveKey()); std::set set_id_extrinsics; //unique so can use a set - transform(sfm_data.getPoses().begin(), sfm_data.getPoses().end(), + transform(sfm_data.GetPoses().begin(), sfm_data.GetPoses().end(), std::inserter(set_id_extrinsics, set_id_extrinsics.begin()), std::RetrieveKey()); // Collect existing id_intrinsic && id_extrinsic from views std::set reallyDefined_id_intrinsics; std::set reallyDefined_id_extrinsics; - for (Views::const_iterator iter = sfm_data.getViews().begin(); - iter != sfm_data.getViews().end(); + for (Views::const_iterator iter = sfm_data.GetViews().begin(); + iter != sfm_data.GetViews().end(); ++iter) { // If a pose is defined, at least the intrinsic must be valid, diff --git a/src/openMVG/sfm/sfm_data_io_baf.hpp b/src/openMVG/sfm/sfm_data_io_baf.hpp index a003757c70..9422300a08 100644 --- a/src/openMVG/sfm/sfm_data_io_baf.hpp +++ b/src/openMVG/sfm/sfm_data_io_baf.hpp @@ -35,11 +35,11 @@ static bool Save_BAF( bool bOk = false; { stream - << sfm_data.getIntrinsics().size() << '\n' - << sfm_data.getPoses().size() << '\n' - << sfm_data.getLandmarks().size() << '\n'; + << sfm_data.GetIntrinsics().size() << '\n' + << sfm_data.GetPoses().size() << '\n' + << sfm_data.GetLandmarks().size() << '\n'; - const Intrinsics & intrinsics = sfm_data.getIntrinsics(); + const Intrinsics & intrinsics = sfm_data.GetIntrinsics(); for (Intrinsics::const_iterator iterIntrinsic = intrinsics.begin(); iterIntrinsic != intrinsics.end(); ++iterIntrinsic) { @@ -50,7 +50,7 @@ static bool Save_BAF( stream << "\n"; } - const Poses & poses = sfm_data.getPoses(); + const Poses & poses = sfm_data.GetPoses(); for (Poses::const_iterator iterPose = poses.begin(); iterPose != poses.end(); ++iterPose) { @@ -62,7 +62,7 @@ static bool Save_BAF( stream << "\n"; } - const Landmarks & landmarks = sfm_data.getLandmarks(); + const Landmarks & landmarks = sfm_data.GetLandmarks(); for (Landmarks::const_iterator iterLandmarks = landmarks.begin(); iterLandmarks != landmarks.end(); ++iterLandmarks) @@ -77,7 +77,7 @@ static bool Save_BAF( iterOb != obs.end(); ++iterOb) { const IndexT id_view = iterOb->first; - const View * v = sfm_data.getViews().at(id_view).get(); + const View * v = sfm_data.GetViews().at(id_view).get(); stream << v->id_intrinsic << ' ' << v->id_pose << ' ' << iterOb->second.x(0) << ' ' << iterOb->second.x(1) << ' '; diff --git a/src/openMVG/sfm/sfm_data_io_ply.hpp b/src/openMVG/sfm/sfm_data_io_ply.hpp index 50b6a50472..1e7f66012b 100644 --- a/src/openMVG/sfm/sfm_data_io_ply.hpp +++ b/src/openMVG/sfm/sfm_data_io_ply.hpp @@ -36,8 +36,8 @@ static bool Save_PLY( stream << "ply" << '\n' << "format ascii 1.0" << '\n' << "element vertex " - << ((b_structure ? data.getLandmarks().size() : 0) + - (b_extrinsics ? data.getPoses().size() : 0)) + << ((b_structure ? data.GetLandmarks().size() : 0) + + (b_extrinsics ? data.GetPoses().size() : 0)) << '\n' << "property float x" << '\n' << "property float y" << '\n' << "property float z" @@ -48,7 +48,7 @@ static bool Save_PLY( if (b_extrinsics) { - const Poses & poses = data.getPoses(); + const Poses & poses = data.GetPoses(); for (Poses::const_iterator iterPose = poses.begin(); iterPose != poses.end(); ++iterPose) { stream << iterPose->second.center().transpose() @@ -58,7 +58,7 @@ static bool Save_PLY( if (b_structure) { - const Landmarks & landmarks = data.getLandmarks(); + const Landmarks & landmarks = data.GetLandmarks(); for (Landmarks::const_iterator iterLandmarks = landmarks.begin(); iterLandmarks != landmarks.end(); ++iterLandmarks) { diff --git a/src/openMVG/sfm/sfm_data_triangulation.hpp b/src/openMVG/sfm/sfm_data_triangulation.hpp index 2e32cf8031..d1602c96ed 100644 --- a/src/openMVG/sfm/sfm_data_triangulation.hpp +++ b/src/openMVG/sfm/sfm_data_triangulation.hpp @@ -76,8 +76,8 @@ struct SfM_Data_Structure_Computation_Blind: public SfM_Data_Structure_Computati itObs != obs.end(); ++itObs) { const View * view = sfm_data.views.at(itObs->first).get(); - const IntrinsicBase * cam = sfm_data.getIntrinsics().at(view->id_intrinsic).get(); - const Pose3 & pose = sfm_data.poses.at(view->id_pose); + const IntrinsicBase * cam = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); + const Pose3 & pose = sfm_data.GetPoseOrDie(view); trianObj.add( cam->get_projective_equivalent(pose), cam->get_ud_pixel(itObs->second.x)); @@ -213,8 +213,8 @@ struct SfM_Data_Structure_Computation_Robust: public SfM_Data_Structure_Computat Observations::const_iterator itObs = obs.begin(); std::advance(itObs, it); const View * view = sfm_data.views.at(itObs->first).get(); - const IntrinsicBase * cam = sfm_data.getIntrinsics().at(view->id_intrinsic).get(); - const Pose3 & pose = sfm_data.poses.at(view->id_pose); + const IntrinsicBase * cam = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); + const Pose3 & pose = sfm_data.GetPoseOrDie(view); const double z = pose.depth(current_model); // TODO: cam->depth(pose(X)); bChierality &= z > 0; } @@ -229,8 +229,8 @@ struct SfM_Data_Structure_Computation_Robust: public SfM_Data_Structure_Computat itObs != obs.end(); ++itObs) { const View * view = sfm_data.views.at(itObs->first).get(); - const IntrinsicBase * intrinsic = sfm_data.getIntrinsics().at(view->id_intrinsic).get(); - const Pose3 & pose = sfm_data.poses.at(view->id_pose); + const IntrinsicBase * intrinsic = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); + const Pose3 & pose = sfm_data.GetPoseOrDie(view); const Vec2 residual = intrinsic->residual(pose, current_model, itObs->second.x); const double residual_d = residual.norm(); if (residual_d < dThresholdPixel) @@ -268,8 +268,8 @@ struct SfM_Data_Structure_Computation_Robust: public SfM_Data_Structure_Computat Observations::const_iterator itObs = obs.begin(); std::advance(itObs, idx); const View * view = sfm_data.views.at(itObs->first).get(); - const IntrinsicBase * cam = sfm_data.getIntrinsics().at(view->id_intrinsic).get(); - const Pose3 & pose = sfm_data.poses.at(view->id_pose); + const IntrinsicBase * cam = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); + const Pose3 & pose = sfm_data.GetPoseOrDie(view); trianObj.add( cam->get_projective_equivalent(pose), cam->get_ud_pixel(itObs->second.x)); diff --git a/src/openMVG/sfm/sfm_report.hpp b/src/openMVG/sfm/sfm_report.hpp index fc5b6b48aa..f1db8f0007 100644 --- a/src/openMVG/sfm/sfm_report.hpp +++ b/src/openMVG/sfm/sfm_report.hpp @@ -23,8 +23,8 @@ static bool Generate_SfM_Report // Compute mean,max,median residual values per View IndexT residualCount = 0; Hash_Map< IndexT, std::vector > residuals_per_view; - for (Landmarks::const_iterator iterTracks = sfm_data.getLandmarks().begin(); - iterTracks != sfm_data.getLandmarks().end(); + for (Landmarks::const_iterator iterTracks = sfm_data.GetLandmarks().begin(); + iterTracks != sfm_data.GetLandmarks().end(); ++iterTracks ) { @@ -32,9 +32,9 @@ static bool Generate_SfM_Report for (Observations::const_iterator itObs = obs.begin(); itObs != obs.end(); ++itObs) { - const View * view = sfm_data.getViews().at(itObs->first).get(); - const Pose3 & pose = sfm_data.getPoses().at(view->id_pose); - const IntrinsicBase * intrinsic = sfm_data.getIntrinsics().at(view->id_intrinsic).get(); + const View * view = sfm_data.GetViews().at(itObs->first).get(); + const Pose3 pose = sfm_data.GetPoseOrDie(view); + const IntrinsicBase * intrinsic = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); // Use absolute values const Vec2 residual = intrinsic->residual(pose, iterTracks->second.X, itObs->second.x).array().abs(); residuals_per_view[itObs->first].push_back(residual(0)); @@ -58,10 +58,10 @@ static bool Generate_SfM_Report htmlDocStream.pushInfo( "Dataset info:" + sNewLine ); std::ostringstream os; - os << " #views: " << sfm_data.getViews().size() << sNewLine - << " #poses: " << sfm_data.getPoses().size() << sNewLine - << " #intrinsics: " << sfm_data.getIntrinsics().size() << sNewLine - << " #tracks: " << sfm_data.getLandmarks().size() << sNewLine + os << " #views: " << sfm_data.GetViews().size() << sNewLine + << " #poses: " << sfm_data.GetPoses().size() << sNewLine + << " #intrinsics: " << sfm_data.GetIntrinsics().size() << sNewLine + << " #tracks: " << sfm_data.GetLandmarks().size() << sNewLine << " #residuals: " << residualCount << sNewLine; htmlDocStream.pushInfo( os.str() ); @@ -80,8 +80,8 @@ static bool Generate_SfM_Report << sRowEnd; htmlDocStream.pushInfo( os.str() ); - for (Views::const_iterator iterV = sfm_data.getViews().begin(); - iterV != sfm_data.getViews().end(); + for (Views::const_iterator iterV = sfm_data.GetViews().begin(); + iterV != sfm_data.GetViews().end(); ++iterV) { const View * v = iterV->second.get(); @@ -168,6 +168,8 @@ static bool Generate_SfM_Report std::ofstream htmlFileStream(htmlFilename.c_str()); htmlFileStream << htmlDocStream.getDoc(); + const bool bOk = !htmlFileStream.bad(); + return bOk; } } // namespace openMVG diff --git a/src/openMVG/version.hpp b/src/openMVG/version.hpp index fc4776a665..f490925fa2 100644 --- a/src/openMVG/version.hpp +++ b/src/openMVG/version.hpp @@ -9,7 +9,7 @@ #define OPENMVG_VERSION_MAJOR 0 #define OPENMVG_VERSION_MINOR 8 -#define OPENMVG_VERSION_REVISION 0 +#define OPENMVG_VERSION_REVISION 1 // Preprocessor to string conversion #define OPENMVG_TO_STRING_HELPER(x) #x diff --git a/src/software/SfM/main_ComputeFeatures.cpp b/src/software/SfM/main_ComputeFeatures.cpp index e0d190af44..ed948f4dbe 100644 --- a/src/software/SfM/main_ComputeFeatures.cpp +++ b/src/software/SfM/main_ComputeFeatures.cpp @@ -208,7 +208,7 @@ int main(int argc, char **argv) { Timer timer; Image imageGray; - C_Progress_display my_progress_bar( sfm_data.getViews().size(), + C_Progress_display my_progress_bar( sfm_data.GetViews().size(), std::cout, "\n- EXTRACT FEATURES -\n" ); for(Views::const_iterator iterViews = sfm_data.views.begin(); iterViews != sfm_data.views.end(); diff --git a/src/software/SfM/main_ComputeFeatures_OpenCV.cpp b/src/software/SfM/main_ComputeFeatures_OpenCV.cpp index 3a44461387..fb2f39475c 100644 --- a/src/software/SfM/main_ComputeFeatures_OpenCV.cpp +++ b/src/software/SfM/main_ComputeFeatures_OpenCV.cpp @@ -235,7 +235,7 @@ int main(int argc, char **argv) { Timer timer; Image imageGray; - C_Progress_display my_progress_bar( sfm_data.getViews().size(), + C_Progress_display my_progress_bar( sfm_data.GetViews().size(), std::cout, "\n- EXTRACT FEATURES -\n" ); for(Views::const_iterator iterViews = sfm_data.views.begin(); iterViews != sfm_data.views.end(); diff --git a/src/software/SfM/main_ComputeMatches.cpp b/src/software/SfM/main_ComputeMatches.cpp index 821b6896eb..b6178e8380 100644 --- a/src/software/SfM/main_ComputeMatches.cpp +++ b/src/software/SfM/main_ComputeMatches.cpp @@ -199,10 +199,10 @@ int main(int argc, char **argv) std::vector vec_fileNames; std::vector > vec_imagesSize; { - vec_fileNames.reserve(sfm_data.getViews().size()); - vec_imagesSize.reserve(sfm_data.getViews().size()); - for (Views::const_iterator iter = sfm_data.getViews().begin(); - iter != sfm_data.getViews().end(); + vec_fileNames.reserve(sfm_data.GetViews().size()); + vec_imagesSize.reserve(sfm_data.GetViews().size()); + for (Views::const_iterator iter = sfm_data.GetViews().begin(); + iter != sfm_data.GetViews().end(); ++iter) { const View * v = iter->second.get(); @@ -271,10 +271,10 @@ int main(int argc, char **argv) Pair_Set pairs; switch (ePairmode) { - case PAIR_EXHAUSTIVE: pairs = exhaustivePairs(sfm_data.getViews().size()); break; - case PAIR_CONTIGUOUS: pairs = contiguousWithOverlap(sfm_data.getViews().size(), iMatchingVideoMode); break; + case PAIR_EXHAUSTIVE: pairs = exhaustivePairs(sfm_data.GetViews().size()); break; + case PAIR_CONTIGUOUS: pairs = contiguousWithOverlap(sfm_data.GetViews().size(), iMatchingVideoMode); break; case PAIR_FROM_FILE: - if(!loadPairs(sfm_data.getViews().size(), sPredefinedPairList, pairs)) + if(!loadPairs(sfm_data.GetViews().size(), sPredefinedPairList, pairs)) { return EXIT_FAILURE; }; @@ -333,14 +333,14 @@ int main(int argc, char **argv) // Build the intrinsic parameter map for each view std::map map_K; size_t cpt = 0; - for (Views::const_iterator iter = sfm_data.getViews().begin(); - iter != sfm_data.getViews().end(); + for (Views::const_iterator iter = sfm_data.GetViews().begin(); + iter != sfm_data.GetViews().end(); ++iter, ++cpt) { const View * v = iter->second.get(); - if (sfm_data.getIntrinsics().count(v->id_intrinsic)) + if (sfm_data.GetIntrinsics().count(v->id_intrinsic)) { - const IntrinsicBase * ptrIntrinsic = sfm_data.getIntrinsics().find(v->id_intrinsic)->second.get(); + const IntrinsicBase * ptrIntrinsic = sfm_data.GetIntrinsics().find(v->id_intrinsic)->second.get(); if (isPinhole(ptrIntrinsic->getType())) { const Pinhole_Intrinsic * ptrPinhole = (const Pinhole_Intrinsic*)(ptrIntrinsic); diff --git a/src/software/SfM/main_ComputeSfM_DataColor.cpp b/src/software/SfM/main_ComputeSfM_DataColor.cpp index eb7abe5260..46d59ad9a4 100644 --- a/src/software/SfM/main_ComputeSfM_DataColor.cpp +++ b/src/software/SfM/main_ComputeSfM_DataColor.cpp @@ -26,18 +26,18 @@ void ColorizeTracks( // and iterate to provide a color to each 3D point { - C_Progress_display my_progress_bar(sfm_data.getLandmarks().size(), + C_Progress_display my_progress_bar(sfm_data.GetLandmarks().size(), std::cout, "\nCompute scene structure color\n"); - vec_tracksColor.resize(sfm_data.getLandmarks().size()); - vec_3dPoints.resize(sfm_data.getLandmarks().size()); + vec_tracksColor.resize(sfm_data.GetLandmarks().size()); + vec_3dPoints.resize(sfm_data.GetLandmarks().size()); //Build a list of contiguous index for the trackIds std::map trackIds_to_contiguousIndexes; IndexT cpt = 0; - for (Landmarks::const_iterator it = sfm_data.getLandmarks().begin(); - it != sfm_data.getLandmarks().end(); ++it, ++cpt) + for (Landmarks::const_iterator it = sfm_data.GetLandmarks().begin(); + it != sfm_data.GetLandmarks().end(); ++it, ++cpt) { trackIds_to_contiguousIndexes[it->first] = cpt; vec_3dPoints[cpt] = it->second.X; @@ -45,7 +45,7 @@ void ColorizeTracks( // The track list that will be colored (point removed during the process) std::set remainingTrackToColor; - std::transform(sfm_data.getLandmarks().begin(), sfm_data.getLandmarks().end(), + std::transform(sfm_data.GetLandmarks().begin(), sfm_data.GetLandmarks().end(), std::inserter(remainingTrackToColor, remainingTrackToColor.begin()), RetrieveKey() ); @@ -62,7 +62,7 @@ void ColorizeTracks( ++iterT) { const size_t trackId = *iterT; - const Observations & obs = sfm_data.getLandmarks().at(trackId).obs; + const Observations & obs = sfm_data.GetLandmarks().at(trackId).obs; for( Observations::const_iterator iterObs = obs.begin(); iterObs != obs.end(); ++iterObs) { @@ -88,7 +88,7 @@ void ColorizeTracks( std::map::const_iterator iterTT = map_IndexCardinal.begin(); std::advance(iterTT, packet_vec[0].index); const size_t view_index = iterTT->first; - const View * view = sfm_data.getViews().at(view_index).get(); + const View * view = sfm_data.GetViews().at(view_index).get(); const std::string sView_filename = stlplus::create_filespec(sfm_data.s_root_path, view->s_Img_path); Image image; @@ -103,7 +103,7 @@ void ColorizeTracks( ++iterT) { const size_t trackId = *iterT; - const Observations & obs = sfm_data.getLandmarks().at(trackId).obs; + const Observations & obs = sfm_data.GetLandmarks().at(trackId).obs; Observations::const_iterator it = obs.find(view_index); if (it != obs.end()) @@ -130,7 +130,7 @@ void ColorizeTracks( /// Export camera poses positions as a Vec3 vector void GetCameraPositions(const SfM_Data & sfm_data, std::vector & vec_camPosition) { - const Poses & poses = sfm_data.getPoses(); + const Poses & poses = sfm_data.GetPoses(); for (Poses::const_iterator iterPose = poses.begin(); iterPose != poses.end(); ++iterPose) { diff --git a/src/software/SfM/main_ComputeStructureFromKnownPoses.cpp b/src/software/SfM/main_ComputeStructureFromKnownPoses.cpp index 9495038a75..017769ad01 100644 --- a/src/software/SfM/main_ComputeStructureFromKnownPoses.cpp +++ b/src/software/SfM/main_ComputeStructureFromKnownPoses.cpp @@ -121,7 +121,7 @@ int main(int argc, char **argv) std::cout << "\nStructure estimation took (s): " << timer.elapsed() << "." << std::endl; - std::cout << "#landmark found: " << sfm_data.getLandmarks().size() << std::endl; + std::cout << "#landmark found: " << sfm_data.GetLandmarks().size() << std::endl; if (stlplus::extension_part(sOutFile) != "ply") { Save(sfm_data, diff --git a/src/software/SfM/main_FrustumFiltering.cpp b/src/software/SfM/main_FrustumFiltering.cpp index 67f95e0f87..ec9534502a 100644 --- a/src/software/SfM/main_FrustumFiltering.cpp +++ b/src/software/SfM/main_FrustumFiltering.cpp @@ -21,8 +21,8 @@ Pair_Set BuildPairsFromStructureObservations(const SfM_Data & sfm_data) { Pair_Set pairs; - for (Landmarks::const_iterator itL = sfm_data.getLandmarks().begin(); - itL != sfm_data.getLandmarks().end(); ++itL) + for (Landmarks::const_iterator itL = sfm_data.GetLandmarks().begin(); + itL != sfm_data.GetLandmarks().end(); ++itL) { const Landmark & landmark = itL->second; const Vec3 & X = landmark.X; diff --git a/src/software/SfM/main_IncrementalSfM.cpp b/src/software/SfM/main_IncrementalSfM.cpp index 75a3c550b6..ccc1e03dcc 100644 --- a/src/software/SfM/main_IncrementalSfM.cpp +++ b/src/software/SfM/main_IncrementalSfM.cpp @@ -32,8 +32,8 @@ bool computeIndexFromImageNames( /// List views filenames and find the one that correspond to the user ones: std::vector vec_camImageName; - for (Views::const_iterator it = sfm_data.getViews().begin(); - it != sfm_data.getViews().end(); ++it) + for (Views::const_iterator it = sfm_data.GetViews().begin(); + it != sfm_data.GetViews().end(); ++it) { const View * v = it->second.get(); const std::string filename = stlplus::filename_part(v->s_Img_path); diff --git a/src/software/SfM/main_evalQuality.cpp b/src/software/SfM/main_evalQuality.cpp index c28605467b..257ac843f6 100644 --- a/src/software/SfM/main_evalQuality.cpp +++ b/src/software/SfM/main_evalQuality.cpp @@ -126,7 +126,7 @@ int main(int argc, char **argv) return EXIT_FAILURE; } // Assert that GT and loaded scene have the same camera count - if (map_Cam_gt.size() != sfm_data.getPoses().size()) + if (map_Cam_gt.size() != sfm_data.GetPoses().size()) { std::cerr << std::endl << "There is missing camera in the loaded scene." << std::endl; @@ -134,7 +134,7 @@ int main(int argc, char **argv) } // Prepare data for comparison (corresponding camera centers and rotations) - Poses::const_iterator iter_loaded_poses = sfm_data.getPoses().begin(); + Poses::const_iterator iter_loaded_poses = sfm_data.GetPoses().begin(); std::vector vec_camPosGT, vec_C; std::vector vec_camRotGT, vec_camRot; for(std::map< size_t, PinholeCamera>::const_iterator iterGT = map_Cam_gt.begin(); diff --git a/src/software/SfM/main_exportMatches.cpp b/src/software/SfM/main_exportMatches.cpp index 51b3601225..ae6720a8f4 100644 --- a/src/software/SfM/main_exportMatches.cpp +++ b/src/software/SfM/main_exportMatches.cpp @@ -143,10 +143,10 @@ int main(int argc, char ** argv) const size_t I = iter->first; const size_t J = iter->second; - const View * view_I = sfm_data.getViews().at(I).get(); + const View * view_I = sfm_data.GetViews().at(I).get(); const std::string sView_I= stlplus::create_filespec(sfm_data.s_root_path, view_I->s_Img_path); - const View * view_J = sfm_data.getViews().at(J).get(); + const View * view_J = sfm_data.GetViews().at(J).get(); const std::string sView_J= stlplus::create_filespec(sfm_data.s_root_path, view_J->s_Img_path); diff --git a/src/software/SfM/main_exportTracks.cpp b/src/software/SfM/main_exportTracks.cpp index 513566b721..880e26ff40 100644 --- a/src/software/SfM/main_exportTracks.cpp +++ b/src/software/SfM/main_exportTracks.cpp @@ -114,7 +114,7 @@ int main(int argc, char ** argv) // ------------ // For each pair, export the matches // ------------ - const size_t viewCount = sfm_data.getViews().size(); + const size_t viewCount = sfm_data.GetViews().size(); stlplus::folder_create(sOutDir); std::cout << "\n Export pairwise tracks" << std::endl; @@ -125,10 +125,10 @@ int main(int argc, char ** argv) for (size_t J = I+1; J < viewCount; ++J, ++my_progress_bar) { - const View * view_I = sfm_data.getViews().at(I).get(); + const View * view_I = sfm_data.GetViews().at(I).get(); const std::string sView_I= stlplus::create_filespec(sfm_data.s_root_path, view_I->s_Img_path); - const View * view_J = sfm_data.getViews().at(J).get(); + const View * view_J = sfm_data.GetViews().at(J).get(); const std::string sView_J= stlplus::create_filespec(sfm_data.s_root_path, view_J->s_Img_path); diff --git a/src/software/SfM/main_openMVG2CMPMVS.cpp b/src/software/SfM/main_openMVG2CMPMVS.cpp index e23a49e359..b9a871f492 100644 --- a/src/software/SfM/main_openMVG2CMPMVS.cpp +++ b/src/software/SfM/main_openMVG2CMPMVS.cpp @@ -41,21 +41,22 @@ bool exportToCMPMVSFormat( { // Export data : - C_Progress_display my_progress_bar( sfm_data.getViews().size()*2 ); + C_Progress_display my_progress_bar( sfm_data.GetViews().size()*2 ); // Export valid views as Projective Cameras: size_t count = 0; - for(Views::const_iterator iter = sfm_data.getViews().begin(); - iter != sfm_data.getViews().end(); ++iter, ++my_progress_bar) + for(Views::const_iterator iter = sfm_data.GetViews().begin(); + iter != sfm_data.GetViews().end(); ++iter, ++my_progress_bar) { const View * view = iter->second.get(); if (!sfm_data.IsPoseAndIntrinsicDefined(view)) continue; + const Pose3 pose = sfm_data.GetPoseOrDie(view); + Intrinsics::const_iterator iterIntrinsic = sfm_data.GetIntrinsics().find(view->id_intrinsic); + // We have a valid view with a corresponding camera & pose - Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); - Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); - const Mat34 P = iterIntrinsic->second.get()->get_projective_equivalent(iterPose->second); + const Mat34 P = iterIntrinsic->second.get()->get_projective_equivalent(pose); std::ostringstream os; os << std::setw(5) << std::setfill('0') << count << "_P"; std::ofstream file( @@ -71,15 +72,14 @@ bool exportToCMPMVSFormat( count = 0; std::pair w_h_image_size; Image image, image_ud; - for(Views::const_iterator iter = sfm_data.getViews().begin(); - iter != sfm_data.getViews().end(); ++iter, ++my_progress_bar) + for(Views::const_iterator iter = sfm_data.GetViews().begin(); + iter != sfm_data.GetViews().end(); ++iter, ++my_progress_bar) { const View * view = iter->second.get(); if (!sfm_data.IsPoseAndIntrinsicDefined(view)) continue; - Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); - Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); + Intrinsics::const_iterator iterIntrinsic = sfm_data.GetIntrinsics().find(view->id_intrinsic); // We have a valid view with a corresponding camera & pose const std::string srcImage = stlplus::create_filespec(sfm_data.s_root_path, view->s_Img_path); diff --git a/src/software/SfM/main_openMVG2MESHLAB.cpp b/src/software/SfM/main_openMVG2MESHLAB.cpp index fc125c2ff3..62158d4be3 100644 --- a/src/software/SfM/main_openMVG2MESHLAB.cpp +++ b/src/software/SfM/main_openMVG2MESHLAB.cpp @@ -79,20 +79,20 @@ int main(int argc, char **argv) outfile << " " << outfile.widen('\n'); - for(Views::const_iterator iter = sfm_data.getViews().begin(); - iter != sfm_data.getViews().end(); ++iter) + for(Views::const_iterator iter = sfm_data.GetViews().begin(); + iter != sfm_data.GetViews().end(); ++iter) { const View * view = iter->second.get(); if (!sfm_data.IsPoseAndIntrinsicDefined(view)) continue; - Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); - Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); + const Pose3 pose = sfm_data.GetPoseOrDie(view); + Intrinsics::const_iterator iterIntrinsic = sfm_data.GetIntrinsics().find(view->id_intrinsic); // We have a valid view with a corresponding camera & pose const std::string srcImage = stlplus::create_filespec(sfm_data.s_root_path, view->s_Img_path); const IntrinsicBase * cam = iterIntrinsic->second.get(); - Mat34 P = cam->get_projective_equivalent(iterPose->second); + Mat34 P = cam->get_projective_equivalent(pose); for ( int i = 1; i < 3 ; ++i) for ( int j = 0; j < 4; ++j) diff --git a/src/software/SfM/main_openMVG2PMVS.cpp b/src/software/SfM/main_openMVG2PMVS.cpp index 70cf1e3987..306fa3bb1a 100644 --- a/src/software/SfM/main_openMVG2PMVS.cpp +++ b/src/software/SfM/main_openMVG2PMVS.cpp @@ -53,22 +53,22 @@ bool exportToPMVSFormat( if (bOk) { - C_Progress_display my_progress_bar( sfm_data.getViews().size()*2 ); + C_Progress_display my_progress_bar( sfm_data.GetViews().size()*2 ); // Export valid views as Projective Cameras: size_t count = 0; - for(Views::const_iterator iter = sfm_data.getViews().begin(); - iter != sfm_data.getViews().end(); ++iter, ++my_progress_bar) + for(Views::const_iterator iter = sfm_data.GetViews().begin(); + iter != sfm_data.GetViews().end(); ++iter, ++my_progress_bar) { const View * view = iter->second.get(); if (!sfm_data.IsPoseAndIntrinsicDefined(view)) continue; - Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); - Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); + const Pose3 pose = sfm_data.GetPoseOrDie(view); + Intrinsics::const_iterator iterIntrinsic = sfm_data.GetIntrinsics().find(view->id_intrinsic); // We have a valid view with a corresponding camera & pose - const Mat34 P = iterIntrinsic->second.get()->get_projective_equivalent(iterPose->second); + const Mat34 P = iterIntrinsic->second.get()->get_projective_equivalent(pose); std::ostringstream os; os << std::setw(8) << std::setfill('0') << count; std::ofstream file( @@ -84,15 +84,14 @@ bool exportToPMVSFormat( count = 0; Image image, image_ud; Hash_Map map_viewIdToContiguous; - for(Views::const_iterator iter = sfm_data.getViews().begin(); - iter != sfm_data.getViews().end(); ++iter, ++my_progress_bar) + for(Views::const_iterator iter = sfm_data.GetViews().begin(); + iter != sfm_data.GetViews().end(); ++iter, ++my_progress_bar) { const View * view = iter->second.get(); if (!sfm_data.IsPoseAndIntrinsicDefined(view)) continue; - Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); - Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); + Intrinsics::const_iterator iterIntrinsic = sfm_data.GetIntrinsics().find(view->id_intrinsic); map_viewIdToContiguous[view->id_view] = count; // We have a valid view with a corresponding camera & pose @@ -148,8 +147,8 @@ bool exportToPMVSFormat( { std::map< IndexT, std::set > view_shared; // From the structure observations, list the putatives pairs (symmetric) - for (Landmarks::const_iterator itL = sfm_data.getLandmarks().begin(); - itL != sfm_data.getLandmarks().end(); ++itL) + for (Landmarks::const_iterator itL = sfm_data.GetLandmarks().begin(); + itL != sfm_data.GetLandmarks().end(); ++itL) { const Landmark & landmark = itL->second; const Observations & obs = landmark.obs; @@ -212,8 +211,8 @@ bool exportToBundlerFormat( { // Count the number of valid cameras IndexT validCameraCount = 0; - for(Views::const_iterator iter = sfm_data.getViews().begin(); - iter != sfm_data.getViews().end(); ++iter) + for(Views::const_iterator iter = sfm_data.GetViews().begin(); + iter != sfm_data.GetViews().end(); ++iter) { const View * view = iter->second.get(); if (!sfm_data.IsPoseAndIntrinsicDefined(view)) @@ -224,18 +223,18 @@ bool exportToBundlerFormat( // Fill the "Bundle file" os << "# Bundle file v0.3" << os.widen('\n') - << validCameraCount << " " << sfm_data.getLandmarks().size() << os.widen('\n'); + << validCameraCount << " " << sfm_data.GetLandmarks().size() << os.widen('\n'); // Export camera properties & image filenames - for(Views::const_iterator iter = sfm_data.getViews().begin(); - iter != sfm_data.getViews().end(); ++iter) + for(Views::const_iterator iter = sfm_data.GetViews().begin(); + iter != sfm_data.GetViews().end(); ++iter) { const View * view = iter->second.get(); if (!sfm_data.IsPoseAndIntrinsicDefined(view)) continue; - Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); - Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); + const Pose3 pose = sfm_data.GetPoseOrDie(view); + Intrinsics::const_iterator iterIntrinsic = sfm_data.GetIntrinsics().find(view->id_intrinsic); // Must export focal, k1, k2, R, t @@ -248,8 +247,8 @@ bool exportToBundlerFormat( { const Pinhole_Intrinsic * cam = dynamic_cast(iterIntrinsic->second.get()); const double focal = cam->focal(); - const Mat3 R = D * iterPose->second.rotation(); - const Vec3 t = D * iterPose->second.translation(); + const Mat3 R = D * pose.rotation(); + const Vec3 t = D * pose.translation(); os << focal << " " << k1 << " " << k2 << os.widen('\n') //f k1 k2 << R(0,0) << " " << R(0, 1) << " " << R(0, 2) << os.widen('\n') //R.row(0) @@ -268,8 +267,8 @@ bool exportToBundlerFormat( } // Export structure and visibility IndexT count = 0; - for (Landmarks::const_iterator iter = sfm_data.getLandmarks().begin(); - iter != sfm_data.getLandmarks().end(); ++iter, ++count) + for (Landmarks::const_iterator iter = sfm_data.GetLandmarks().begin(); + iter != sfm_data.GetLandmarks().end(); ++iter, ++count) { const Landmark & landmark = iter->second; const Observations & obs = landmark.obs; diff --git a/src/software/SfMViewer/main.cpp b/src/software/SfMViewer/main.cpp index 8412f1e9f4..306456ceb4 100644 --- a/src/software/SfMViewer/main.cpp +++ b/src/software/SfMViewer/main.cpp @@ -56,7 +56,7 @@ void load_textures() C_Progress_display my_progress_bar( nbCams, std::cout, "\n", " " , "Textures loading, Please wait...\n" ); for ( int i_cam=0; i_cam < nbCams; ++i_cam, ++my_progress_bar) { - const View * view = sfm_data.getViews().at(vec_cameras[i_cam]).get(); + const View * view = sfm_data.GetViews().at(vec_cameras[i_cam]).get(); const std::string srcImage = stlplus::create_filespec(sfm_data.s_root_path, view->s_Img_path); std::vector img; @@ -202,8 +202,8 @@ static void draw(void) glMultMatrixd((GLdouble*)offset_w.data()); // then apply current camera transformation - const View * view = sfm_data.getViews().at(vec_cameras[current_cam]).get(); - const Pose3 pose = sfm_data.getPoses().at(view->id_pose); + const View * view = sfm_data.GetViews().at(vec_cameras[current_cam]).get(); + const Pose3 pose = sfm_data.GetPoseOrDie(view); const openMVG::Mat4 l2w = l2w_Camera(pose.rotation(), pose.translation()); glPushMatrix(); @@ -214,12 +214,12 @@ static void draw(void) glDisable(GL_LIGHTING); //Draw Structure in GREEN (as seen from the current camera) - size_t nbPoint = sfm_data.getLandmarks().size(); + size_t nbPoint = sfm_data.GetLandmarks().size(); size_t cpt = 0; glBegin(GL_POINTS); glColor3f(0.f,1.f,0.f); - for (Landmarks::const_iterator iter = sfm_data.getLandmarks().begin(); - iter != sfm_data.getLandmarks().end(); ++iter) + for (Landmarks::const_iterator iter = sfm_data.GetLandmarks().begin(); + iter != sfm_data.GetLandmarks().end(); ++iter) { const Landmark & landmark = iter->second; glVertex3d(landmark.X(0), landmark.X(1), landmark.X(2)); @@ -230,9 +230,9 @@ static void draw(void) for (int i_cam=0; i_cam < vec_cameras.size(); ++i_cam) { - const View * view = sfm_data.getViews().at(vec_cameras[i_cam]).get(); - const Pose3 pose = sfm_data.getPoses().at(view->id_pose); - const IntrinsicBase * cam = sfm_data.getIntrinsics().at(view->id_intrinsic).get(); + const View * view = sfm_data.GetViews().at(vec_cameras[i_cam]).get(); + const Pose3 pose = sfm_data.GetPoseOrDie(view); + const IntrinsicBase * cam = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); if (isPinhole(cam->getType())) { const Pinhole_Intrinsic * camPinhole = dynamic_cast(cam); @@ -355,8 +355,8 @@ int main(int argc, char *argv[]) { } // List valid camera (view that have a pose & a valid intrinsic data) - for(Views::const_iterator iter = sfm_data.getViews().begin(); - iter != sfm_data.getViews().end(); ++iter) + for(Views::const_iterator iter = sfm_data.GetViews().begin(); + iter != sfm_data.GetViews().end(); ++iter) { const View * view = iter->second.get(); if (!sfm_data.IsPoseAndIntrinsicDefined(view)) diff --git a/src/software/colorHarmonize/colorHarmonizeEngineGlobal.cpp b/src/software/colorHarmonize/colorHarmonizeEngineGlobal.cpp index ccf89ea179..92acbb7adc 100644 --- a/src/software/colorHarmonize/colorHarmonizeEngineGlobal.cpp +++ b/src/software/colorHarmonize/colorHarmonizeEngineGlobal.cpp @@ -1,592 +1,592 @@ - -// Copyright (c) 2013, 2014 openMVG authors. - -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "colorHarmonizeEngineGlobal.hpp" -#include "software/SfM/SfMIOHelper.hpp" - -#include "openMVG/image/image.hpp" -//-- Feature matches -#include -#include "openMVG/matching/indMatch_utils.hpp" -#include "openMVG/stl/stl.hpp" - -#include "openMVG/sfm/sfm.hpp" -#include "openMVG/graph/graph.hpp" - -#include "third_party/stlplus3/filesystemSimplified/file_system.hpp" -#include "third_party/vectorGraphics/svgDrawer.hpp" - -//-- Selection Methods -#include "openMVG/color_harmonization/selection_fullFrame.hpp" -#include "openMVG/color_harmonization/selection_matchedPoints.hpp" -#include "openMVG/color_harmonization/selection_VLDSegment.hpp" - -//-- Color harmonization solver -#include "openMVG/color_harmonization/global_quantile_gain_offset_alignment.hpp" - -#include "openMVG/system/timer.hpp" - -#include "third_party/progress/progress.hpp" - -#include -#include -#include -#include -#include -#include - - -namespace openMVG{ - -using namespace lemon; -using namespace openMVG::matching; -using namespace openMVG::lInfinity; - -typedef SIOPointFeature FeatureT; -typedef vector< FeatureT > featsT; - -ColorHarmonizationEngineGlobal::ColorHarmonizationEngineGlobal( - const string & sSfM_Data_Filename, - const string & sMatchesPath, - const std::string & sMatchesFile, - const string & sOutDirectory, - const int selectionMethod, - const int imgRef): + +// Copyright (c) 2013, 2014 openMVG authors. + +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "colorHarmonizeEngineGlobal.hpp" +#include "software/SfM/SfMIOHelper.hpp" + +#include "openMVG/image/image.hpp" +//-- Feature matches +#include +#include "openMVG/matching/indMatch_utils.hpp" +#include "openMVG/stl/stl.hpp" + +#include "openMVG/sfm/sfm.hpp" +#include "openMVG/graph/graph.hpp" + +#include "third_party/stlplus3/filesystemSimplified/file_system.hpp" +#include "third_party/vectorGraphics/svgDrawer.hpp" + +//-- Selection Methods +#include "openMVG/color_harmonization/selection_fullFrame.hpp" +#include "openMVG/color_harmonization/selection_matchedPoints.hpp" +#include "openMVG/color_harmonization/selection_VLDSegment.hpp" + +//-- Color harmonization solver +#include "openMVG/color_harmonization/global_quantile_gain_offset_alignment.hpp" + +#include "openMVG/system/timer.hpp" + +#include "third_party/progress/progress.hpp" + +#include +#include +#include +#include +#include +#include + + +namespace openMVG{ + +using namespace lemon; +using namespace openMVG::matching; +using namespace openMVG::lInfinity; + +typedef SIOPointFeature FeatureT; +typedef vector< FeatureT > featsT; + +ColorHarmonizationEngineGlobal::ColorHarmonizationEngineGlobal( + const string & sSfM_Data_Filename, + const string & sMatchesPath, + const std::string & sMatchesFile, + const string & sOutDirectory, + const int selectionMethod, + const int imgRef): _sSfM_Data_Path(sSfM_Data_Filename), _sMatchesPath(sMatchesPath), - _sOutDirectory(sOutDirectory), - _selectionMethod( selectionMethod ), - _imgRef( imgRef ), - _sMatchesFile(sMatchesFile) -{ - if( !stlplus::folder_exists( sOutDirectory ) ) - { - stlplus::folder_create( sOutDirectory ); - } -} - -ColorHarmonizationEngineGlobal::~ColorHarmonizationEngineGlobal() -{ -} - -static void pauseProcess() -{ - unsigned char i; - cout << "\nPause : type key and press enter: "; - std::cin >> i; -} - - -bool ColorHarmonizationEngineGlobal::Process() -{ - const std::string vec_selectionMethod[ 3 ] = { "fullFrame", "matchedPoints", "KVLD" }; - const std::string vec_harmonizeMethod[ 1 ] = { "quantifiedGainCompensation" }; - const int harmonizeMethod = 0; - - //------------------- - // Load data - //------------------- - - if( !ReadInputData() ) - return false; - if( _map_Matches.size() == 0 ) - { - cout << endl << "Matches file is empty" << endl; - return false; - } - - //-- Remove EG with poor support: - - for (matching::PairWiseMatches::iterator iter = _map_Matches.begin(); - iter != _map_Matches.end(); - ++iter) - { - if (iter->second.size() < 120) - { - _map_Matches.erase(iter); - iter = _map_Matches.begin(); - } - } - - { - graphUtils::indexedGraph putativeGraph(getPairs(_map_Matches)); - - // Save the graph before cleaning: - graphUtils::exportToGraphvizData( - stlplus::create_filespec(_sOutDirectory, "input_graph_poor_supportRemoved"), - putativeGraph.g); - } - - //------------------- - // Keep the largest CC in the image graph - //------------------- - if (!CleanGraph()) - { - std::cout << std::endl << "There is no largest CC in the graph" << std::endl; - return false; - } - - //------------------- - //-- Color Harmonization - //------------------- - - //Choose image reference - if( _imgRef == -1 ) - { - do - { - cout << "Choose your reference image:\n"; - for( int i = 0; i < _vec_fileNames.size(); ++i ) - { - cout << "id: " << i << "\t" << _vec_fileNames[ i ] << endl; - } - }while( !( cin >> _imgRef ) || _imgRef < 0 || _imgRef >= _vec_fileNames.size() ); - } - - //Choose selection method - if( _selectionMethod == -1 ) - { - cout << "Choose your selection method:\n" - << "- FullFrame: 0\n" - << "- Matched Points: 1\n" - << "- VLD Segment: 2\n"; - while( ! ( cin >> _selectionMethod ) || _selectionMethod < 0 || _selectionMethod > 2 ) - { - cout << _selectionMethod << " is not accepted.\nTo use: \n- FullFrame enter: 0\n- Matched Points enter: 1\n- VLD Segment enter: 2\n"; - } - } - - //------------------- - // Compute remaining camera node Id - //------------------- - - std::map map_cameraNodeToCameraIndex; // graph node Id to 0->Ncam - std::map map_cameraIndexTocameraNode; // 0->Ncam correspondance to graph node Id - std::set set_indeximage; - for (size_t i = 0; i < _map_Matches.size(); ++i) - { - matching::PairWiseMatches::const_iterator iter = _map_Matches.begin(); - std::advance(iter, i); - - const size_t I = iter->first.first; - const size_t J = iter->first.second; - set_indeximage.insert(I); - set_indeximage.insert(J); - } - - for (std::set::const_iterator iterSet = set_indeximage.begin(); - iterSet != set_indeximage.end(); ++iterSet) - { - map_cameraIndexTocameraNode[std::distance(set_indeximage.begin(), iterSet)] = *iterSet; - map_cameraNodeToCameraIndex[*iterSet] = std::distance(set_indeximage.begin(), iterSet); - } - - std::cout << "\n Remaining cameras after CC filter : \n" - << map_cameraIndexTocameraNode.size() << " from a total of " << _vec_fileNames.size() << std::endl; - - size_t bin = 256; - double minvalue = 0.0; - double maxvalue = 255.0; - - // For each edge computes the selection masks and histograms (for the RGB channels) - std::vector map_relativeHistograms[3]; - map_relativeHistograms[0].resize(_map_Matches.size()); - map_relativeHistograms[1].resize(_map_Matches.size()); - map_relativeHistograms[2].resize(_map_Matches.size()); - - for (size_t i = 0; i < _map_Matches.size(); ++i) - { - matching::PairWiseMatches::const_iterator iter = _map_Matches.begin(); - std::advance(iter, i); - - const size_t I = iter->first.first; - const size_t J = iter->first.second; - - const std::vector & vec_matchesInd = iter->second; - - //-- Edges names: - std::pair< std::string, std::string > p_imaNames; - p_imaNames = make_pair( _vec_fileNames[ I ], _vec_fileNames[ J ] ); - std::cout << "Current edge : " - << stlplus::filename_part(p_imaNames.first) << "\t" - << stlplus::filename_part(p_imaNames.second) << std::endl; - - //-- Compute the masks from the data selection: - Image< unsigned char > maskI ( _vec_imageSize[ I ].first, _vec_imageSize[ I ].second ); - Image< unsigned char > maskJ ( _vec_imageSize[ J ].first, _vec_imageSize[ J ].second ); - - switch(_selectionMethod) - { - enum EHistogramSelectionMethod - { - eHistogramHarmonizeFullFrame = 0, - eHistogramHarmonizeMatchedPoints = 1, - eHistogramHarmonizeVLDSegment = 2, - }; - - case eHistogramHarmonizeFullFrame: - { - color_harmonization::commonDataByPair_FullFrame dataSelector( - p_imaNames.first, - p_imaNames.second); - dataSelector.computeMask( maskI, maskJ ); - } - break; - case eHistogramHarmonizeMatchedPoints: - { - int circleSize = 10; - color_harmonization::commonDataByPair_MatchedPoints dataSelector( - p_imaNames.first, - p_imaNames.second, - vec_matchesInd, - _map_feats[ I ], - _map_feats[ J ], - circleSize); - dataSelector.computeMask( maskI, maskJ ); - } - break; - case eHistogramHarmonizeVLDSegment: - { - color_harmonization::commonDataByPair_VLDSegment dataSelector( - p_imaNames.first, - p_imaNames.second, - vec_matchesInd, - _map_feats[ I ], - _map_feats[ J ]); - - dataSelector.computeMask( maskI, maskJ ); - } - break; - default: - std::cout << "Selection method unsupported" << std::endl; - return false; - } - - //-- Export the masks - bool bExportMask = false; - if (bExportMask) - { - string sEdge = _vec_fileNames[ I ] + "_" + _vec_fileNames[ J ]; - sEdge = stlplus::create_filespec( _sOutDirectory, sEdge ); - if( !stlplus::folder_exists( sEdge ) ) - stlplus::folder_create( sEdge ); - - string out_filename_I = "00_mask_I.png"; - out_filename_I = stlplus::create_filespec( sEdge, out_filename_I ); - - string out_filename_J = "00_mask_J.png"; - out_filename_J = stlplus::create_filespec( sEdge, out_filename_J ); - - WriteImage( out_filename_I.c_str(), maskI ); - WriteImage( out_filename_J.c_str(), maskJ ); - } - - //-- Compute the histograms - Image< RGBColor > imageI, imageJ; - ReadImage( p_imaNames.first.c_str(), &imageI ); - ReadImage( p_imaNames.second.c_str(), &imageJ ); - - Histogram< double > histoI( minvalue, maxvalue, bin); - Histogram< double > histoJ( minvalue, maxvalue, bin); - - int channelIndex = 0; // RED channel - color_harmonization::commonDataByPair::computeHisto( histoI, maskI, channelIndex, imageI ); - color_harmonization::commonDataByPair::computeHisto( histoJ, maskJ, channelIndex, imageJ ); - relativeColorHistogramEdge & edgeR = map_relativeHistograms[channelIndex][i]; - edgeR = relativeColorHistogramEdge(map_cameraNodeToCameraIndex[I], map_cameraNodeToCameraIndex[J], - histoI.GetHist(), histoJ.GetHist()); - - histoI = histoJ = Histogram< double >( minvalue, maxvalue, bin); - channelIndex = 1; // GREEN channel - color_harmonization::commonDataByPair::computeHisto( histoI, maskI, channelIndex, imageI ); - color_harmonization::commonDataByPair::computeHisto( histoJ, maskJ, channelIndex, imageJ ); - relativeColorHistogramEdge & edgeG = map_relativeHistograms[channelIndex][i]; - edgeG = relativeColorHistogramEdge(map_cameraNodeToCameraIndex[I], map_cameraNodeToCameraIndex[J], - histoI.GetHist(), histoJ.GetHist()); - - histoI = histoJ = Histogram< double >( minvalue, maxvalue, bin); - channelIndex = 2; // BLUE channel - color_harmonization::commonDataByPair::computeHisto( histoI, maskI, channelIndex, imageI ); - color_harmonization::commonDataByPair::computeHisto( histoJ, maskJ, channelIndex, imageJ ); - relativeColorHistogramEdge & edgeB = map_relativeHistograms[channelIndex][i]; - edgeB = relativeColorHistogramEdge(map_cameraNodeToCameraIndex[I], map_cameraNodeToCameraIndex[J], - histoI.GetHist(), histoJ.GetHist()); - } - - std::cout << "\n -- \n SOLVE for color consistency with linear programming\n --" << std::endl; - //-- Solve for the gains and offsets: - std::vector vec_indexToFix; - vec_indexToFix.push_back(map_cameraNodeToCameraIndex[_imgRef]); - - using namespace openMVG::linearProgramming; - - std::vector vec_solution_r(_vec_fileNames.size() * 2 + 1); - std::vector vec_solution_g(_vec_fileNames.size() * 2 + 1); - std::vector vec_solution_b(_vec_fileNames.size() * 2 + 1); - - openMVG::Timer timer; - - #ifdef OPENMVG_HAVE_MOSEK - typedef MOSEK_SolveWrapper SOLVER_LP_T; - #else - typedef OSI_CLP_SolverWrapper SOLVER_LP_T; - #endif - // Red channel - { - SOLVER_LP_T lpSolver(vec_solution_r.size()); - - ConstraintBuilder_GainOffset cstBuilder(map_relativeHistograms[0], vec_indexToFix); - LP_Constraints_Sparse constraint; - cstBuilder.Build(constraint); - lpSolver.setup(constraint); - lpSolver.solve(); - lpSolver.getSolution(vec_solution_r); - } - // Green channel - { - SOLVER_LP_T lpSolver(vec_solution_g.size()); - - ConstraintBuilder_GainOffset cstBuilder(map_relativeHistograms[1], vec_indexToFix); - LP_Constraints_Sparse constraint; - cstBuilder.Build(constraint); - lpSolver.setup(constraint); - lpSolver.solve(); - lpSolver.getSolution(vec_solution_g); - } - // Blue channel - { - SOLVER_LP_T lpSolver(vec_solution_b.size()); - - ConstraintBuilder_GainOffset cstBuilder(map_relativeHistograms[2], vec_indexToFix); - LP_Constraints_Sparse constraint; - cstBuilder.Build(constraint); - lpSolver.setup(constraint); - lpSolver.solve(); - lpSolver.getSolution(vec_solution_b); - } - - std::cout << std::endl - << " ColorHarmonization solving on a graph with: " << _map_Matches.size() << " edges took (s): " - << timer.elapsed() << std::endl - << "LInfinity fitting error: \n" - << "- for the red channel is: " << vec_solution_r.back() << " gray level(s)" <(std::cout, " ")); - - std::cout << "\n\nFound solution_g:\n"; - std::copy(vec_solution_g.begin(), vec_solution_g.end(), std::ostream_iterator(std::cout, " ")); - - std::cout << "\n\nFound solution_b:\n"; - std::copy(vec_solution_b.begin(), vec_solution_b.end(), std::ostream_iterator(std::cout, " ")); - std::cout << std::endl; - - std::cout << "\n\nThere is :\n" << set_indeximage.size() << " images to transform." << std::endl; - - //-> convert solution to gain offset and creation of the LUT per image - C_Progress_display my_progress_bar( set_indeximage.size() ); - for (std::set::const_iterator iterSet = set_indeximage.begin(); - iterSet != set_indeximage.end(); ++iterSet, ++my_progress_bar) - { - size_t imaNum = *iterSet; - typedef Eigen::Matrix Vec256; - std::vector< Vec256 > vec_map_lut(3); - - size_t nodeIndex = std::distance(set_indeximage.begin(), iterSet); - - double g_r = vec_solution_r[nodeIndex*2]; - double offset_r = vec_solution_r[nodeIndex*2+1]; - double g_g = vec_solution_g[nodeIndex*2]; - double offset_g = vec_solution_g[nodeIndex*2+1]; - double g_b = vec_solution_b[nodeIndex*2]; - double offset_b = vec_solution_b[nodeIndex*2+1]; - - for( size_t k = 0; k < 256; ++k) - { - vec_map_lut[0][k] = clamp( k * g_r + offset_r, 0., 255. ); - vec_map_lut[1][k] = clamp( k * g_g + offset_g, 0., 255. ); - vec_map_lut[2][k] = clamp( k * g_b + offset_b, 0., 255. ); - } - - Image< RGBColor > image_c; - ReadImage( _vec_fileNames[ imaNum ].c_str(), &image_c ); - -#ifdef OPENMVG_USE_OPENMP -#pragma omp parallel for -#endif - for( int j = 0; j < image_c.Height(); ++j ) - { - for( int i = 0; i < image_c.Width(); ++i ) - { - image_c(j, i)[0] = clamp(vec_map_lut[0][image_c(j, i)[0]], 0., 255.); - image_c(j, i)[1] = clamp(vec_map_lut[1][image_c(j, i)[1]], 0., 255.); - image_c(j, i)[2] = clamp(vec_map_lut[2][image_c(j, i)[2]], 0., 255.); - } - } - - std::string out_folder = stlplus::create_filespec( _sOutDirectory, - vec_selectionMethod[ _selectionMethod ] + "_" + vec_harmonizeMethod[ harmonizeMethod ]); - if( !stlplus::folder_exists( out_folder ) ) - stlplus::folder_create( out_folder ); - std::string out_filename = stlplus::create_filespec( out_folder, _vec_fileNames[ imaNum ] ); - - WriteImage( out_filename.c_str(), image_c ); - } - return true; -} - -bool ColorHarmonizationEngineGlobal::ReadInputData() -{ - if( !stlplus::is_folder( _sMatchesPath) || - !stlplus::is_folder( _sOutDirectory) ) - { - cerr << endl - << "One of the required directory is not a valid directory" << endl; - return false; - } - - if( !stlplus::is_file( _sSfM_Data_Path ) || - !stlplus::is_file( _sMatchesFile ) ) - { - cerr << endl - << "One of the input required file is not a present (sfm_data.X," - << stlplus::basename_part(_sMatchesFile) << ")" << endl; - return false; - } - - // a. Read input scenes views - SfM_Data sfm_data; - if (!Load(sfm_data, _sSfM_Data_Path, ESfM_Data(VIEWS))) { - std::cerr << std::endl - << "The input file \""<< _sSfM_Data_Path << "\" cannot be read" << std::endl; - return false; - } - - // Read images names - for (Views::const_iterator iter = sfm_data.getViews().begin(); - iter != sfm_data.getViews().end(); ++iter) - { - const View * v = iter->second.get(); - _vec_fileNames.push_back( stlplus::create_filespec(sfm_data.s_root_path, v->s_Img_path)); - _vec_imageSize.push_back( std::make_pair( v->ui_width, v->ui_height )); - } - - // b. Read matches - if( !matching::PairedIndMatchImport( _sMatchesFile, _map_Matches ) ) - { - cerr<< "Unable to read the geometric matrix matches" << endl; - return false; - } - - // Read features: - for( size_t i = 0; i < _vec_fileNames.size(); ++i ) - { - const size_t camIndex = i; - if( !loadFeatsFromFile( - stlplus::create_filespec( _sMatchesPath, - stlplus::basename_part( _vec_fileNames[ camIndex ] ), - ".feat" ), - _map_feats[ camIndex ] ) ) - { - cerr << "Bad reading of feature files" << endl; - return false; - } - } - - graphUtils::indexedGraph putativeGraph(getPairs(_map_Matches)); - - // Save the graph before cleaning: - graphUtils::exportToGraphvizData( - stlplus::create_filespec( _sOutDirectory, "initialGraph" ), - putativeGraph.g ); - - return true; -} - -bool ColorHarmonizationEngineGlobal::CleanGraph() -{ - // Create a graph from pairwise correspondences: - // - keep the largest connected component. - - graphUtils::indexedGraph putativeGraph(getPairs(_map_Matches)); - - // Save the graph before cleaning: - graphUtils::exportToGraphvizData( - stlplus::create_filespec(_sOutDirectory, "initialGraph"), - putativeGraph.g); - - const int connectedComponentCount = lemon::countConnectedComponents(putativeGraph.g); - std::cout << "\n" - << "ColorHarmonizationEngineGlobal::CleanGraph() :: => connected Component cardinal: " - << connectedComponentCount << std::endl; - - if (connectedComponentCount > 1) // If more than one CC, keep the largest - { - // Search the largest CC index - const std::map > map_subgraphs = - openMVG::graphUtils::exportGraphToMapSubgraphs(putativeGraph.g); - size_t count = std::numeric_limits::min(); - std::map >::const_iterator iterLargestCC = map_subgraphs.end(); - for(std::map >::const_iterator iter = map_subgraphs.begin(); - iter != map_subgraphs.end(); ++iter) - { - if (iter->second.size() > count) { - count = iter->second.size(); - iterLargestCC = iter; - } - std::cout << "Connected component of size : " << iter->second.size() << std::endl; - } - - //-- Remove all nodes that are not listed in the largest CC - for(std::map >::const_iterator iter = map_subgraphs.begin(); - iter != map_subgraphs.end(); ++iter) - { - if (iter == iterLargestCC) // Skip this CC since it's the one we want to keep - continue; - - const std::set & ccSet = iter->second; - for (std::set::const_iterator iter2 = ccSet.begin(); - iter2 != ccSet.end(); ++iter2) - { - // Remove all outgoing edges - for (lemon::ListGraph::OutArcIt e(putativeGraph.g, *iter2); e!=INVALID; ++e) - { - putativeGraph.g.erase(e); - const IndexT Idu = (*putativeGraph.map_nodeMapIndex)[putativeGraph.g.target(e)]; - const IndexT Idv = (*putativeGraph.map_nodeMapIndex)[putativeGraph.g.source(e)]; - matching::PairWiseMatches::iterator iterM = _map_Matches.find(std::make_pair(Idu,Idv)); - if( iterM != _map_Matches.end()) - { - _map_Matches.erase(iterM); - } - else // Try to find the opposite directed edge - { - iterM = _map_Matches.find(std::make_pair(Idv,Idu)); - if( iterM != _map_Matches.end()) - _map_Matches.erase(iterM); - } - } - } - } - } - - // Save the graph after cleaning: - graphUtils::exportToGraphvizData( - stlplus::create_filespec(_sOutDirectory, "cleanedGraph"), - putativeGraph.g); - - std::cout << "\n" - << "Cardinal of nodes: " << lemon::countNodes(putativeGraph.g) << "\n" - << "Cardinal of edges: " << lemon::countEdges(putativeGraph.g) << std::endl - << std::endl; - - return true; -} - -} // namespace openMVG + _sOutDirectory(sOutDirectory), + _selectionMethod( selectionMethod ), + _imgRef( imgRef ), + _sMatchesFile(sMatchesFile) +{ + if( !stlplus::folder_exists( sOutDirectory ) ) + { + stlplus::folder_create( sOutDirectory ); + } +} + +ColorHarmonizationEngineGlobal::~ColorHarmonizationEngineGlobal() +{ +} + +static void pauseProcess() +{ + unsigned char i; + cout << "\nPause : type key and press enter: "; + std::cin >> i; +} + + +bool ColorHarmonizationEngineGlobal::Process() +{ + const std::string vec_selectionMethod[ 3 ] = { "fullFrame", "matchedPoints", "KVLD" }; + const std::string vec_harmonizeMethod[ 1 ] = { "quantifiedGainCompensation" }; + const int harmonizeMethod = 0; + + //------------------- + // Load data + //------------------- + + if( !ReadInputData() ) + return false; + if( _map_Matches.size() == 0 ) + { + cout << endl << "Matches file is empty" << endl; + return false; + } + + //-- Remove EG with poor support: + + for (matching::PairWiseMatches::iterator iter = _map_Matches.begin(); + iter != _map_Matches.end(); + ++iter) + { + if (iter->second.size() < 120) + { + _map_Matches.erase(iter); + iter = _map_Matches.begin(); + } + } + + { + graphUtils::indexedGraph putativeGraph(getPairs(_map_Matches)); + + // Save the graph before cleaning: + graphUtils::exportToGraphvizData( + stlplus::create_filespec(_sOutDirectory, "input_graph_poor_supportRemoved"), + putativeGraph.g); + } + + //------------------- + // Keep the largest CC in the image graph + //------------------- + if (!CleanGraph()) + { + std::cout << std::endl << "There is no largest CC in the graph" << std::endl; + return false; + } + + //------------------- + //-- Color Harmonization + //------------------- + + //Choose image reference + if( _imgRef == -1 ) + { + do + { + cout << "Choose your reference image:\n"; + for( int i = 0; i < _vec_fileNames.size(); ++i ) + { + cout << "id: " << i << "\t" << _vec_fileNames[ i ] << endl; + } + }while( !( cin >> _imgRef ) || _imgRef < 0 || _imgRef >= _vec_fileNames.size() ); + } + + //Choose selection method + if( _selectionMethod == -1 ) + { + cout << "Choose your selection method:\n" + << "- FullFrame: 0\n" + << "- Matched Points: 1\n" + << "- VLD Segment: 2\n"; + while( ! ( cin >> _selectionMethod ) || _selectionMethod < 0 || _selectionMethod > 2 ) + { + cout << _selectionMethod << " is not accepted.\nTo use: \n- FullFrame enter: 0\n- Matched Points enter: 1\n- VLD Segment enter: 2\n"; + } + } + + //------------------- + // Compute remaining camera node Id + //------------------- + + std::map map_cameraNodeToCameraIndex; // graph node Id to 0->Ncam + std::map map_cameraIndexTocameraNode; // 0->Ncam correspondance to graph node Id + std::set set_indeximage; + for (size_t i = 0; i < _map_Matches.size(); ++i) + { + matching::PairWiseMatches::const_iterator iter = _map_Matches.begin(); + std::advance(iter, i); + + const size_t I = iter->first.first; + const size_t J = iter->first.second; + set_indeximage.insert(I); + set_indeximage.insert(J); + } + + for (std::set::const_iterator iterSet = set_indeximage.begin(); + iterSet != set_indeximage.end(); ++iterSet) + { + map_cameraIndexTocameraNode[std::distance(set_indeximage.begin(), iterSet)] = *iterSet; + map_cameraNodeToCameraIndex[*iterSet] = std::distance(set_indeximage.begin(), iterSet); + } + + std::cout << "\n Remaining cameras after CC filter : \n" + << map_cameraIndexTocameraNode.size() << " from a total of " << _vec_fileNames.size() << std::endl; + + size_t bin = 256; + double minvalue = 0.0; + double maxvalue = 255.0; + + // For each edge computes the selection masks and histograms (for the RGB channels) + std::vector map_relativeHistograms[3]; + map_relativeHistograms[0].resize(_map_Matches.size()); + map_relativeHistograms[1].resize(_map_Matches.size()); + map_relativeHistograms[2].resize(_map_Matches.size()); + + for (size_t i = 0; i < _map_Matches.size(); ++i) + { + matching::PairWiseMatches::const_iterator iter = _map_Matches.begin(); + std::advance(iter, i); + + const size_t I = iter->first.first; + const size_t J = iter->first.second; + + const std::vector & vec_matchesInd = iter->second; + + //-- Edges names: + std::pair< std::string, std::string > p_imaNames; + p_imaNames = make_pair( _vec_fileNames[ I ], _vec_fileNames[ J ] ); + std::cout << "Current edge : " + << stlplus::filename_part(p_imaNames.first) << "\t" + << stlplus::filename_part(p_imaNames.second) << std::endl; + + //-- Compute the masks from the data selection: + Image< unsigned char > maskI ( _vec_imageSize[ I ].first, _vec_imageSize[ I ].second ); + Image< unsigned char > maskJ ( _vec_imageSize[ J ].first, _vec_imageSize[ J ].second ); + + switch(_selectionMethod) + { + enum EHistogramSelectionMethod + { + eHistogramHarmonizeFullFrame = 0, + eHistogramHarmonizeMatchedPoints = 1, + eHistogramHarmonizeVLDSegment = 2, + }; + + case eHistogramHarmonizeFullFrame: + { + color_harmonization::commonDataByPair_FullFrame dataSelector( + p_imaNames.first, + p_imaNames.second); + dataSelector.computeMask( maskI, maskJ ); + } + break; + case eHistogramHarmonizeMatchedPoints: + { + int circleSize = 10; + color_harmonization::commonDataByPair_MatchedPoints dataSelector( + p_imaNames.first, + p_imaNames.second, + vec_matchesInd, + _map_feats[ I ], + _map_feats[ J ], + circleSize); + dataSelector.computeMask( maskI, maskJ ); + } + break; + case eHistogramHarmonizeVLDSegment: + { + color_harmonization::commonDataByPair_VLDSegment dataSelector( + p_imaNames.first, + p_imaNames.second, + vec_matchesInd, + _map_feats[ I ], + _map_feats[ J ]); + + dataSelector.computeMask( maskI, maskJ ); + } + break; + default: + std::cout << "Selection method unsupported" << std::endl; + return false; + } + + //-- Export the masks + bool bExportMask = false; + if (bExportMask) + { + string sEdge = _vec_fileNames[ I ] + "_" + _vec_fileNames[ J ]; + sEdge = stlplus::create_filespec( _sOutDirectory, sEdge ); + if( !stlplus::folder_exists( sEdge ) ) + stlplus::folder_create( sEdge ); + + string out_filename_I = "00_mask_I.png"; + out_filename_I = stlplus::create_filespec( sEdge, out_filename_I ); + + string out_filename_J = "00_mask_J.png"; + out_filename_J = stlplus::create_filespec( sEdge, out_filename_J ); + + WriteImage( out_filename_I.c_str(), maskI ); + WriteImage( out_filename_J.c_str(), maskJ ); + } + + //-- Compute the histograms + Image< RGBColor > imageI, imageJ; + ReadImage( p_imaNames.first.c_str(), &imageI ); + ReadImage( p_imaNames.second.c_str(), &imageJ ); + + Histogram< double > histoI( minvalue, maxvalue, bin); + Histogram< double > histoJ( minvalue, maxvalue, bin); + + int channelIndex = 0; // RED channel + color_harmonization::commonDataByPair::computeHisto( histoI, maskI, channelIndex, imageI ); + color_harmonization::commonDataByPair::computeHisto( histoJ, maskJ, channelIndex, imageJ ); + relativeColorHistogramEdge & edgeR = map_relativeHistograms[channelIndex][i]; + edgeR = relativeColorHistogramEdge(map_cameraNodeToCameraIndex[I], map_cameraNodeToCameraIndex[J], + histoI.GetHist(), histoJ.GetHist()); + + histoI = histoJ = Histogram< double >( minvalue, maxvalue, bin); + channelIndex = 1; // GREEN channel + color_harmonization::commonDataByPair::computeHisto( histoI, maskI, channelIndex, imageI ); + color_harmonization::commonDataByPair::computeHisto( histoJ, maskJ, channelIndex, imageJ ); + relativeColorHistogramEdge & edgeG = map_relativeHistograms[channelIndex][i]; + edgeG = relativeColorHistogramEdge(map_cameraNodeToCameraIndex[I], map_cameraNodeToCameraIndex[J], + histoI.GetHist(), histoJ.GetHist()); + + histoI = histoJ = Histogram< double >( minvalue, maxvalue, bin); + channelIndex = 2; // BLUE channel + color_harmonization::commonDataByPair::computeHisto( histoI, maskI, channelIndex, imageI ); + color_harmonization::commonDataByPair::computeHisto( histoJ, maskJ, channelIndex, imageJ ); + relativeColorHistogramEdge & edgeB = map_relativeHistograms[channelIndex][i]; + edgeB = relativeColorHistogramEdge(map_cameraNodeToCameraIndex[I], map_cameraNodeToCameraIndex[J], + histoI.GetHist(), histoJ.GetHist()); + } + + std::cout << "\n -- \n SOLVE for color consistency with linear programming\n --" << std::endl; + //-- Solve for the gains and offsets: + std::vector vec_indexToFix; + vec_indexToFix.push_back(map_cameraNodeToCameraIndex[_imgRef]); + + using namespace openMVG::linearProgramming; + + std::vector vec_solution_r(_vec_fileNames.size() * 2 + 1); + std::vector vec_solution_g(_vec_fileNames.size() * 2 + 1); + std::vector vec_solution_b(_vec_fileNames.size() * 2 + 1); + + openMVG::Timer timer; + + #ifdef OPENMVG_HAVE_MOSEK + typedef MOSEK_SolveWrapper SOLVER_LP_T; + #else + typedef OSI_CLP_SolverWrapper SOLVER_LP_T; + #endif + // Red channel + { + SOLVER_LP_T lpSolver(vec_solution_r.size()); + + ConstraintBuilder_GainOffset cstBuilder(map_relativeHistograms[0], vec_indexToFix); + LP_Constraints_Sparse constraint; + cstBuilder.Build(constraint); + lpSolver.setup(constraint); + lpSolver.solve(); + lpSolver.getSolution(vec_solution_r); + } + // Green channel + { + SOLVER_LP_T lpSolver(vec_solution_g.size()); + + ConstraintBuilder_GainOffset cstBuilder(map_relativeHistograms[1], vec_indexToFix); + LP_Constraints_Sparse constraint; + cstBuilder.Build(constraint); + lpSolver.setup(constraint); + lpSolver.solve(); + lpSolver.getSolution(vec_solution_g); + } + // Blue channel + { + SOLVER_LP_T lpSolver(vec_solution_b.size()); + + ConstraintBuilder_GainOffset cstBuilder(map_relativeHistograms[2], vec_indexToFix); + LP_Constraints_Sparse constraint; + cstBuilder.Build(constraint); + lpSolver.setup(constraint); + lpSolver.solve(); + lpSolver.getSolution(vec_solution_b); + } + + std::cout << std::endl + << " ColorHarmonization solving on a graph with: " << _map_Matches.size() << " edges took (s): " + << timer.elapsed() << std::endl + << "LInfinity fitting error: \n" + << "- for the red channel is: " << vec_solution_r.back() << " gray level(s)" <(std::cout, " ")); + + std::cout << "\n\nFound solution_g:\n"; + std::copy(vec_solution_g.begin(), vec_solution_g.end(), std::ostream_iterator(std::cout, " ")); + + std::cout << "\n\nFound solution_b:\n"; + std::copy(vec_solution_b.begin(), vec_solution_b.end(), std::ostream_iterator(std::cout, " ")); + std::cout << std::endl; + + std::cout << "\n\nThere is :\n" << set_indeximage.size() << " images to transform." << std::endl; + + //-> convert solution to gain offset and creation of the LUT per image + C_Progress_display my_progress_bar( set_indeximage.size() ); + for (std::set::const_iterator iterSet = set_indeximage.begin(); + iterSet != set_indeximage.end(); ++iterSet, ++my_progress_bar) + { + size_t imaNum = *iterSet; + typedef Eigen::Matrix Vec256; + std::vector< Vec256 > vec_map_lut(3); + + size_t nodeIndex = std::distance(set_indeximage.begin(), iterSet); + + double g_r = vec_solution_r[nodeIndex*2]; + double offset_r = vec_solution_r[nodeIndex*2+1]; + double g_g = vec_solution_g[nodeIndex*2]; + double offset_g = vec_solution_g[nodeIndex*2+1]; + double g_b = vec_solution_b[nodeIndex*2]; + double offset_b = vec_solution_b[nodeIndex*2+1]; + + for( size_t k = 0; k < 256; ++k) + { + vec_map_lut[0][k] = clamp( k * g_r + offset_r, 0., 255. ); + vec_map_lut[1][k] = clamp( k * g_g + offset_g, 0., 255. ); + vec_map_lut[2][k] = clamp( k * g_b + offset_b, 0., 255. ); + } + + Image< RGBColor > image_c; + ReadImage( _vec_fileNames[ imaNum ].c_str(), &image_c ); + +#ifdef OPENMVG_USE_OPENMP +#pragma omp parallel for +#endif + for( int j = 0; j < image_c.Height(); ++j ) + { + for( int i = 0; i < image_c.Width(); ++i ) + { + image_c(j, i)[0] = clamp(vec_map_lut[0][image_c(j, i)[0]], 0., 255.); + image_c(j, i)[1] = clamp(vec_map_lut[1][image_c(j, i)[1]], 0., 255.); + image_c(j, i)[2] = clamp(vec_map_lut[2][image_c(j, i)[2]], 0., 255.); + } + } + + std::string out_folder = stlplus::create_filespec( _sOutDirectory, + vec_selectionMethod[ _selectionMethod ] + "_" + vec_harmonizeMethod[ harmonizeMethod ]); + if( !stlplus::folder_exists( out_folder ) ) + stlplus::folder_create( out_folder ); + std::string out_filename = stlplus::create_filespec( out_folder, _vec_fileNames[ imaNum ] ); + + WriteImage( out_filename.c_str(), image_c ); + } + return true; +} + +bool ColorHarmonizationEngineGlobal::ReadInputData() +{ + if( !stlplus::is_folder( _sMatchesPath) || + !stlplus::is_folder( _sOutDirectory) ) + { + cerr << endl + << "One of the required directory is not a valid directory" << endl; + return false; + } + + if( !stlplus::is_file( _sSfM_Data_Path ) || + !stlplus::is_file( _sMatchesFile ) ) + { + cerr << endl + << "One of the input required file is not a present (sfm_data.X," + << stlplus::basename_part(_sMatchesFile) << ")" << endl; + return false; + } + + // a. Read input scenes views + SfM_Data sfm_data; + if (!Load(sfm_data, _sSfM_Data_Path, ESfM_Data(VIEWS))) { + std::cerr << std::endl + << "The input file \""<< _sSfM_Data_Path << "\" cannot be read" << std::endl; + return false; + } + + // Read images names + for (Views::const_iterator iter = sfm_data.GetViews().begin(); + iter != sfm_data.GetViews().end(); ++iter) + { + const View * v = iter->second.get(); + _vec_fileNames.push_back( stlplus::create_filespec(sfm_data.s_root_path, v->s_Img_path)); + _vec_imageSize.push_back( std::make_pair( v->ui_width, v->ui_height )); + } + + // b. Read matches + if( !matching::PairedIndMatchImport( _sMatchesFile, _map_Matches ) ) + { + cerr<< "Unable to read the geometric matrix matches" << endl; + return false; + } + + // Read features: + for( size_t i = 0; i < _vec_fileNames.size(); ++i ) + { + const size_t camIndex = i; + if( !loadFeatsFromFile( + stlplus::create_filespec( _sMatchesPath, + stlplus::basename_part( _vec_fileNames[ camIndex ] ), + ".feat" ), + _map_feats[ camIndex ] ) ) + { + cerr << "Bad reading of feature files" << endl; + return false; + } + } + + graphUtils::indexedGraph putativeGraph(getPairs(_map_Matches)); + + // Save the graph before cleaning: + graphUtils::exportToGraphvizData( + stlplus::create_filespec( _sOutDirectory, "initialGraph" ), + putativeGraph.g ); + + return true; +} + +bool ColorHarmonizationEngineGlobal::CleanGraph() +{ + // Create a graph from pairwise correspondences: + // - keep the largest connected component. + + graphUtils::indexedGraph putativeGraph(getPairs(_map_Matches)); + + // Save the graph before cleaning: + graphUtils::exportToGraphvizData( + stlplus::create_filespec(_sOutDirectory, "initialGraph"), + putativeGraph.g); + + const int connectedComponentCount = lemon::countConnectedComponents(putativeGraph.g); + std::cout << "\n" + << "ColorHarmonizationEngineGlobal::CleanGraph() :: => connected Component cardinal: " + << connectedComponentCount << std::endl; + + if (connectedComponentCount > 1) // If more than one CC, keep the largest + { + // Search the largest CC index + const std::map > map_subgraphs = + openMVG::graphUtils::exportGraphToMapSubgraphs(putativeGraph.g); + size_t count = std::numeric_limits::min(); + std::map >::const_iterator iterLargestCC = map_subgraphs.end(); + for(std::map >::const_iterator iter = map_subgraphs.begin(); + iter != map_subgraphs.end(); ++iter) + { + if (iter->second.size() > count) { + count = iter->second.size(); + iterLargestCC = iter; + } + std::cout << "Connected component of size : " << iter->second.size() << std::endl; + } + + //-- Remove all nodes that are not listed in the largest CC + for(std::map >::const_iterator iter = map_subgraphs.begin(); + iter != map_subgraphs.end(); ++iter) + { + if (iter == iterLargestCC) // Skip this CC since it's the one we want to keep + continue; + + const std::set & ccSet = iter->second; + for (std::set::const_iterator iter2 = ccSet.begin(); + iter2 != ccSet.end(); ++iter2) + { + // Remove all outgoing edges + for (lemon::ListGraph::OutArcIt e(putativeGraph.g, *iter2); e!=INVALID; ++e) + { + putativeGraph.g.erase(e); + const IndexT Idu = (*putativeGraph.map_nodeMapIndex)[putativeGraph.g.target(e)]; + const IndexT Idv = (*putativeGraph.map_nodeMapIndex)[putativeGraph.g.source(e)]; + matching::PairWiseMatches::iterator iterM = _map_Matches.find(std::make_pair(Idu,Idv)); + if( iterM != _map_Matches.end()) + { + _map_Matches.erase(iterM); + } + else // Try to find the opposite directed edge + { + iterM = _map_Matches.find(std::make_pair(Idv,Idu)); + if( iterM != _map_Matches.end()) + _map_Matches.erase(iterM); + } + } + } + } + } + + // Save the graph after cleaning: + graphUtils::exportToGraphvizData( + stlplus::create_filespec(_sOutDirectory, "cleanedGraph"), + putativeGraph.g); + + std::cout << "\n" + << "Cardinal of nodes: " << lemon::countNodes(putativeGraph.g) << "\n" + << "Cardinal of edges: " << lemon::countEdges(putativeGraph.g) << std::endl + << std::endl; + + return true; +} + +} // namespace openMVG From 2dd98cf47d86bcafe253fead785784b15ce046e9 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Mon, 18 May 2015 15:40:54 +0200 Subject: [PATCH 08/52] Fix a bug in L2 translation averaging in case of missing view index. #297 --- .../GlobalSfM_translation_averaging.cpp | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp b/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp index 7106c52b19..7d25149efb 100644 --- a/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp +++ b/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp @@ -96,12 +96,13 @@ bool GlobalSfM_Translation_AveragingSolver::Translation_averaging( return false; } //-- Update initial estimates from [minId,maxId] to range [0->Ncam] - const Pair_Set pairs = getPairs(vec_initialRijTijEstimates); + RelativeInfo_Vec vec_initialRijTijEstimates_cpy = vec_initialRijTijEstimates; + const Pair_Set pairs = getPairs(vec_initialRijTijEstimates_cpy); Hash_Map _reindexForward, _reindexBackward; openMVG::reindex(pairs, _reindexForward, _reindexBackward); - for(size_t i = 0; i < vec_initialRijTijEstimates.size(); ++i) + for(size_t i = 0; i < vec_initialRijTijEstimates_cpy.size(); ++i) { - openMVG::relativeInfo & rel = vec_initialRijTijEstimates[i]; + openMVG::relativeInfo & rel = vec_initialRijTijEstimates_cpy[i]; rel.first = Pair(_reindexForward[rel.first.first], _reindexForward[rel.first.second]); } @@ -114,7 +115,7 @@ bool GlobalSfM_Translation_AveragingSolver::Translation_averaging( double gamma = -1.0; std::vector vec_solution; { - vec_solution.resize(iNview*3 + vec_initialRijTijEstimates.size()/3 + 1); + vec_solution.resize(iNview*3 + vec_initialRijTijEstimates_cpy.size()/3 + 1); using namespace openMVG::linearProgramming; #ifdef OPENMVG_HAVE_MOSEK MOSEK_SolveWrapper solverLP(vec_solution.size()); @@ -122,7 +123,7 @@ bool GlobalSfM_Translation_AveragingSolver::Translation_averaging( OSI_CLP_SolverWrapper solverLP(vec_solution.size()); #endif - lInfinityCV::Tifromtij_ConstraintBuilder_OneLambdaPerTrif cstBuilder(vec_initialRijTijEstimates); + lInfinityCV::Tifromtij_ConstraintBuilder_OneLambdaPerTrif cstBuilder(vec_initialRijTijEstimates_cpy); LP_Constraints_Sparse constraint; //-- Setup constraint and solver @@ -152,15 +153,11 @@ bool GlobalSfM_Translation_AveragingSolver::Translation_averaging( os << "Translation fusion statistics."; os.str(""); os << "-------------------------------" << "\n" - << "-- #relative estimates: " << vec_initialRijTijEstimates.size() + << "-- #relative estimates: " << vec_initialRijTijEstimates_cpy.size() << " converge with gamma: " << gamma << ".\n" << " timing (s): " << timeLP_translation << ".\n" << "-------------------------------" << "\n"; std::cout << os.str() << std::endl; - //using namespace htmlDocument; - //_htmlDocStream->pushInfo("
"); - //_htmlDocStream->pushInfo(htmlMarkup("h1",os.str())); - //_htmlDocStream->pushInfo(os.str()); } std::cout << "Found solution:\n"; @@ -169,7 +166,7 @@ bool GlobalSfM_Translation_AveragingSolver::Translation_averaging( std::vector vec_camTranslation(iNview*3,0); std::copy(&vec_solution[0], &vec_solution[iNview*3], &vec_camTranslation[0]); - std::vector vec_camRelLambdas(&vec_solution[iNview*3], &vec_solution[iNview*3 + vec_initialRijTijEstimates.size()/3]); + std::vector vec_camRelLambdas(&vec_solution[iNview*3], &vec_solution[iNview*3 + vec_initialRijTijEstimates_cpy.size()/3]); std::cout << "\ncam position: " << std::endl; std::copy(vec_camTranslation.begin(), vec_camTranslation.end(), std::ostream_iterator(std::cout, " ")); std::cout << "\ncam Lambdas: " << std::endl; @@ -191,18 +188,22 @@ bool GlobalSfM_Translation_AveragingSolver::Translation_averaging( case TRANSLATION_AVERAGING_L2: { std::vector vec_edges; - vec_edges.reserve(vec_initialRijTijEstimates.size() * 2); + vec_edges.reserve(vec_initialRijTijEstimates_cpy.size() * 2); std::vector vec_poses; - vec_poses.reserve(vec_initialRijTijEstimates.size() * 3); + vec_poses.reserve(vec_initialRijTijEstimates_cpy.size() * 3); std::vector vec_weights; - vec_weights.reserve(vec_initialRijTijEstimates.size()); + vec_weights.reserve(vec_initialRijTijEstimates_cpy.size()); - for(int i=0; i < vec_initialRijTijEstimates.size(); ++i) + for(int i=0; i < vec_initialRijTijEstimates_cpy.size(); ++i) { - const openMVG::relativeInfo & rel = vec_initialRijTijEstimates[i]; + const openMVG::relativeInfo & rel = vec_initialRijTijEstimates_cpy[i]; vec_edges.push_back(rel.first.first); vec_edges.push_back(rel.first.second); - const Mat3 Ri = map_globalR.at(rel.first.second); + // Since index have been remapped + // (use the backward indexing to retrieve the second global rotation) + const IndexT secondId = _reindexBackward[rel.first.second]; + const View * view = sfm_data.views.at(secondId).get(); + const Mat3 & Ri = map_globalR.at(view->id_pose); const Vec3 direction = -(Ri.transpose() * rel.second.second.normalized()); vec_poses.push_back(direction(0)); @@ -222,7 +223,7 @@ bool GlobalSfM_Translation_AveragingSolver::Translation_averaging( &vec_edges[0], &vec_poses[0], &vec_weights[0], - vec_initialRijTijEstimates.size(), + vec_initialRijTijEstimates_cpy.size(), loss_width, &X[0], function_tolerance, @@ -237,8 +238,8 @@ bool GlobalSfM_Translation_AveragingSolver::Translation_averaging( { const Vec3 C(X[i*3], X[i*3+1], X[i*3+2]); const IndexT camNodeId = _reindexBackward[i]; // undo the reindexing - const View * view = sfm_data.views[camNodeId].get(); - const Mat3 & Ri = map_globalR.find(view->id_pose)->second; + const View * view = sfm_data.views.at(camNodeId).get(); + const Mat3 & Ri = map_globalR.at(view->id_pose); sfm_data.poses[view->id_pose] = Pose3(Ri, C); } } From e49ebff6c5acf814c10d2342286ed4bb2d1b5cd6 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Tue, 19 May 2015 16:44:32 +0200 Subject: [PATCH 09/52] [Image] Move openMVG/image to namespace openMVG::image. #300 --- .../main_computeMatchesCasHas.cpp | 1 + src/nonFree/sift/SIFT_describer.hpp | 8 ++--- .../selection_VLDSegment.hpp | 14 ++++----- .../selection_fullFrame.hpp | 6 ++-- .../selection_interface.hpp | 6 ++-- .../selection_matchedPoints.hpp | 6 ++-- src/openMVG/features/akaze/AKAZE.cpp | 2 ++ src/openMVG/features/akaze/AKAZE.hpp | 24 +++++++------- .../features/akaze/mldb_descriptor.hpp | 6 ++-- src/openMVG/features/image_describer.hpp | 4 +-- .../features/image_describer_akaze.hpp | 11 +++---- src/openMVG/features/liop/liop_descriptor.hpp | 18 +++++------ src/openMVG/image/image_concat.hpp | 6 ++++ src/openMVG/image/image_container.hpp | 2 ++ src/openMVG/image/image_converter.hpp | 2 ++ src/openMVG/image/image_convolution.hpp | 7 +++-- src/openMVG/image/image_convolution_base.hpp | 5 +-- src/openMVG/image/image_diffusion.hpp | 6 ++-- src/openMVG/image/image_drawing.hpp | 4 ++- src/openMVG/image/image_drawing_test.cpp | 1 + src/openMVG/image/image_filtering.hpp | 9 +++--- src/openMVG/image/image_filtering_test.cpp | 1 + src/openMVG/image/image_io.cpp | 4 ++- src/openMVG/image/image_io.hpp | 2 ++ src/openMVG/image/image_io_test.cpp | 25 ++++++++------- src/openMVG/image/image_resampling.hpp | 8 +++-- src/openMVG/image/image_test.cpp | 5 +-- src/openMVG/image/pixel_types.hpp | 2 ++ src/openMVG/image/sample.hpp | 4 ++- src/openMVG/matching/kvld/algorithm.cpp | 9 +++--- src/openMVG/matching/kvld/algorithm.h | 6 ++-- src/openMVG/matching/kvld/kvld.cpp | 1 + src/openMVG/matching/kvld/kvld.h | 31 ++++++++++--------- src/openMVG/matching/kvld/kvld_draw.h | 8 ++--- .../describe_and_match.cpp | 1 + .../kvld_filter/kvld_filter.cpp | 11 ++++--- .../robust_essential/robust_essential.cpp | 1 + .../robust_essential_ba.cpp | 1 + .../robust_essential_spherical.cpp | 1 + .../robust_fundamental/robust_fundamental.cpp | 1 + .../robust_fundamental_guided.cpp | 1 + .../robust_homography/robust_homography.cpp | 1 + .../robust_homography_guided.cpp | 1 + .../siftPutativeMatches/siftmatch.cpp | 1 + .../undisto_Brown/undistoBrown.cpp | 1 + src/software/SfM/main_ComputeFeatures.cpp | 1 + .../SfM/main_ComputeFeatures_OpenCV.cpp | 1 + .../SfM/main_ComputeSfM_DataColor.cpp | 1 + .../SfM/main_SfMInit_ImageListing.cpp | 5 +-- src/software/SfM/main_openMVG2CMPMVS.cpp | 1 + src/software/SfM/main_openMVG2MESHLAB.cpp | 1 + src/software/SfM/main_openMVG2PMVS.cpp | 1 + src/software/SfMViewer/main.cpp | 1 + .../colorHarmonizeEngineGlobal.cpp | 1 + 54 files changed, 172 insertions(+), 116 deletions(-) diff --git a/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp b/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp index c9526a7a72..2fc821941c 100644 --- a/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp +++ b/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp @@ -35,6 +35,7 @@ #include using namespace openMVG; +using namespace openMVG::image; using namespace openMVG::matching; using namespace openMVG::robust; using namespace std; diff --git a/src/nonFree/sift/SIFT_describer.hpp b/src/nonFree/sift/SIFT_describer.hpp index 0c812268df..22e06267cd 100644 --- a/src/nonFree/sift/SIFT_describer.hpp +++ b/src/nonFree/sift/SIFT_describer.hpp @@ -111,13 +111,13 @@ class SIFT_Image_describer : public Image_describer @param mask 8-bit gray image for keypoint filtering (optional). Non-zero values depict the region of interest. */ - bool Describe(const Image& image, + bool Describe(const image::Image& image, std::unique_ptr ®ions, - const Image * mask = NULL) + const image::Image * mask = NULL) { const int w = image.Width(), h = image.Height(); //Convert to float - const Image If( image.GetMat().cast() ); + const image::Image If(image.GetMat().cast()); // Configure VLFeat vl_constructor(); @@ -160,7 +160,7 @@ class SIFT_Image_describer : public Image_describer // Feature masking if (mask) { - const Image & maskIma = *mask; + const image::Image & maskIma = *mask; if (maskIma(keys[i].y, keys[i].x) > 0) continue; } diff --git a/src/openMVG/color_harmonization/selection_VLDSegment.hpp b/src/openMVG/color_harmonization/selection_VLDSegment.hpp index 4bc0219bc8..6ffe6b3aa4 100644 --- a/src/openMVG/color_harmonization/selection_VLDSegment.hpp +++ b/src/openMVG/color_harmonization/selection_VLDSegment.hpp @@ -40,17 +40,17 @@ class commonDataByPair_VLDSegment : public commonDataByPair * \return True. */ virtual bool computeMask( - Image< unsigned char > & maskLeft, - Image< unsigned char > & maskRight ) + image::Image< unsigned char > & maskLeft, + image::Image< unsigned char > & maskRight ) { std::vector< matching::IndMatch > vec_KVLDMatches; - Image< unsigned char > imageL, imageR; - ReadImage( _sLeftImage.c_str(), &imageL ); - ReadImage( _sRightImage.c_str(), &imageR ); + image::Image< unsigned char > imageL, imageR; + image::ReadImage( _sLeftImage.c_str(), &imageL ); + image::ReadImage( _sRightImage.c_str(), &imageR ); - Image< float > imgA ( imageL.GetMat().cast< float >() ); - Image< float > imgB ( imageR.GetMat().cast< float >() ); + image::Image< float > imgA ( imageL.GetMat().cast< float >() ); + image::Image< float > imgB(imageR.GetMat().cast< float >()); std::vector< Pair > matchesFiltered, matchesPair; diff --git a/src/openMVG/color_harmonization/selection_fullFrame.hpp b/src/openMVG/color_harmonization/selection_fullFrame.hpp index 55eed885ce..7625fa24dc 100644 --- a/src/openMVG/color_harmonization/selection_fullFrame.hpp +++ b/src/openMVG/color_harmonization/selection_fullFrame.hpp @@ -31,10 +31,10 @@ class commonDataByPair_FullFrame : public commonDataByPair * * \return True. */ - virtual bool computeMask( Image< unsigned char > & maskLeft, Image< unsigned char > & maskRight ) + virtual bool computeMask( image::Image< unsigned char > & maskLeft, image::Image< unsigned char > & maskRight ) { - maskLeft.fill( WHITE ); - maskRight.fill( WHITE ); + maskLeft.fill( image::WHITE ); + maskRight.fill( image::WHITE ); return true; } diff --git a/src/openMVG/color_harmonization/selection_interface.hpp b/src/openMVG/color_harmonization/selection_interface.hpp index 2180bf5da4..e48c679434 100644 --- a/src/openMVG/color_harmonization/selection_interface.hpp +++ b/src/openMVG/color_harmonization/selection_interface.hpp @@ -35,7 +35,7 @@ class commonDataByPair * * \return True if(mask not empty). */ - virtual bool computeMask( Image< unsigned char > & maskLeft, Image< unsigned char > & maskRight ) = 0; + virtual bool computeMask( image::Image< unsigned char > & maskLeft, image::Image< unsigned char > & maskRight ) = 0; /** * Compute Histogram for the color's masked data @@ -49,9 +49,9 @@ class commonDataByPair template< typename ImageType > static void computeHisto( Histogram< double > & histo, - const Image< unsigned char >& mask, + const image::Image< unsigned char >& mask, size_t channelIndex, - const Image< ImageType >& image ) + const image::Image< ImageType >& image ) { for( int j = 0; j < mask.Height(); ++j ) { diff --git a/src/openMVG/color_harmonization/selection_matchedPoints.hpp b/src/openMVG/color_harmonization/selection_matchedPoints.hpp index 47fc242017..28296f6bc5 100644 --- a/src/openMVG/color_harmonization/selection_matchedPoints.hpp +++ b/src/openMVG/color_harmonization/selection_matchedPoints.hpp @@ -42,7 +42,7 @@ class commonDataByPair_MatchedPoints : public commonDataByPair * * \return True if some pixel have been set to true. */ - virtual bool computeMask( Image< unsigned char > & maskLeft, Image< unsigned char > & maskRight ) + virtual bool computeMask( image::Image< unsigned char > & maskLeft, image::Image< unsigned char > & maskRight ) { maskLeft.fill(0); maskRight.fill(0); @@ -54,8 +54,8 @@ class commonDataByPair_MatchedPoints : public commonDataByPair const SIOPointFeature & L = _vec_featsL[ iter_putativeMatches->_i ]; const SIOPointFeature & R = _vec_featsR[ iter_putativeMatches->_j ]; - FilledCircle( L.x(), L.y(), ( int )_radius, ( unsigned char ) 255, &maskLeft ); - FilledCircle( R.x(), R.y(), ( int )_radius, ( unsigned char ) 255, &maskRight ); + image::FilledCircle( L.x(), L.y(), ( int )_radius, ( unsigned char ) 255, &maskLeft ); + image::FilledCircle( R.x(), R.y(), ( int )_radius, ( unsigned char ) 255, &maskRight ); } return _vec_PutativeMatches.size() > 0; } diff --git a/src/openMVG/features/akaze/AKAZE.cpp b/src/openMVG/features/akaze/AKAZE.cpp index 08f1658967..a2a7bebca3 100644 --- a/src/openMVG/features/akaze/AKAZE.cpp +++ b/src/openMVG/features/akaze/AKAZE.cpp @@ -8,6 +8,8 @@ namespace openMVG { +using namespace openMVG::image; + /// Lookup table for 2d gaussian (sigma = 2.5) where (0,0) is top left and (6,6) is bottom right const float gauss25[7][7] = { {0.02546481f, 0.02350698f, 0.01849125f, 0.01239505f, 0.00708017f, 0.00344629f, 0.00142946f}, diff --git a/src/openMVG/features/akaze/AKAZE.hpp b/src/openMVG/features/akaze/AKAZE.hpp index 5ecd9009f5..77f820ec64 100644 --- a/src/openMVG/features/akaze/AKAZE.hpp +++ b/src/openMVG/features/akaze/AKAZE.hpp @@ -92,7 +92,7 @@ struct AKAZEKeypoint{ struct TEvolution { - Image + image::Image cur, ///< Current gaussian image Lx, ///< Current x derivatives Ly, ///< Current y derivatives @@ -107,12 +107,12 @@ class AKAZE { AKAZEConfig options_; ///< Configuration options for AKAZE std::vector evolution_; ///< Vector of nonlinear diffusion evolution (Scale Space) - Image in_; ///< Input image + image::Image in_; ///< Input image public: /// Constructor - AKAZE(const Image & in, const AKAZEConfig & options); + AKAZE(const image::Image & in, const AKAZEConfig & options); /// Compute the AKAZE non linear diffusion scale space per slice void Compute_AKAZEScaleSpace(void); @@ -124,7 +124,7 @@ class AKAZE { void Do_Subpixel_Refinement(std::vector& kpts) const; /// Sub pixel refinement of a keypoint - bool Do_Subpixel_Refinement( AKAZEKeypoint & kpts, const Image & Ldet) const; + bool Do_Subpixel_Refinement(AKAZEKeypoint & kpts, const image::Image & Ldet) const; /// Scale Space accessor const std::vector & getSlices() const {return evolution_;} @@ -137,27 +137,27 @@ class AKAZE { */ void Compute_Main_Orientation( AKAZEKeypoint& kpt, - const Image & Lx, - const Image & Ly) const; + const image::Image & Lx, + const image::Image & Ly) const; /// Compute an AKAZE slice static void ComputeAKAZESlice( - const Image & src , // Input image for the given octave + const image::Image & src, // Input image for the given octave const int p , // octave index const int q , // slice index const int nbSlice , // slices per octave const float sigma0 , // first octave initial scale const float contrast_factor , - Image & Li , // Diffusion image - Image & Lx , // X derivatives - Image & Ly , // Y derivatives - Image & Lhess // Det(Hessian) + image::Image & Li, // Diffusion image + image::Image & Lx, // X derivatives + image::Image & Ly, // Y derivatives + image::Image & Lhess // Det(Hessian) ); /// Compute Contrast Factor static float ComputeAutomaticContrastFactor( - const Image & src, + const image::Image & src, const float percentile ); }; /* ************************************************************************* */ diff --git a/src/openMVG/features/akaze/mldb_descriptor.hpp b/src/openMVG/features/akaze/mldb_descriptor.hpp index d2c5a6f17e..9675115ff2 100644 --- a/src/openMVG/features/akaze/mldb_descriptor.hpp +++ b/src/openMVG/features/akaze/mldb_descriptor.hpp @@ -140,9 +140,9 @@ namespace openMVG **/ template< typename Real> void ComputeMLDBDescriptor( - const Image & Li , - const Image &Lx , - const Image &Ly , + const image::Image & Li, + const image::Image &Lx, + const image::Image &Ly, const int id_octave , const SIOPointFeature & ipt , Descriptor & desc ) diff --git a/src/openMVG/features/image_describer.hpp b/src/openMVG/features/image_describer.hpp index e17674b386..5df23abf7d 100644 --- a/src/openMVG/features/image_describer.hpp +++ b/src/openMVG/features/image_describer.hpp @@ -44,9 +44,9 @@ class Image_describer @param mask 8-bit gray image for keypoint filtering (optional). Non-zero values depict the region of interest. */ - virtual bool Describe(const Image & image, + virtual bool Describe(const image::Image & image, std::unique_ptr ®ions, - const Image * mask = NULL) = 0; + const image::Image * mask = NULL) = 0; /// Allocate regions depending of the Image_describer virtual void Allocate(std::unique_ptr ®ions) const = 0; diff --git a/src/openMVG/features/image_describer_akaze.hpp b/src/openMVG/features/image_describer_akaze.hpp index e638b50953..072547ca86 100644 --- a/src/openMVG/features/image_describer_akaze.hpp +++ b/src/openMVG/features/image_describer_akaze.hpp @@ -19,7 +19,6 @@ #include using namespace std; -using namespace openMVG; namespace openMVG { namespace features { @@ -84,9 +83,9 @@ class AKAZE_Image_describer : public Image_describer @param mask 8-bit gray image for keypoint filtering (optional). Non-zero values depict the region of interest. */ - bool Describe(const Image& image, + bool Describe(const image::Image& image, std::unique_ptr ®ions, - const Image * mask = NULL) + const image::Image * mask = NULL) { _params._options.fDesc_factor = (_params._eAkazeDescriptor == AKAZE_MSURF || @@ -121,7 +120,7 @@ class AKAZE_Image_describer : public Image_describer // Feature masking if (mask) { - const Image & maskIma = *mask; + const image::Image & maskIma = *mask; if (maskIma(ptAkaze.y, ptAkaze.x) > 0) continue; } @@ -162,7 +161,7 @@ class AKAZE_Image_describer : public Image_describer // Feature masking if (mask) { - const Image & maskIma = *mask; + const image::Image & maskIma = *mask; if (maskIma(ptAkaze.y, ptAkaze.x) > 0) continue; } @@ -209,7 +208,7 @@ class AKAZE_Image_describer : public Image_describer // Feature masking if (mask) { - const Image & maskIma = *mask; + const image::Image & maskIma = *mask; if (maskIma(ptAkaze.y, ptAkaze.x) > 0) continue; } diff --git a/src/openMVG/features/liop/liop_descriptor.hpp b/src/openMVG/features/liop/liop_descriptor.hpp index 440f949f15..7aca245ee2 100644 --- a/src/openMVG/features/liop/liop_descriptor.hpp +++ b/src/openMVG/features/liop/liop_descriptor.hpp @@ -47,7 +47,7 @@ class Liop_Descriptor_Extractor } void extract( - const Image & I, + const image::Image & I, const SIOPointFeature & feat, float desc[144]) { @@ -61,8 +61,8 @@ class Liop_Descriptor_Extractor const int outRadius2 = outRadius*outRadius; const float scale = feat.scale(); - Image outPatch(outPatchWidth,outPatchWidth, true, 0); - Image flagPatch(outPatchWidth,outPatchWidth, true, 0); + image::Image outPatch(outPatchWidth,outPatchWidth, true, 0); + image::Image flagPatch(outPatchWidth, outPatchWidth, true, 0); // pointer alias const unsigned char * img_data = I.GetMat().data(); @@ -89,7 +89,7 @@ class Liop_Descriptor_Extractor flagPatch_data[(y+outRadius)*outPatchWidth+x+outRadius] = 1; } } - ImageGaussianFilter( Image(outPatch), 1.2, outPatch); + image::ImageGaussianFilter(image::Image(outPatch), 1.2, outPatch); //b. creation of the LIOP ordering const int inRadius = scalePatchWidth/2; @@ -104,8 +104,8 @@ class Liop_Descriptor_Extractor }; void CreateLIOP_GOrder( - const Image & outPatch, - const Image & flagPatch, + const image::Image & outPatch, + const image::Image & flagPatch, const int inRadius, float desc[144]) { @@ -118,7 +118,7 @@ class Liop_Descriptor_Extractor const int outRadius = outPatch.Width() / 2; const int lsRadius = 6; - const float theta = 2.0*M_PI/(float)LIOP_NUM; + const float theta = 2.0f*M_PI/(float)LIOP_NUM; Pixel pixel[MAX_PIXEL_NUM]; int pixelCount = 0; @@ -238,8 +238,8 @@ class Liop_Descriptor_Extractor bool BilinearInterpolation_BorderCheck( float& val, float x, float y, - const Image & image, - const Image & flagImage) const + const image::Image & image, + const image::Image & flagImage) const { val = 0.0f; if(!(x >= 0 && y >= 0 && x<=image.Width()-1 && y<=image.Height()-1)) diff --git a/src/openMVG/image/image_concat.hpp b/src/openMVG/image/image_concat.hpp index e5a36d01f1..46ae235d0b 100644 --- a/src/openMVG/image/image_concat.hpp +++ b/src/openMVG/image/image_concat.hpp @@ -9,6 +9,9 @@ #include "openMVG/image/image_container.hpp" +namespace openMVG { +namespace image { + /// Horizontal concatenation of images template < class Image > void ConcatH(const Image & imageA, const Image & imageB, Image & Out) @@ -43,4 +46,7 @@ void ConcatV(const Image & imageA, const Image & imageB, Image & Out) Out.block(imageA.Height(), 0, imageB.Height(), imageB.Width()) = imageB.GetMat(); } +} // namespace image +} // namespace openMVG + #endif // OPENMVG_IMAGE_IMAGE_CONCAT_H_ diff --git a/src/openMVG/image/image_container.hpp b/src/openMVG/image/image_container.hpp index 0a581f5bb4..0b251bba27 100644 --- a/src/openMVG/image/image_container.hpp +++ b/src/openMVG/image/image_container.hpp @@ -25,6 +25,7 @@ // [2/3/2011 pierre MOULON] //--------------------------- namespace openMVG { +namespace image { template class Image : public Eigen::Matrix @@ -88,6 +89,7 @@ protected : //-- Image data are stored by inheritance of a matrix }; +} // namespace image } // namespace openMVG #endif // OPENMVG_IMAGE_IMAGE_HPP diff --git a/src/openMVG/image/image_converter.hpp b/src/openMVG/image/image_converter.hpp index ea6c277110..4c37535622 100644 --- a/src/openMVG/image/image_converter.hpp +++ b/src/openMVG/image/image_converter.hpp @@ -11,6 +11,7 @@ #include "openMVG/image/pixel_types.hpp" namespace openMVG{ +namespace image { template // The factor comes from http://www.easyrgb.com/ @@ -116,6 +117,7 @@ static void rgbFloat2rgbInt( convertFloatToInt( imaIn( j, i ), (*imaOut)( j, i ), factor ); } +} // namespace image } // namespace openMVG #endif // OPENMVG_IMAGE_IMAGE_CONVERTER_HPP diff --git a/src/openMVG/image/image_convolution.hpp b/src/openMVG/image/image_convolution.hpp index d78070b464..837d0e6604 100644 --- a/src/openMVG/image/image_convolution.hpp +++ b/src/openMVG/image/image_convolution.hpp @@ -16,8 +16,9 @@ ** - 2D (using standard 2d kernel of with separable kernels) **/ -namespace openMVG -{ +namespace openMVG { +namespace image { + /** ** General image convolution by a kernel ** assume kernel has odd size in both dimensions and (border pixel are copied) @@ -268,7 +269,7 @@ void ImageSeparableConvolution( const Image & img , SeparableConvolution2d(img.GetMat(), horiz_k_cast, vert_k_cast, &((Image::Base&)out)); } +} // namespace image } // namespace openMVG #endif // OPENMVG_IMAGE_IMAGE_CONVOLUTION_HPP_ - diff --git a/src/openMVG/image/image_convolution_base.hpp b/src/openMVG/image/image_convolution_base.hpp index 9ae82bf3e7..94ce21dbec 100644 --- a/src/openMVG/image/image_convolution_base.hpp +++ b/src/openMVG/image/image_convolution_base.hpp @@ -7,8 +7,8 @@ #ifndef OPENMVG_IMAGE_IMAGE_CONVOLUTION_BASE_HPP #define OPENMVG_IMAGE_IMAGE_CONVOLUTION_BASE_HPP -namespace openMVG -{ +namespace openMVG { +namespace image { /** ** Filter an extended row [halfKernelSize][row][halfKernelSize] ** @param buffer data to filter @@ -29,6 +29,7 @@ namespace openMVG buffer[i] = sum; } } +} // namespace image } // namespace openMVG #endif // OPENMVG_IMAGE_IMAGE_CONVOLUTION_BASE_HPP diff --git a/src/openMVG/image/image_diffusion.hpp b/src/openMVG/image/image_diffusion.hpp index c01ab45c2b..dba9ac3dd5 100644 --- a/src/openMVG/image/image_diffusion.hpp +++ b/src/openMVG/image/image_diffusion.hpp @@ -11,8 +11,9 @@ #pragma warning(once:4244) #endif -namespace openMVG -{ +namespace openMVG { +namespace image { + /** ** Compute Perona and Malik G2 diffusion coefficient ** @param Lx Image of X-derivative @@ -332,6 +333,7 @@ int FEDCycleTimings( const Real T , const Real Tmax , std::vector< Real > & tau return n ; } +} // namespace image } // namespace openMVG #endif // OPENMVG_IMAGE_IMAGE_DIFFUSION_HPP_ diff --git a/src/openMVG/image/image_drawing.hpp b/src/openMVG/image/image_drawing.hpp index 5040581dd2..697e7b2313 100644 --- a/src/openMVG/image/image_drawing.hpp +++ b/src/openMVG/image/image_drawing.hpp @@ -26,6 +26,7 @@ #include "openMVG/image/image_container.hpp" namespace openMVG { +namespace image { /// Put the pixel in the image to the given color only if the point (xc,yc) /// is inside the image. @@ -402,6 +403,7 @@ void DrawLineThickness(int xa, int ya, int xb, int yb, const Color& col, int thi DrawCircle(x, y, halfThickness, col, pim); } -} //namespace openMVG +} // namespace image +} // namespace openMVG #endif // OPENMVG_IMAGE_IMAGE_DRAWING_HPP diff --git a/src/openMVG/image/image_drawing_test.cpp b/src/openMVG/image/image_drawing_test.cpp index e78558db9a..9fe744fcb8 100644 --- a/src/openMVG/image/image_drawing_test.cpp +++ b/src/openMVG/image/image_drawing_test.cpp @@ -8,6 +8,7 @@ #include "testing/testing.h" using namespace openMVG; +using namespace openMVG::image; // Horizontal / Vertical scanlines // Assert that pixels was drawn at the good place diff --git a/src/openMVG/image/image_filtering.hpp b/src/openMVG/image/image_filtering.hpp index 0b57430a8f..ce8a1b549d 100644 --- a/src/openMVG/image/image_filtering.hpp +++ b/src/openMVG/image/image_filtering.hpp @@ -23,8 +23,8 @@ #include "openMVG/image/image_convolution.hpp" -namespace openMVG -{ +namespace openMVG { +namespace image { /** ** Compute X-derivative using central difference @@ -338,8 +338,7 @@ namespace openMVG ImageSeparableConvolution( img , kernel_horiz , kernel_vert , out) ; } - - -} +} // namespace image +} // namespace openMVG #endif diff --git a/src/openMVG/image/image_filtering_test.cpp b/src/openMVG/image/image_filtering_test.cpp index 7ff377134d..a2d3d6b387 100644 --- a/src/openMVG/image/image_filtering_test.cpp +++ b/src/openMVG/image/image_filtering_test.cpp @@ -8,6 +8,7 @@ #include "testing/testing.h" using namespace openMVG; +using namespace openMVG::image; #include using namespace std; diff --git a/src/openMVG/image/image_io.cpp b/src/openMVG/image/image_io.cpp index 0c4ac0d9d6..ca7d077d7f 100644 --- a/src/openMVG/image/image_io.cpp +++ b/src/openMVG/image/image_io.cpp @@ -19,6 +19,7 @@ extern "C" { using namespace std; namespace openMVG { +namespace image { static bool CmpFormatExt(const char *a, const char *b) { size_t len_a = strlen(a); @@ -55,7 +56,7 @@ int ReadImage(const char *filename, int * w, int * h, int * depth){ - Format f = GetFormat(filename); + const Format f = GetFormat(filename); switch (f) { case Pnm: @@ -629,4 +630,5 @@ int WriteTiff(const char * filename, return 1; } +} // namespace image } // namespace openMVG diff --git a/src/openMVG/image/image_io.hpp b/src/openMVG/image/image_io.hpp index a20fb41e26..3664cea918 100644 --- a/src/openMVG/image/image_io.hpp +++ b/src/openMVG/image/image_io.hpp @@ -11,6 +11,7 @@ #include "openMVG/image/pixel_types.hpp" namespace openMVG { +namespace image { enum Format { Pnm, Png, Jpg, Tiff, Unknown @@ -153,6 +154,7 @@ int WriteJpg(const char * filename, const Image& im, int quality) return WriteJpg(filename, array, w, h, depth, quality); } +} // namespace image } // namespace openMVG #endif // OPENMVG_IMAGE_IMAGE_IMAGE_IO_HPP diff --git a/src/openMVG/image/image_io_test.cpp b/src/openMVG/image/image_io_test.cpp index f46826a582..42e202b5bc 100644 --- a/src/openMVG/image/image_io_test.cpp +++ b/src/openMVG/image/image_io_test.cpp @@ -13,6 +13,7 @@ #include "testing/testing.h" using namespace openMVG; +using namespace openMVG::image; using std::string; TEST(ReadJpg, Jpg_Color) { @@ -61,18 +62,18 @@ TEST(ReadPng, Png_Monochrome) { } TEST(GetFormat, filenames) { - EXPECT_EQ(GetFormat("something.jpg"), openMVG::Jpg); - EXPECT_EQ(GetFormat("something.png"), openMVG::Png); - EXPECT_EQ(GetFormat("something.pnm"), openMVG::Pnm); - EXPECT_EQ(GetFormat("something.tif"), openMVG::Tiff); - EXPECT_EQ(GetFormat("/some/thing.JpG"), openMVG::Jpg); - EXPECT_EQ(GetFormat("/some/thing.pNG"), openMVG::Png); - EXPECT_EQ(GetFormat("some/thing.PNm"), openMVG::Pnm); - EXPECT_EQ(GetFormat("some/thing.TIf"), openMVG::Tiff); - EXPECT_EQ(GetFormat(".s/o.m/e.t/h.i/n.g.JPG"), openMVG::Jpg); - EXPECT_EQ(GetFormat(".s/o.m/e.t/h.i/n.g.PNG"), openMVG::Png); - EXPECT_EQ(GetFormat(".s/o.m/e.t/h.i/n.g.PNM"), openMVG::Pnm); - EXPECT_EQ(GetFormat(".s/o.m/e.t/h.i/n.g.TIF"), openMVG::Tiff); + EXPECT_EQ(GetFormat("something.jpg"), openMVG::image::Jpg); + EXPECT_EQ(GetFormat("something.png"), openMVG::image::Png); + EXPECT_EQ(GetFormat("something.pnm"), openMVG::image::Pnm); + EXPECT_EQ(GetFormat("something.tif"), openMVG::image::Tiff); + EXPECT_EQ(GetFormat("/some/thing.JpG"), openMVG::image::Jpg); + EXPECT_EQ(GetFormat("/some/thing.pNG"), openMVG::image::Png); + EXPECT_EQ(GetFormat("some/thing.PNm"), openMVG::image::Pnm); + EXPECT_EQ(GetFormat("some/thing.TIf"), openMVG::image::Tiff); + EXPECT_EQ(GetFormat(".s/o.m/e.t/h.i/n.g.JPG"), openMVG::image::Jpg); + EXPECT_EQ(GetFormat(".s/o.m/e.t/h.i/n.g.PNG"), openMVG::image::Png); + EXPECT_EQ(GetFormat(".s/o.m/e.t/h.i/n.g.PNM"), openMVG::image::Pnm); + EXPECT_EQ(GetFormat(".s/o.m/e.t/h.i/n.g.TIF"), openMVG::image::Tiff); } TEST(ImageIOTest, Png_Out) { diff --git a/src/openMVG/image/image_resampling.hpp b/src/openMVG/image/image_resampling.hpp index 4e8a150569..83c12b75ad 100644 --- a/src/openMVG/image/image_resampling.hpp +++ b/src/openMVG/image/image_resampling.hpp @@ -8,8 +8,9 @@ #define OPENMVG_IMAGE_IMAGE_RESAMPLING_HPP_ -namespace openMVG -{ +namespace openMVG { +namespace image { + /** ** Half sample an image (ie reduce it's size by a factor 2) using bilinear interpolation ** @param src input image @@ -36,6 +37,7 @@ namespace openMVG // TODO : provide a Double size resampling image -} +} // namespace image +} // namespace openMVG #endif \ No newline at end of file diff --git a/src/openMVG/image/image_test.cpp b/src/openMVG/image/image_test.cpp index bf783e6461..c07c279dd5 100644 --- a/src/openMVG/image/image_test.cpp +++ b/src/openMVG/image/image_test.cpp @@ -10,6 +10,7 @@ #include using namespace std; using namespace openMVG; +using namespace openMVG::image; TEST(Image, Basis) { @@ -73,12 +74,12 @@ TEST(Image, ImageConverter) Image imaColorRGB(5,5); imaColorRGB.fill(RGBColor(10,10,10)); Image imaGray; - openMVG::ConvertPixelType(imaColorRGB, &imaGray); + ConvertPixelType(imaColorRGB, &imaGray); //RGBA Image imaColorRGBA(5,5); imaColorRGBA.fill(RGBAColor(10,10,10, 255)); - openMVG::ConvertPixelType(imaColorRGBA, &imaGray); + ConvertPixelType(imaColorRGBA, &imaGray); } /* ************************************************************************* */ diff --git a/src/openMVG/image/pixel_types.hpp b/src/openMVG/image/pixel_types.hpp index 029fd38e42..742fbf22c8 100644 --- a/src/openMVG/image/pixel_types.hpp +++ b/src/openMVG/image/pixel_types.hpp @@ -10,6 +10,7 @@ #include "openMVG/numeric/numeric.h" namespace openMVG { +namespace image { /// RGB template pixel type template @@ -142,6 +143,7 @@ const RGBColor YELLOW(255,255,0); const RGBColor CYAN(0,255,255); const RGBColor MAGENTA(255,0,255); +} // namespace image } // namespace openMVG #endif // OPENMVG_IMAGE_PIXELTYPES_HPP diff --git a/src/openMVG/image/sample.hpp b/src/openMVG/image/sample.hpp index 1524271c48..e08a1adc1e 100644 --- a/src/openMVG/image/sample.hpp +++ b/src/openMVG/image/sample.hpp @@ -31,6 +31,7 @@ #include "openMVG/image/pixel_types.hpp" namespace openMVG { +namespace image { /// Nearest neighbor interpolation. template @@ -102,6 +103,7 @@ inline RGBColor SampleLinear(const Image& image, float y, fl ); } -} // namespace openMVG +} // namespace image +} // namespace openMVG #endif // OPENMVG_IMAGE_SAMPLE_HPP diff --git a/src/openMVG/matching/kvld/algorithm.cpp b/src/openMVG/matching/kvld/algorithm.cpp index 5eff0d8da1..26422c535e 100644 --- a/src/openMVG/matching/kvld/algorithm.cpp +++ b/src/openMVG/matching/kvld/algorithm.cpp @@ -12,7 +12,7 @@ the terms of the BSD license (see the COPYING file). #include "algorithm.h" -IntegralImages::IntegralImages( const openMVG::Image< float >& I ) +IntegralImages::IntegralImages(const openMVG::image::Image< float >& I) { map.resize( I.Width() + 1, I.Height() + 1 ); map.fill( 0 ); @@ -25,9 +25,10 @@ IntegralImages::IntegralImages( const openMVG::Image< float >& I ) } } -float getRange( const openMVG::Image< float >& I, - int a, - const float p ) +float getRange( + const openMVG::image::Image< float >& I, + int a, + const float p ) { float range = sqrt( float( 3.f * I.Height() * I.Width() ) / ( p * a * PI_ ) ); return range; diff --git a/src/openMVG/matching/kvld/algorithm.h b/src/openMVG/matching/kvld/algorithm.h index cdedc0c134..3988d5cc0f 100644 --- a/src/openMVG/matching/kvld/algorithm.h +++ b/src/openMVG/matching/kvld/algorithm.h @@ -49,9 +49,9 @@ struct PointS //It is used to efficiently construct the pyramid of scale images in KVLD struct IntegralImages { - openMVG::Image< double > map; + openMVG::image::Image< double > map; - IntegralImages( const openMVG::Image< float >& I ); + IntegralImages(const openMVG::image::Image< float >& I); inline double operator()( double x1, double y1, double x2, double y2 )const { @@ -196,6 +196,6 @@ inline float consistent( const T& a1, const T& a2, const T& b1, const T& b2 ) float d = std::min( d1_error / std::min( d1, point_distance( b1, b2 ) ), d2_error / std::min( d2, point_distance( b1, b2 ) ) ); return d; } -float getRange( const openMVG::Image< float >& I, int a, const float p ); +float getRange(const openMVG::image::Image< float >& I, int a, const float p); #endif //KVLD_ALGORITHM_H diff --git a/src/openMVG/matching/kvld/kvld.cpp b/src/openMVG/matching/kvld/kvld.cpp index 39df39c592..564edc603a 100644 --- a/src/openMVG/matching/kvld/kvld.cpp +++ b/src/openMVG/matching/kvld/kvld.cpp @@ -19,6 +19,7 @@ the terms of the BSD license ( see the COPYING file). using namespace std; using namespace openMVG; +using namespace openMVG::image; ImageScale::ImageScale( const Image< float >& I, double r ) { diff --git a/src/openMVG/matching/kvld/kvld.h b/src/openMVG/matching/kvld/kvld.h index 6c7c04ce16..8b1eb00b66 100644 --- a/src/openMVG/matching/kvld/kvld.h +++ b/src/openMVG/matching/kvld/kvld.h @@ -56,17 +56,20 @@ struct KvldParameters // magnitudes: store gradient norms of pixels of each scale image into a vector of images struct ImageScale { - std::vector< openMVG::Image< float > > angles; - std::vector< openMVG::Image< float > > magnitudes; + std::vector< openMVG::image::Image< float > > angles; + std::vector< openMVG::image::Image< float > > magnitudes; std::vector< double > ratios; double radius_size; double step; - ImageScale( const openMVG::Image< float >& I,double r = 5.0 ); + ImageScale(const openMVG::image::Image< float >& I, double r = 5.0); int getIndex( const double r )const; private: - void GradAndNorm( const openMVG::Image< float >& I, openMVG::Image< float >& angle, openMVG::Image< float >& m ); + void GradAndNorm( + const openMVG::image::Image< float >& I, + openMVG::image::Image< float >& angle, + openMVG::image::Image< float >& m); }; //====== VLD structures ======// @@ -169,15 +172,15 @@ class VLD // //kvldParameters: container of minimum inlier rate, the value of K (=3 initially) and geometric verification flag (true initially) -float KVLD( const openMVG::Image< float >& I1, - const openMVG::Image< float >& I2, - const std::vector & F1, - const std::vector & F2, - const std::vector< openMVG::Pair >& matches, - std::vector< openMVG::Pair >& matchesFiltered, - std::vector< double >& score, - openMVG::Mat& E, - std::vector< bool >& valide, - KvldParameters& kvldParameters ); +float KVLD(const openMVG::image::Image< float >& I1, + const openMVG::image::Image< float >& I2, + const std::vector & F1, + const std::vector & F2, + const std::vector< openMVG::Pair >& matches, + std::vector< openMVG::Pair >& matchesFiltered, + std::vector< double >& score, + openMVG::Mat& E, + std::vector< bool >& valide, + KvldParameters& kvldParameters ); #endif //KVLD_H diff --git a/src/openMVG/matching/kvld/kvld_draw.h b/src/openMVG/matching/kvld/kvld_draw.h index c9f88ab313..8b016206e4 100644 --- a/src/openMVG/matching/kvld/kvld_draw.h +++ b/src/openMVG/matching/kvld/kvld_draw.h @@ -14,8 +14,8 @@ namespace openMVG { //-- A slow but accurate way to draw K-VLD lines void getKVLDMask( - Image< unsigned char > *maskL, - Image< unsigned char > *maskR, + image::Image< unsigned char > *maskL, + image::Image< unsigned char > *maskR, const std::vector< openMVG::SIOPointFeature > &vec_F1, const std::vector< openMVG::SIOPointFeature > &vec_F2, const std::vector< Pair >& vec_matches, @@ -33,14 +33,14 @@ void getKVLDMask( float l = ( l1.coords() - l2.coords() ).norm(); int widthL = std::max( 1.f, l / ( dimension + 1.f ) ); - DrawLineThickness(l1.x(), l1.y(), l2.x(), l2.y(), 255, widthL, maskL); + image::DrawLineThickness(l1.x(), l1.y(), l2.x(), l2.y(), 255, widthL, maskL); const openMVG::SIOPointFeature & r1 = vec_F2[ vec_matches[ it1 ].second ]; const openMVG::SIOPointFeature & r2 = vec_F2[ vec_matches[ it2 ].second ]; float r = ( r1.coords() - r2.coords() ).norm(); int widthR = std::max( 1.f, r / ( dimension + 1.f ) ); - DrawLineThickness(r1.x(), r1.y(), r2.x(), r2.y(), 255, widthR, maskR); + image::DrawLineThickness(r1.x(), r1.y(), r2.x(), r2.y(), 255, widthR, maskR); } } } diff --git a/src/openMVG_Samples/image_describer_matches/describe_and_match.cpp b/src/openMVG_Samples/image_describer_matches/describe_and_match.cpp index 322ffe99d1..9c2e4301b0 100644 --- a/src/openMVG_Samples/image_describer_matches/describe_and_match.cpp +++ b/src/openMVG_Samples/image_describer_matches/describe_and_match.cpp @@ -22,6 +22,7 @@ #include using namespace openMVG; +using namespace openMVG::image; using namespace svg; using namespace std; diff --git a/src/openMVG_Samples/kvld_filter/kvld_filter.cpp b/src/openMVG_Samples/kvld_filter/kvld_filter.cpp index bba180a483..fdd03e4960 100644 --- a/src/openMVG_Samples/kvld_filter/kvld_filter.cpp +++ b/src/openMVG_Samples/kvld_filter/kvld_filter.cpp @@ -6,10 +6,11 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include "openMVG/image/image.hpp" + +using namespace openMVG::image; + #include "openMVG/features/features.hpp" #include "openMVG/matching/matcher_brute_force.hpp" -#include "openMVG/matching/matcher_kdtree_flann.hpp" - #include "openMVG_Samples/siftPutativeMatches/two_view_matches.hpp" using namespace openMVG::matching; @@ -94,8 +95,8 @@ int main(int argc, char **argv) { if (!stlplus::folder_exists(sOutDir)) stlplus::folder_create( sOutDir ); - string jpg_filenameL = sImg1; - string jpg_filenameR = sImg2; + const string jpg_filenameL = sImg1; + const string jpg_filenameR = sImg2; Image imageL, imageR; ReadImage(jpg_filenameL.c_str(), &imageL); @@ -146,7 +147,7 @@ int main(int argc, char **argv) { std::vector vec_PutativeMatches; //-- Perform matching -> find Nearest neighbor, filtered with Distance ratio { -// Define a matcher and a metric to find corresponding points + // Define a matcher and a metric to find corresponding points typedef SIFT_Regions::DescriptorT DescriptorT; typedef L2_Vectorized Metric; typedef ArrayMatcherBruteForce MatcherT; diff --git a/src/openMVG_Samples/robust_essential/robust_essential.cpp b/src/openMVG_Samples/robust_essential/robust_essential.cpp index cecb0697b8..f23ae1d920 100644 --- a/src/openMVG_Samples/robust_essential/robust_essential.cpp +++ b/src/openMVG_Samples/robust_essential/robust_essential.cpp @@ -26,6 +26,7 @@ using namespace openMVG; using namespace openMVG::matching; +using namespace openMVG::image; using namespace svg; using namespace std; diff --git a/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp b/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp index e7b45f5d31..e730e024fa 100644 --- a/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp +++ b/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp @@ -31,6 +31,7 @@ #include using namespace openMVG; +using namespace openMVG::image; using namespace openMVG::matching; using namespace openMVG::bundle_adjustment; using namespace svg; diff --git a/src/openMVG_Samples/robust_essential_spherical/robust_essential_spherical.cpp b/src/openMVG_Samples/robust_essential_spherical/robust_essential_spherical.cpp index db99210930..b8cc1fff3e 100644 --- a/src/openMVG_Samples/robust_essential_spherical/robust_essential_spherical.cpp +++ b/src/openMVG_Samples/robust_essential_spherical/robust_essential_spherical.cpp @@ -28,6 +28,7 @@ #include using namespace openMVG; +using namespace openMVG::image; using namespace openMVG::matching; using namespace openMVG::robust; using namespace svg; diff --git a/src/openMVG_Samples/robust_fundamental/robust_fundamental.cpp b/src/openMVG_Samples/robust_fundamental/robust_fundamental.cpp index abd7e49df8..a4ed4df778 100644 --- a/src/openMVG_Samples/robust_fundamental/robust_fundamental.cpp +++ b/src/openMVG_Samples/robust_fundamental/robust_fundamental.cpp @@ -23,6 +23,7 @@ #include using namespace openMVG; +using namespace openMVG::image; using namespace openMVG::matching; using namespace openMVG::robust; using namespace svg; diff --git a/src/openMVG_Samples/robust_fundamental_guided/robust_fundamental_guided.cpp b/src/openMVG_Samples/robust_fundamental_guided/robust_fundamental_guided.cpp index 7d76348483..1bcb1141d2 100644 --- a/src/openMVG_Samples/robust_fundamental_guided/robust_fundamental_guided.cpp +++ b/src/openMVG_Samples/robust_fundamental_guided/robust_fundamental_guided.cpp @@ -25,6 +25,7 @@ #include using namespace openMVG; +using namespace openMVG::image; using namespace openMVG::matching; using namespace openMVG::robust; using namespace svg; diff --git a/src/openMVG_Samples/robust_homography/robust_homography.cpp b/src/openMVG_Samples/robust_homography/robust_homography.cpp index b6e1c671a8..93987bdfb9 100644 --- a/src/openMVG_Samples/robust_homography/robust_homography.cpp +++ b/src/openMVG_Samples/robust_homography/robust_homography.cpp @@ -24,6 +24,7 @@ #include using namespace openMVG; +using namespace openMVG::image; using namespace openMVG::matching; using namespace openMVG::robust; using namespace svg; diff --git a/src/openMVG_Samples/robust_homography_guided/robust_homography_guided.cpp b/src/openMVG_Samples/robust_homography_guided/robust_homography_guided.cpp index c4b6e4a3ba..fd3d28eb83 100644 --- a/src/openMVG_Samples/robust_homography_guided/robust_homography_guided.cpp +++ b/src/openMVG_Samples/robust_homography_guided/robust_homography_guided.cpp @@ -25,6 +25,7 @@ #include using namespace openMVG; +using namespace openMVG::image; using namespace openMVG::matching; using namespace openMVG::robust; using namespace svg; diff --git a/src/openMVG_Samples/siftPutativeMatches/siftmatch.cpp b/src/openMVG_Samples/siftPutativeMatches/siftmatch.cpp index 3c2179c380..3f547ad4c9 100644 --- a/src/openMVG_Samples/siftPutativeMatches/siftmatch.cpp +++ b/src/openMVG_Samples/siftPutativeMatches/siftmatch.cpp @@ -21,6 +21,7 @@ #include using namespace openMVG; +using namespace openMVG::image; using namespace openMVG::matching; using namespace svg; using namespace std; diff --git a/src/openMVG_Samples/undisto_Brown/undistoBrown.cpp b/src/openMVG_Samples/undisto_Brown/undistoBrown.cpp index d7f6510b9a..dacc27f782 100644 --- a/src/openMVG_Samples/undisto_Brown/undistoBrown.cpp +++ b/src/openMVG_Samples/undisto_Brown/undistoBrown.cpp @@ -16,6 +16,7 @@ #include using namespace openMVG; +using namespace openMVG::image; using namespace std; // A simple container and undistort function for the Brown's distortion model [1] diff --git a/src/software/SfM/main_ComputeFeatures.cpp b/src/software/SfM/main_ComputeFeatures.cpp index ed948f4dbe..9609c07bcb 100644 --- a/src/software/SfM/main_ComputeFeatures.cpp +++ b/src/software/SfM/main_ComputeFeatures.cpp @@ -23,6 +23,7 @@ #include using namespace openMVG; +using namespace openMVG::image; using namespace std; features::EDESCRIBER_PRESET stringToEnum(const std::string & sPreset) diff --git a/src/software/SfM/main_ComputeFeatures_OpenCV.cpp b/src/software/SfM/main_ComputeFeatures_OpenCV.cpp index fb2f39475c..f6bcb0b8dc 100644 --- a/src/software/SfM/main_ComputeFeatures_OpenCV.cpp +++ b/src/software/SfM/main_ComputeFeatures_OpenCV.cpp @@ -27,6 +27,7 @@ #include using namespace openMVG; +using namespace openMVG::image; using namespace std; enum eGeometricModel diff --git a/src/software/SfM/main_ComputeSfM_DataColor.cpp b/src/software/SfM/main_ComputeSfM_DataColor.cpp index 46d59ad9a4..78287b4105 100644 --- a/src/software/SfM/main_ComputeSfM_DataColor.cpp +++ b/src/software/SfM/main_ComputeSfM_DataColor.cpp @@ -14,6 +14,7 @@ #include using namespace openMVG; +using namespace openMVG::image; /// Find the color of the SfM_Data Landmarks/structure void ColorizeTracks( diff --git a/src/software/SfM/main_SfMInit_ImageListing.cpp b/src/software/SfM/main_SfMInit_ImageListing.cpp index 076c6bc1b1..d8ea535632 100644 --- a/src/software/SfM/main_SfMInit_ImageListing.cpp +++ b/src/software/SfM/main_SfMInit_ImageListing.cpp @@ -23,6 +23,7 @@ #include using namespace openMVG; +using namespace openMVG::image; /// Check that Kmatrix is a string like "f;0;ppx;0;f;ppy;0;0;1" /// With f,ppx,ppy as valid numerical value @@ -178,11 +179,11 @@ int main(int argc, char **argv) const std::string sImageFilename = stlplus::create_filespec( sImageDir, *iter_image ); // Test if the image format is supported: - if (openMVG::GetFormat(sImageFilename.c_str()) == openMVG::Unknown) + if (openMVG::image::GetFormat(sImageFilename.c_str()) == openMVG::image::Unknown) continue; // image cannot be opened Image image; - if (openMVG::ReadImage( sImageFilename.c_str(), &image)) { + if (openMVG::image::ReadImage( sImageFilename.c_str(), &image)) { width = image.Width(); height = image.Height(); ppx = width / 2.0; diff --git a/src/software/SfM/main_openMVG2CMPMVS.cpp b/src/software/SfM/main_openMVG2CMPMVS.cpp index b9a871f492..8188e30e4a 100644 --- a/src/software/SfM/main_openMVG2CMPMVS.cpp +++ b/src/software/SfM/main_openMVG2CMPMVS.cpp @@ -9,6 +9,7 @@ #include "openMVG/image/image.hpp" using namespace openMVG; +using namespace openMVG::image; #include "third_party/cmdLine/cmdLine.h" #include "third_party/progress/progress.hpp" diff --git a/src/software/SfM/main_openMVG2MESHLAB.cpp b/src/software/SfM/main_openMVG2MESHLAB.cpp index 62158d4be3..2d9c04620c 100644 --- a/src/software/SfM/main_openMVG2MESHLAB.cpp +++ b/src/software/SfM/main_openMVG2MESHLAB.cpp @@ -10,6 +10,7 @@ #include "openMVG/image/image.hpp" using namespace openMVG; +using namespace openMVG::image; #include "third_party/cmdLine/cmdLine.h" #include "third_party/stlplus3/filesystemSimplified/file_system.hpp" diff --git a/src/software/SfM/main_openMVG2PMVS.cpp b/src/software/SfM/main_openMVG2PMVS.cpp index 306fa3bb1a..223be3c8d9 100644 --- a/src/software/SfM/main_openMVG2PMVS.cpp +++ b/src/software/SfM/main_openMVG2PMVS.cpp @@ -9,6 +9,7 @@ #include "openMVG/image/image.hpp" using namespace openMVG; +using namespace openMVG::image; #include "third_party/cmdLine/cmdLine.h" #include "third_party/progress/progress.hpp" diff --git a/src/software/SfMViewer/main.cpp b/src/software/SfMViewer/main.cpp index 306456ceb4..28cd9c4f92 100644 --- a/src/software/SfMViewer/main.cpp +++ b/src/software/SfMViewer/main.cpp @@ -19,6 +19,7 @@ #include "third_party/cmdLine/cmdLine.h" using namespace openMVG; +using namespace openMVG::image; static int running = 1; static SfM_Data sfm_data; diff --git a/src/software/colorHarmonize/colorHarmonizeEngineGlobal.cpp b/src/software/colorHarmonize/colorHarmonizeEngineGlobal.cpp index 92acbb7adc..9b762210a9 100644 --- a/src/software/colorHarmonize/colorHarmonizeEngineGlobal.cpp +++ b/src/software/colorHarmonize/colorHarmonizeEngineGlobal.cpp @@ -43,6 +43,7 @@ namespace openMVG{ using namespace lemon; +using namespace openMVG::image; using namespace openMVG::matching; using namespace openMVG::lInfinity; From 2e101c47f517c5bb376a66e9b8e495e497ac5c71 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Wed, 20 May 2015 09:25:45 +0200 Subject: [PATCH 10/52] Move split module to stl module. #300 --- src/openMVG/matching_image_collection/Pair_Builder.hpp | 4 ++-- src/openMVG/{split => stl}/CMakeLists.txt | 0 src/openMVG/{split => stl}/split.hpp | 0 src/openMVG/{split => stl}/split_test.cpp | 0 src/openMVG_Samples/sensorWidthDatabase/ParseDatabase.hpp | 4 ++-- src/openMVG_Samples/sensorWidthDatabase/datasheet.hpp | 8 ++++---- src/software/SfM/SfMIOHelper.hpp | 4 ++-- src/software/SfM/main_SfMInit_ImageListing.cpp | 5 +++-- 8 files changed, 13 insertions(+), 12 deletions(-) rename src/openMVG/{split => stl}/CMakeLists.txt (100%) rename src/openMVG/{split => stl}/split.hpp (100%) rename src/openMVG/{split => stl}/split_test.cpp (100%) diff --git a/src/openMVG/matching_image_collection/Pair_Builder.hpp b/src/openMVG/matching_image_collection/Pair_Builder.hpp index 1c50ed3265..6ff3988fa7 100644 --- a/src/openMVG/matching_image_collection/Pair_Builder.hpp +++ b/src/openMVG/matching_image_collection/Pair_Builder.hpp @@ -7,7 +7,7 @@ #pragma once #include "openMVG/types.hpp" -#include "openMVG/split/split.hpp" +#include "openMVG/stl/split.hpp" #include #include @@ -56,7 +56,7 @@ static bool loadPairs( while(std::getline( in, sValue ) ) { vec_str.clear(); - split( sValue, " ", vec_str ); + std::split( sValue, " ", vec_str ); const size_t str_size = vec_str.size(); if (str_size < 2) { diff --git a/src/openMVG/split/CMakeLists.txt b/src/openMVG/stl/CMakeLists.txt similarity index 100% rename from src/openMVG/split/CMakeLists.txt rename to src/openMVG/stl/CMakeLists.txt diff --git a/src/openMVG/split/split.hpp b/src/openMVG/stl/split.hpp similarity index 100% rename from src/openMVG/split/split.hpp rename to src/openMVG/stl/split.hpp diff --git a/src/openMVG/split/split_test.cpp b/src/openMVG/stl/split_test.cpp similarity index 100% rename from src/openMVG/split/split_test.cpp rename to src/openMVG/stl/split_test.cpp diff --git a/src/openMVG_Samples/sensorWidthDatabase/ParseDatabase.hpp b/src/openMVG_Samples/sensorWidthDatabase/ParseDatabase.hpp index d7be551db4..180bfe86cb 100644 --- a/src/openMVG_Samples/sensorWidthDatabase/ParseDatabase.hpp +++ b/src/openMVG_Samples/sensorWidthDatabase/ParseDatabase.hpp @@ -1,7 +1,7 @@ #ifndef PARSE_DATABASE_HPP #define PARSE_DATABASE_HPP -#include "openMVG/split/split.hpp" +#include "openMVG/stl/split.hpp" #include "datasheet.hpp" #include @@ -28,7 +28,7 @@ bool parseDatabase( const std::string& sfileDatabase, std::vector& ve if ( line[0] != '#' ) { std::vector values; - split( line, ";", values ); + std::split( line, ";", values ); if ( values.size() == 3 ) { const std::string brand = values[0]; diff --git a/src/openMVG_Samples/sensorWidthDatabase/datasheet.hpp b/src/openMVG_Samples/sensorWidthDatabase/datasheet.hpp index 018da16ed9..98e0301e83 100644 --- a/src/openMVG_Samples/sensorWidthDatabase/datasheet.hpp +++ b/src/openMVG_Samples/sensorWidthDatabase/datasheet.hpp @@ -1,7 +1,7 @@ #ifndef DATASHEET_HPP #define DATASHEET_HPP -#include "openMVG/split/split.hpp" +#include "openMVG/stl/split.hpp" #include // Database structure @@ -22,7 +22,7 @@ struct Datasheet { bool isEqual = false; std::vector vec_brand; - split( ds._brand, " ", vec_brand ); + std::split( ds._brand, " ", vec_brand ); std::string brandlower = _brand; for ( int index = 0; index < brandlower.length(); index++ ) @@ -44,9 +44,9 @@ struct Datasheet { std::vector vec_model1; - split( ds._model, " ", vec_model1 ); + std::split( ds._model, " ", vec_model1 ); std::vector vec_model2; - split( _model, " ", vec_model2 ); + std::split( _model, " ", vec_model2 ); bool isAllFind = true; for ( std::vector::const_iterator iter_model1 = vec_model1.begin(); iter_model1 != vec_model1.end(); diff --git a/src/software/SfM/SfMIOHelper.hpp b/src/software/SfM/SfMIOHelper.hpp index 5d23e6b457..0456c0325e 100644 --- a/src/software/SfM/SfMIOHelper.hpp +++ b/src/software/SfM/SfMIOHelper.hpp @@ -9,7 +9,7 @@ #define OPENMVG_SFM_IO_H #include "openMVG/numeric/numeric.h" -#include "openMVG/split/split.hpp" +#include "openMVG/stl/split.hpp" #include #include @@ -74,7 +74,7 @@ static bool loadImageList( std::vector & vec_camImageName, while(getline( in, sValue ) ) { vec_str.clear(); - split( sValue, ";", vec_str ); + std::split( sValue, ";", vec_str ); if (vec_str.size() == 1) { std::cerr << "Invalid input file" << std::endl; diff --git a/src/software/SfM/main_SfMInit_ImageListing.cpp b/src/software/SfM/main_SfMInit_ImageListing.cpp index d8ea535632..c1310236a2 100644 --- a/src/software/SfM/main_SfMInit_ImageListing.cpp +++ b/src/software/SfM/main_SfMInit_ImageListing.cpp @@ -8,7 +8,7 @@ #include "openMVG_Samples/sensorWidthDatabase/ParseDatabase.hpp" #include "openMVG/image/image.hpp" -#include "openMVG/split/split.hpp" +#include "openMVG/stl/split.hpp" #include "openMVG/sfm/sfm.hpp" @@ -24,13 +24,14 @@ using namespace openMVG; using namespace openMVG::image; +using namespace openMVG::exif; /// Check that Kmatrix is a string like "f;0;ppx;0;f;ppy;0;0;1" /// With f,ppx,ppy as valid numerical value bool checkIntrinsicStringValidity(const std::string & Kmatrix, double & focal, double & ppx, double & ppy) { std::vector vec_str; - split( Kmatrix, ";", vec_str ); + std::split( Kmatrix, ";", vec_str ); if (vec_str.size() != 9) { std::cerr << "\n Missing ';' character" << std::endl; return false; From 1e26a89007d474f6fca0dfa9ae0a734532c39b77 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Wed, 20 May 2015 09:30:51 +0200 Subject: [PATCH 11/52] Move split module to stl module. #300 --- src/openMVG/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/openMVG/CMakeLists.txt b/src/openMVG/CMakeLists.txt index b9d37e401a..e279ec268c 100644 --- a/src/openMVG/CMakeLists.txt +++ b/src/openMVG/CMakeLists.txt @@ -11,7 +11,6 @@ ADD_SUBDIRECTORY(matching_image_collection) ADD_SUBDIRECTORY(multiview) ADD_SUBDIRECTORY(numeric) ADD_SUBDIRECTORY(robust_estimation) -ADD_SUBDIRECTORY(split) ADD_SUBDIRECTORY(tracks) ADD_SUBDIRECTORY(color_harmonization) ADD_SUBDIRECTORY(system) From ee4d16b79b2079d5c899bfc865175bb30fc3c0d7 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Wed, 20 May 2015 12:11:39 +0200 Subject: [PATCH 12/52] Update some namespaces. #300 --- docs/sphinx/rst/openMVG/openMVG.rst | 2 +- .../main_computeMatchesCasHas.cpp | 6 +- src/openMVG/CMakeLists.txt | 2 +- src/openMVG/cameras/Camera_Intrinsics.hpp | 8 +-- src/openMVG/{exif_IO => exif}/CMakeLists.txt | 0 src/openMVG/{exif_IO => exif}/exif_IO.hpp | 6 ++ .../{exif_IO => exif}/exif_IO_EasyExif.hpp | 10 +++- .../{exif_IO => exif}/exif_IO_test.cpp | 1 + src/openMVG/graph/connectedComponent.hpp | 10 ++-- src/openMVG/graph/connectedComponent_test.cpp | 2 +- src/openMVG/graph/graph_builder.hpp | 4 +- src/openMVG/graph/graph_graphviz_export.hpp | 58 +++++++++---------- src/openMVG/graph/triplet_finder.hpp | 16 ++--- src/openMVG/graph/triplet_finder_test.cpp | 2 +- .../global_translations_fromTij_test.cpp | 2 +- .../global_translations_fromTriplets_test.cpp | 6 +- src/openMVG/matching/matcher_brute_force.hpp | 2 +- .../Pair_Builder.hpp | 2 +- .../multiview/translation_averaging_test.cpp | 6 +- .../robust_estimation/guided_matching.hpp | 4 +- .../global/GlobalSfM_rotation_averaging.cpp | 14 ++--- .../global/GlobalSfM_rotation_averaging.hpp | 2 +- .../GlobalSfM_translation_averaging.cpp | 24 ++++---- .../GlobalSfM_translation_averaging.hpp | 2 +- .../sfm_global_engine_relative_motions.cpp | 4 +- .../pipelines/sequential/sequential_SfM.cpp | 6 +- .../structure_estimator.hpp | 6 +- src/openMVG/sfm/sfm_data_filters.hpp | 8 +-- src/openMVG/sfm/sfm_data_filters_frustum.cpp | 2 +- src/openMVG/sfm/sfm_data_io.cpp | 4 +- src/openMVG/sfm/sfm_data_triangulation.hpp | 8 +-- src/openMVG/stl/hash.hpp | 4 +- src/openMVG/stl/indexed_sort.hpp | 4 +- src/openMVG/stl/split.hpp | 4 +- src/openMVG/stl/split_test.cpp | 12 ++-- src/openMVG/stl/stlMap.hpp | 8 +-- src/openMVG/system/timer.cpp | 3 +- src/openMVG/system/timer.hpp | 2 + .../exifParsing/exifParsing.cpp | 6 +- .../sensorWidthDatabase/ParseDatabase.hpp | 2 +- .../sensorWidthDatabase/datasheet.hpp | 6 +- src/software/SfM/SfMIOHelper.hpp | 2 +- src/software/SfM/main_ComputeFeatures.cpp | 2 +- src/software/SfM/main_ComputeMatches.cpp | 4 +- .../SfM/main_ComputeSfM_DataColor.cpp | 6 +- .../main_ComputeStructureFromKnownPoses.cpp | 2 +- src/software/SfM/main_ConvertList.cpp | 2 +- src/software/SfM/main_FrustumFiltering.cpp | 2 +- src/software/SfM/main_GlobalSfM.cpp | 2 +- src/software/SfM/main_IncrementalSfM.cpp | 2 +- .../SfM/main_SfMInit_ImageListing.cpp | 4 +- .../colorHarmonizeEngineGlobal.cpp | 18 +++--- .../colorHarmonize/main_ColHarmonize.cpp | 2 +- 53 files changed, 170 insertions(+), 158 deletions(-) rename src/openMVG/{exif_IO => exif}/CMakeLists.txt (100%) rename src/openMVG/{exif_IO => exif}/exif_IO.hpp (88%) rename src/openMVG/{exif_IO => exif}/exif_IO_EasyExif.hpp (97%) rename src/openMVG/{exif_IO => exif}/exif_IO_test.cpp (97%) diff --git a/docs/sphinx/rst/openMVG/openMVG.rst b/docs/sphinx/rst/openMVG/openMVG.rst index 249ea250bf..039a292bc1 100644 --- a/docs/sphinx/rst/openMVG/openMVG.rst +++ b/docs/sphinx/rst/openMVG/openMVG.rst @@ -34,7 +34,7 @@ Todo: * **graph** - Manipulation of graphs (connected CC, triplet listing...) -* **exif_IO** - Collection of tools to extract and use image EXIF data. +* **exif** - Collection of tools to extract and use image EXIF data. * **matching_image_collection** - Functions to perform local matching and geometric filtering of putative correspondences in image collections. diff --git a/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp b/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp index 2fc821941c..c01330d89a 100644 --- a/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp +++ b/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp @@ -213,7 +213,7 @@ int main(int argc, char **argv) } { - Timer timer; + system::Timer timer; std::cout << "\n\n - EXTRACT FEATURES - " << std::endl; Image imageGray; @@ -284,7 +284,7 @@ int main(int argc, char **argv) case PAIR_FROM_FILE: std::cout << "user defined pairwise matching" << std::endl; break; } - Timer timer; + system::Timer timer; std::cout << "Use cascade Hashing matcher." << std::endl; Matcher_CascadeHashing_AllInMemory collectionMatcher(fDistRatio); if (collectionMatcher.loadData(*image_describer.get(), vec_fileNames, sOutDir)) @@ -337,7 +337,7 @@ int main(int argc, char **argv) ImageCollectionGeometricFilter collectionGeomFilter(feats_provider.get()); const double maxResidualError = 4.0; { - Timer timer; + system::Timer timer; std::cout << std::endl << " - GEOMETRIC FILTERING - " << std::endl; switch (eGeometricModelToCompute) { diff --git a/src/openMVG/CMakeLists.txt b/src/openMVG/CMakeLists.txt index e279ec268c..1f96653085 100644 --- a/src/openMVG/CMakeLists.txt +++ b/src/openMVG/CMakeLists.txt @@ -1,6 +1,6 @@ ADD_SUBDIRECTORY(bundle_adjustment) ADD_SUBDIRECTORY(cameras) -ADD_SUBDIRECTORY(exif_IO) +ADD_SUBDIRECTORY(exif) ADD_SUBDIRECTORY(features) ADD_SUBDIRECTORY(graph) ADD_SUBDIRECTORY(image) diff --git a/src/openMVG/cameras/Camera_Intrinsics.hpp b/src/openMVG/cameras/Camera_Intrinsics.hpp index fbcc45d1d3..f75a25b4b2 100644 --- a/src/openMVG/cameras/Camera_Intrinsics.hpp +++ b/src/openMVG/cameras/Camera_Intrinsics.hpp @@ -113,12 +113,12 @@ struct IntrinsicBase virtual std::size_t hashValue() const { size_t seed; - std::hash_combine(seed, static_cast(this->getType())); - std::hash_combine(seed, _w); - std::hash_combine(seed, _h); + stl::hash_combine(seed, static_cast(this->getType())); + stl::hash_combine(seed, _w); + stl::hash_combine(seed, _h); const std::vector params = this->getParams(); for (size_t i=0; i < params.size(); ++i) - std::hash_combine(seed, params[i]); + stl::hash_combine(seed, params[i]); return seed; } }; diff --git a/src/openMVG/exif_IO/CMakeLists.txt b/src/openMVG/exif/CMakeLists.txt similarity index 100% rename from src/openMVG/exif_IO/CMakeLists.txt rename to src/openMVG/exif/CMakeLists.txt diff --git a/src/openMVG/exif_IO/exif_IO.hpp b/src/openMVG/exif/exif_IO.hpp similarity index 88% rename from src/openMVG/exif_IO/exif_IO.hpp rename to src/openMVG/exif/exif_IO.hpp index 2878a0cf64..7a6ec1a5b7 100644 --- a/src/openMVG/exif_IO/exif_IO.hpp +++ b/src/openMVG/exif/exif_IO.hpp @@ -3,6 +3,9 @@ #include +namespace openMVG { +namespace exif { + class Exif_IO { public: @@ -28,5 +31,8 @@ class Exif_IO virtual std::string allExifData() const = 0; }; + +} // namespace exif +} // namespace openMVG #endif //EXIF_IO_HPP diff --git a/src/openMVG/exif_IO/exif_IO_EasyExif.hpp b/src/openMVG/exif/exif_IO_EasyExif.hpp similarity index 97% rename from src/openMVG/exif_IO/exif_IO_EasyExif.hpp rename to src/openMVG/exif/exif_IO_EasyExif.hpp index a174d64ef2..cb44bbd4ee 100644 --- a/src/openMVG/exif_IO/exif_IO_EasyExif.hpp +++ b/src/openMVG/exif/exif_IO_EasyExif.hpp @@ -1,14 +1,16 @@ #ifndef EXIF_IO_EASYEXIF_HPP #define EXIF_IO_EASYEXIF_HPP -#include "exif_IO.hpp" +#include "openMVG/exif/exif_IO.hpp" #include "third_party/easyexif/exif.h" #include -#include #include #include +namespace openMVG { +namespace exif { + class Exif_IO_EasyExif : public Exif_IO { public: @@ -138,4 +140,8 @@ class Exif_IO_EasyExif : public Exif_IO EXIFInfo exifInfo_; bool bHaveExifInfo_; }; + +} // namespace exif +} // namespace openMVG + #endif //EXIF_IO_EASYEXIF_HPP diff --git a/src/openMVG/exif_IO/exif_IO_test.cpp b/src/openMVG/exif/exif_IO_test.cpp similarity index 97% rename from src/openMVG/exif_IO/exif_IO_test.cpp rename to src/openMVG/exif/exif_IO_test.cpp index 84e4b01c4c..6c83994528 100644 --- a/src/openMVG/exif_IO/exif_IO_test.cpp +++ b/src/openMVG/exif/exif_IO_test.cpp @@ -8,6 +8,7 @@ using namespace std; using namespace openMVG; +using namespace openMVG::exif; const std::string sImg = stlplus::folder_part( diff --git a/src/openMVG/graph/connectedComponent.hpp b/src/openMVG/graph/connectedComponent.hpp index 44b2d254bd..f3dda4f1f9 100644 --- a/src/openMVG/graph/connectedComponent.hpp +++ b/src/openMVG/graph/connectedComponent.hpp @@ -11,10 +11,8 @@ #include #include -namespace openMVG -{ -namespace graphUtils -{ +namespace openMVG { +namespace graph { /// Export node of each CC (Connected Component) in a map template @@ -50,7 +48,7 @@ std::set CleanGraph_KeepLargestBiEdge_Nodes( // - keep the largest connected component. typedef lemon::ListGraph Graph; - graphUtils::indexedGraph putativeGraph(edges); + graph::indexedGraph putativeGraph(edges); /* if (!_sOutDirectory.empty()) { @@ -149,7 +147,7 @@ std::set CleanGraph_KeepLargestBiEdge_Nodes( return largestBiEdgeCC; } -} // namespace graphUtils +} // namespace graph } // namespace openMVG #endif // OPENMVG_GRAPH_CONNECTED_COMPONENT_H_ diff --git a/src/openMVG/graph/connectedComponent_test.cpp b/src/openMVG/graph/connectedComponent_test.cpp index f1591fc462..0e398f076d 100644 --- a/src/openMVG/graph/connectedComponent_test.cpp +++ b/src/openMVG/graph/connectedComponent_test.cpp @@ -99,7 +99,7 @@ TEST(exportGraphToMapSubgraphs, CC_Subgraph) { graph.addEdge(j,l); const std::map > map_subgraphs = - openMVG::graphUtils::exportGraphToMapSubgraphs(graph); + openMVG::graph::exportGraphToMapSubgraphs(graph); EXPECT_EQ(4, map_subgraphs.size()); EXPECT_EQ(5, map_subgraphs.at(0).size()); diff --git a/src/openMVG/graph/graph_builder.hpp b/src/openMVG/graph/graph_builder.hpp index 79ac6d32a3..e8cc7d5b5a 100644 --- a/src/openMVG/graph/graph_builder.hpp +++ b/src/openMVG/graph/graph_builder.hpp @@ -11,7 +11,7 @@ #include namespace openMVG { -namespace graphUtils { +namespace graph { // Structure used to keep information of an image graph: // - Build a graph (add nodes and connection between nodes) @@ -62,7 +62,7 @@ struct indexedGraph } }; -} // namespace graphUtils +} // namespace graph } // namespace openMVG #endif // OPENMVG_GRAPH_BUILDER__H_ diff --git a/src/openMVG/graph/graph_graphviz_export.hpp b/src/openMVG/graph/graph_graphviz_export.hpp index e7d6f61801..d0f6c44792 100644 --- a/src/openMVG/graph/graph_graphviz_export.hpp +++ b/src/openMVG/graph/graph_graphviz_export.hpp @@ -8,15 +8,12 @@ #ifndef OPENMVG_GRAPH_EXPORT_H_ #define OPENMVG_GRAPH_EXPORT_H_ -//#include - #include #include +#include namespace openMVG { -namespace graphUtils { - - using namespace std; +namespace graph { // Export an Image connection graph // to graphviz file format. @@ -33,10 +30,10 @@ namespace graphUtils { template bool exportToGraphvizFormat_Nodal( const GraphT & g, - ostream & os) + std::ostream & os) { - os << "graph 1 {" << endl; - os << "node [shape=circle]" << endl; + os << "graph 1 {" << std::endl; + os << "node [shape=circle]" << std::endl; //Export node label for(typename GraphT::NodeIt n(g); n!= lemon::INVALID; ++n) { @@ -45,7 +42,7 @@ bool exportToGraphvizFormat_Nodal( //-- Export arc (as the graph is bi-directional, export arc only one time) - map< std::pair, IndexT > map_arcs; + std::map< std::pair, IndexT > map_arcs; for(typename GraphT::ArcIt e(g); e!=lemon::INVALID; ++e) { if( map_arcs.end() == map_arcs.find(std::make_pair(IndexT(g.id(g.source(e))), IndexT(g.id(g.target(e))))) && @@ -55,14 +52,14 @@ bool exportToGraphvizFormat_Nodal( } } //os << "edge [style=bold]" << endl; - for ( map< std::pair, IndexT >::const_iterator iter = map_arcs.begin(); + for (std::map< std::pair, IndexT >::const_iterator iter = map_arcs.begin(); iter != map_arcs.end(); ++iter) { - os << " n" << iter->first.first << " -- " << " n" << iter->first.second << endl; + os << " n" << iter->first.first << " -- " << " n" << iter->first.second << std::endl; } - os << "}" << endl; + os << "}" << std::endl; return os.good(); } @@ -74,22 +71,21 @@ bool exportToGraphvizFormat_Image( const GraphT & g, const NodeMap & nodeMap, const EdgeMap & edgeMap, - ostream & os, bool bWeightedEdge=false) + std::ostream & os, bool bWeightedEdge = false) { - os << "graph 1 {" << endl; - os << "node [shape=none]" << endl; + os << "graph 1 {" << std::endl; + os << "node [shape=none]" << std::endl; //Export node label for(typename GraphT::NodeIt n(g); n!=lemon::INVALID; ++n) { os << " n" << g.id(n) - << "[ label =" - << - "< "<< endl - <<""<< endl - <<""<< endl - <<""<< endl - <<"
" << "\"" << nodeMap[n] <<"\"" <<"
"<< endl - <<">, cluster=1];"<< endl; + << "[ label =" + << "< "<< std::endl + << "" << std::endl + << "" << std::endl + << "" << std::endl + << "
" << "\"" << nodeMap[n] << "\"" << "
" << std::endl + << ">, cluster=1];" << std::endl; //os << " n" << g.id(n) // << " [ " @@ -97,7 +93,7 @@ bool exportToGraphvizFormat_Image( } //Export arc value - map< std::pair, IndexT > map_arcs; + std::map< std::pair, IndexT > map_arcs; for(typename GraphT::ArcIt e(g); e!=lemon::INVALID; ++e) { if( map_arcs.end() == map_arcs.find(std::make_pair(IndexT(g.id(g.source(e))), IndexT(g.id(g.target(e))))) && @@ -108,7 +104,7 @@ bool exportToGraphvizFormat_Image( } } - os << "edge [style=bold]" << endl; + os << "edge [style=bold]" << std::endl; for ( map< std::pair, IndexT>::const_iterator iter = map_arcs.begin(); iter != map_arcs.end(); ++iter) @@ -116,14 +112,14 @@ bool exportToGraphvizFormat_Image( if (bWeightedEdge) { os << " n" << iter->first.first << " -- " << " n" << iter->first.second - << " [label=\"" << iter->second << "\"]" << endl; + << " [label=\"" << iter->second << "\"]" << std::endl; } else { - os << " n" << iter->first.first << " -- " << " n" << iter->first.second << endl; + os << " n" << iter->first.first << " -- " << " n" << iter->first.second << std::endl; } } - os << "}" << endl; + os << "}" << std::endl; return os.good(); } @@ -132,16 +128,16 @@ void exportToGraphvizData(const std::string& sfile, const GraphT & graph){ //Prepare Data std::ofstream file(sfile.c_str()); - openMVG::graphUtils::exportToGraphvizFormat_Nodal(graph, file); + openMVG::graph::exportToGraphvizFormat_Nodal(graph, file); file.close(); //Use Graphviz const std::string cmd = "neato -Tsvg -O -Goverlap=scale -Gsplines=false " + sfile; - int ret = system(cmd.c_str()); + int ret = std::system(cmd.c_str()); (void)ret; } -} // namespace graphUtils +} // namespace graph } // namespace openMVG #endif // OPENMVG_GRAPH_EXPORT_H_ diff --git a/src/openMVG/graph/triplet_finder.hpp b/src/openMVG/graph/triplet_finder.hpp index a63ae539e3..c640736917 100644 --- a/src/openMVG/graph/triplet_finder.hpp +++ b/src/openMVG/graph/triplet_finder.hpp @@ -16,8 +16,8 @@ using namespace lemon; #include #include -namespace openMVG{ -namespace graphUtils{ +namespace openMVG { +namespace graph { /// Simple container for tuple of three value /// It is used to store the node id of triplets of a graph. @@ -117,31 +117,31 @@ bool List_Triplets(const GraphT & g, std::vector< Triplet > & vec_triplets) /// Return triplets contained in the graph build from IterablePairs template -static std::vector< graphUtils::Triplet > tripletListing( +static std::vector< graph::Triplet > tripletListing( const IterablePairs & pairs) { - std::vector< graphUtils::Triplet > vec_triplets; + std::vector< graph::Triplet > vec_triplets; indexedGraph putativeGraph(pairs); - graphUtils::List_Triplets(putativeGraph.g, vec_triplets); + graph::List_Triplets(putativeGraph.g, vec_triplets); //Change triplets to ImageIds for (size_t i = 0; i < vec_triplets.size(); ++i) { - graphUtils::Triplet & triplet = vec_triplets[i]; + graph::Triplet & triplet = vec_triplets[i]; IndexT I = triplet.i, J = triplet.j , K = triplet.k; I = (*putativeGraph.map_nodeMapIndex)[putativeGraph.g.nodeFromId(I)]; J = (*putativeGraph.map_nodeMapIndex)[putativeGraph.g.nodeFromId(J)]; K = (*putativeGraph.map_nodeMapIndex)[putativeGraph.g.nodeFromId(K)]; IndexT triplet_[3] = { I, J, K }; std::sort(&triplet_[0], &triplet_[3]); - triplet = graphUtils::Triplet(triplet_[0],triplet_[1],triplet_[2]); + triplet = graph::Triplet(triplet_[0],triplet_[1],triplet_[2]); } return vec_triplets; } -} // namespace graphUtils +} // namespace graph } // namespace openMVG #endif // OPENMVG_GRAPH_TRIPLET_FINDER_H diff --git a/src/openMVG/graph/triplet_finder_test.cpp b/src/openMVG/graph/triplet_finder_test.cpp index 483864045d..2e6a99287e 100644 --- a/src/openMVG/graph/triplet_finder_test.cpp +++ b/src/openMVG/graph/triplet_finder_test.cpp @@ -5,7 +5,7 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include "openMVG/graph/triplet_finder.hpp" -using namespace openMVG::graphUtils; +using namespace openMVG::graph; #include "CppUnitLite/TestHarness.h" #include "testing/testing.h" diff --git a/src/openMVG/linearProgramming/lInfinityCV/global_translations_fromTij_test.cpp b/src/openMVG/linearProgramming/lInfinityCV/global_translations_fromTij_test.cpp index 05c788fed4..ea883d9214 100644 --- a/src/openMVG/linearProgramming/lInfinityCV/global_translations_fromTij_test.cpp +++ b/src/openMVG/linearProgramming/lInfinityCV/global_translations_fromTij_test.cpp @@ -6,7 +6,7 @@ #include "openMVG/multiview/essential.hpp" #include "openMVG/graph/triplet_finder.hpp" -using namespace openMVG::graphUtils; +using namespace openMVG::graph; #include "third_party/vectorGraphics/svgDrawer.hpp" using namespace svg; diff --git a/src/openMVG/linearProgramming/lInfinityCV/global_translations_fromTriplets_test.cpp b/src/openMVG/linearProgramming/lInfinityCV/global_translations_fromTriplets_test.cpp index 3a794166d9..8029b96a09 100644 --- a/src/openMVG/linearProgramming/lInfinityCV/global_translations_fromTriplets_test.cpp +++ b/src/openMVG/linearProgramming/lInfinityCV/global_translations_fromTriplets_test.cpp @@ -6,7 +6,7 @@ #include "openMVG/multiview/essential.hpp" #include "openMVG/graph/triplet_finder.hpp" -using namespace openMVG::graphUtils; +using namespace openMVG::graph; #include "third_party/vectorGraphics/svgDrawer.hpp" using namespace svg; @@ -89,7 +89,7 @@ TEST(translation_averaging, globalTi_from_tijs_Triplets) { visibleCamPosToSVGSurface(d._C, "global_translations_from_triplets_GT.svg"); // List sucessives triplets of the large loop of camera - std::vector< graphUtils::Triplet > vec_triplets; + std::vector< graph::Triplet > vec_triplets; for (size_t i = 0; i < iNviews; ++i) { const size_t iPlus1 = modifiedMod(i+1,iNviews); @@ -105,7 +105,7 @@ TEST(translation_averaging, globalTi_from_tijs_Triplets) { for (size_t i = 0; i < vec_triplets.size(); ++i) { - const graphUtils::Triplet & triplet = vec_triplets[i]; + const graph::Triplet & triplet = vec_triplets[i]; size_t I = triplet.i, J = triplet.j , K = triplet.k; //-- Build camera alias over GT translations and rotations: diff --git a/src/openMVG/matching/matcher_brute_force.hpp b/src/openMVG/matching/matcher_brute_force.hpp index 31a6f1afcf..5dc592e31a 100644 --- a/src/openMVG/matching/matcher_brute_force.hpp +++ b/src/openMVG/matching/matcher_brute_force.hpp @@ -132,7 +132,7 @@ class ArrayMatcherBruteForce : public ArrayMatcher // Find the N minimum distances: const int maxMinFound = (int) min( size_t(NN), vec_distance.size()); - using namespace indexed_sort; + using namespace stl::indexed_sort; vector< sort_index_packet_ascend< DistanceType, int> > packet_vec(vec_distance.size()); sort_index_helper(packet_vec, &vec_distance[0], maxMinFound); diff --git a/src/openMVG/matching_image_collection/Pair_Builder.hpp b/src/openMVG/matching_image_collection/Pair_Builder.hpp index 6ff3988fa7..4c0a3c7b71 100644 --- a/src/openMVG/matching_image_collection/Pair_Builder.hpp +++ b/src/openMVG/matching_image_collection/Pair_Builder.hpp @@ -56,7 +56,7 @@ static bool loadPairs( while(std::getline( in, sValue ) ) { vec_str.clear(); - std::split( sValue, " ", vec_str ); + stl::split(sValue, " ", vec_str); const size_t str_size = vec_str.size(); if (str_size < 2) { diff --git a/src/openMVG/multiview/translation_averaging_test.cpp b/src/openMVG/multiview/translation_averaging_test.cpp index 55587e7185..59d12cc2d6 100644 --- a/src/openMVG/multiview/translation_averaging_test.cpp +++ b/src/openMVG/multiview/translation_averaging_test.cpp @@ -9,7 +9,7 @@ #include "openMVG/multiview/translation_averaging_solver.hpp" #include "openMVG/graph/triplet_finder.hpp" -using namespace openMVG::graphUtils; +using namespace openMVG::graph; #include "third_party/vectorGraphics/svgDrawer.hpp" using namespace svg; @@ -90,7 +90,7 @@ TEST(translation_averaging, globalTi_from_tijs_Triplets_ECCV14) { visibleCamPosToSVGSurface(d._C, "global_translations_from_triplets_GT.svg"); // List successive triplets of the large loop of camera - std::vector< graphUtils::Triplet > vec_triplets; + std::vector< graph::Triplet > vec_triplets; for (size_t i = 0; i < iNviews; ++i) { const size_t iPlus1 = modifiedMod(i+1,iNviews); @@ -106,7 +106,7 @@ TEST(translation_averaging, globalTi_from_tijs_Triplets_ECCV14) { for (size_t i = 0; i < vec_triplets.size(); ++i) { - const graphUtils::Triplet & triplet = vec_triplets[i]; + const graph::Triplet & triplet = vec_triplets[i]; size_t I = triplet.i, J = triplet.j , K = triplet.k; //-- Build camera alias over GT translations and rotations: diff --git a/src/openMVG/robust_estimation/guided_matching.hpp b/src/openMVG/robust_estimation/guided_matching.hpp index 6bf0688874..7c8bcb7783 100644 --- a/src/openMVG/robust_estimation/guided_matching.hpp +++ b/src/openMVG/robust_estimation/guided_matching.hpp @@ -235,8 +235,8 @@ void GuidedMatching_Fundamental_Fast( IndMatches & vec_corresponding_index) // Ouput corresponding index { // Looking for the corresponding points that have - // the satisfy: - // 1. an geometric distance below the provided Threshold + // to satisfy: + // 1. a geometric distance below the provided Threshold // 2. a distance ratio between descriptors of valid geometric correspondencess // // - Cluster left point according their epipolar line border intersection. diff --git a/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.cpp b/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.cpp index 603a18499c..20393af244 100644 --- a/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.cpp +++ b/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.cpp @@ -38,12 +38,12 @@ bool GlobalSfM_Rotation_AveragingSolver::Run( // Triplet inference (test over the composition error) //------------------- Pair_Set pairs = getPairs(relativeRotations); - std::vector< graphUtils::Triplet > vec_triplets = graphUtils::tripletListing(pairs); + std::vector< graph::Triplet > vec_triplets = graph::tripletListing(pairs); //-- Rejection triplet that are 'not' identity rotation (error to identity > 5°) TripletRotationRejection(5.0f, vec_triplets, relativeRotations); pairs = getPairs(relativeRotations); - const std::set set_remainingIds = graphUtils::CleanGraph_KeepLargestBiEdge_Nodes(pairs); + const std::set set_remainingIds = graph::CleanGraph_KeepLargestBiEdge_Nodes(pairs); if(set_remainingIds.empty()) return false; KeepOnlyReferencedElement(set_remainingIds, relativeRotations); @@ -126,7 +126,7 @@ bool GlobalSfM_Rotation_AveragingSolver::Run( /// angular error once rotation composition have been computed. void GlobalSfM_Rotation_AveragingSolver::TripletRotationRejection( const double max_angular_error, - std::vector< graphUtils::Triplet > & vec_triplets, + std::vector< graph::Triplet > & vec_triplets, RelativeRotations & relativeRotations) const { const size_t edges_start_count = relativeRotations.size(); @@ -135,7 +135,7 @@ void GlobalSfM_Rotation_AveragingSolver::TripletRotationRejection( RelativeRotations_map map_relatives_validated; // DETECTION OF ROTATION OUTLIERS - std::vector< graphUtils::Triplet > vec_triplets_validated; + std::vector< graph::Triplet > vec_triplets_validated; std::vector vec_errToIdentityPerTriplet; vec_errToIdentityPerTriplet.reserve(vec_triplets.size()); @@ -143,7 +143,7 @@ void GlobalSfM_Rotation_AveragingSolver::TripletRotationRejection( // Error to identity rotation. for (size_t i = 0; i < vec_triplets.size(); ++i) { - const graphUtils::Triplet & triplet = vec_triplets[i]; + const graph::Triplet & triplet = vec_triplets[i]; const IndexT I = triplet.i, J = triplet.j , K = triplet.k; //-- Find the three rotations @@ -203,8 +203,8 @@ void GlobalSfM_Rotation_AveragingSolver::TripletRotationRejection( // update to keep only useful triplets relativeRotations.clear(); relativeRotations.reserve(map_relatives.size()); - std::transform(map_relatives.begin(), map_relatives.end(), std::back_inserter(relativeRotations), std::RetrieveValue()); - std::transform(map_relatives.begin(), map_relatives.end(), std::inserter(used_pairs, used_pairs.begin()), std::RetrieveKey()); + std::transform(map_relatives.begin(), map_relatives.end(), std::back_inserter(relativeRotations), stl::RetrieveValue()); + std::transform(map_relatives.begin(), map_relatives.end(), std::inserter(used_pairs, used_pairs.begin()), stl::RetrieveKey()); // Display statistics about rotation triplets error: std::cout << "\nStatistics about rotation triplets:" << std::endl; diff --git a/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.hpp b/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.hpp index 0afc9b94fc..13bb4efcb0 100644 --- a/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.hpp +++ b/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.hpp @@ -50,7 +50,7 @@ class GlobalSfM_Rotation_AveragingSolver /// angular error once rotation composition have been computed. void TripletRotationRejection( const double max_angular_error, - std::vector< graphUtils::Triplet > & vec_triplets, + std::vector< graph::Triplet > & vec_triplets, rotation_averaging::RelativeRotations & relativeRotations) const; }; diff --git a/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp b/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp index 7d25149efb..7a71a2135f 100644 --- a/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp +++ b/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp @@ -43,7 +43,7 @@ bool GlobalSfM_Translation_AveragingSolver::Run( // Assert relative matches only share index between the relative poseId defined by the global rotations matching::PairWiseMatches map_Matches_Ecpy = matches_provider->_pairWise_matches; std::set set_remainingIds; - std::transform(map_globalR.begin(), map_globalR.end(), std::inserter(set_remainingIds, set_remainingIds.begin()), RetrieveKey()); + std::transform(map_globalR.begin(), map_globalR.end(), std::inserter(set_remainingIds, set_remainingIds.begin()), stl::RetrieveKey()); KeepOnlyReferencedElement(set_remainingIds, map_Matches_Ecpy); // Compute the translations and save them to vec_initialRijTijEstimates: @@ -56,8 +56,8 @@ bool GlobalSfM_Translation_AveragingSolver::Run( // Keep the largest Biedge connected component graph of relative translations Pair_Set pairs; - std::transform(vec_initialRijTijEstimates.begin(), vec_initialRijTijEstimates.end(), std::inserter(pairs, pairs.begin()), std::RetrieveKey()); - set_remainingIds = openMVG::graphUtils::CleanGraph_KeepLargestBiEdge_Nodes(pairs, "./"); + std::transform(vec_initialRijTijEstimates.begin(), vec_initialRijTijEstimates.end(), std::inserter(pairs, pairs.begin()), stl::RetrieveKey()); + set_remainingIds = openMVG::graph::CleanGraph_KeepLargestBiEdge_Nodes(pairs, "./"); KeepOnlyReferencedElement(set_remainingIds, map_Matches_Ecpy); KeepOnlyReferencedElement(set_remainingIds, vec_initialRijTijEstimates); KeepOnlyReferencedElement(set_remainingIds, tripletWise_matches); @@ -106,7 +106,7 @@ bool GlobalSfM_Translation_AveragingSolver::Translation_averaging( rel.first = Pair(_reindexForward[rel.first.first], _reindexForward[rel.first.second]); } - openMVG::Timer timerLP_translation; + openMVG::system::Timer timerLP_translation; switch(eTranslationAveragingMethod) { @@ -262,13 +262,13 @@ void GlobalSfM_Translation_AveragingSolver::Compute_translations( // List putative triplets const Pair_Set pairs = getPairs(map_Matches_E); - std::vector< graphUtils::Triplet > vec_triplets = graphUtils::tripletListing(pairs); + std::vector< graph::Triplet > vec_triplets = graph::tripletListing(pairs); std::cout << "#Triplets: " << vec_triplets.size() << std::endl; // Compute putative translations with an edge coverage algorithm - openMVG::Timer timerLP_triplet; + openMVG::system::Timer timerLP_triplet; // Compute relative translations over the graph of putative triplets ComputePutativeTranslation_EdgesCoverage( @@ -297,7 +297,7 @@ void GlobalSfM_Translation_AveragingSolver::ComputePutativeTranslation_EdgesCove const Hash_Map & map_globalR, const Features_Provider * normalized_features_provider, const matching::PairWiseMatches & map_Matches_E, - const std::vector< graphUtils::Triplet > & vec_triplets, + const std::vector< graph::Triplet > & vec_triplets, RelativeInfo_Vec & vec_initialEstimates, matching::PairWiseMatches & newpairMatches) { @@ -308,7 +308,7 @@ void GlobalSfM_Translation_AveragingSolver::ComputePutativeTranslation_EdgesCove #endif for (int i = 0; i < (int)vec_triplets.size(); ++i) { - const graphUtils::Triplet & triplet = vec_triplets[i]; + const graph::Triplet & triplet = vec_triplets[i]; const IndexT I = triplet.i, J = triplet.j , K = triplet.k; PairWiseMatches map_matchesIJK; @@ -350,7 +350,7 @@ void GlobalSfM_Translation_AveragingSolver::ComputePutativeTranslation_EdgesCove for (size_t i = 0; i < vec_triplets.size(); ++i) { - const graphUtils::Triplet & triplet = vec_triplets[i]; + const graph::Triplet & triplet = vec_triplets[i]; const IndexT I = triplet.i, J = triplet.j , K = triplet.k; // Add three edges set_edges.insert(std::make_pair(std::min(I,J), std::max(I,J))); @@ -395,7 +395,7 @@ void GlobalSfM_Translation_AveragingSolver::ComputePutativeTranslation_EdgesCove // Find the triplet that contain the given edge for (size_t i = 0; i < vec_triplets.size(); ++i) { - const graphUtils::Triplet & triplet = vec_triplets[i]; + const graph::Triplet & triplet = vec_triplets[i]; if (triplet.contain(edge)) { vec_possibleTriplets.push_back(i); @@ -412,7 +412,7 @@ void GlobalSfM_Translation_AveragingSolver::ComputePutativeTranslation_EdgesCove if (m_mutexSet.count(edge)) continue; - using namespace indexed_sort; + using namespace stl::indexed_sort; std::vector< sort_index_packet_descend < size_t, size_t> > packet_vec(vec_commonTracksPerTriplets.size()); sort_index_helper(packet_vec, &vec_commonTracksPerTriplets[0]); @@ -426,7 +426,7 @@ void GlobalSfM_Translation_AveragingSolver::ComputePutativeTranslation_EdgesCove // Search the possible triplet: for (size_t i = 0; i < vec_possibleTriplets.size(); ++i) { - const graphUtils::Triplet & triplet = vec_triplets[vec_possibleTriplets[i]]; + const graph::Triplet & triplet = vec_triplets[vec_possibleTriplets[i]]; const IndexT I = triplet.i, J = triplet.j , K = triplet.k; { PairWiseMatches map_matchesIJK; diff --git a/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.hpp b/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.hpp index 439f6c79b2..93f0bb2f6e 100644 --- a/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.hpp +++ b/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.hpp @@ -68,7 +68,7 @@ class GlobalSfM_Translation_AveragingSolver const Hash_Map & map_globalR, const Features_Provider * normalized_features_provider, const matching::PairWiseMatches & map_Matches_E, - const std::vector< graphUtils::Triplet > & vec_triplets, + const std::vector< graph::Triplet > & vec_triplets, RelativeInfo_Vec & vec_initialEstimates, matching::PairWiseMatches & newpairMatches); diff --git a/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp b/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp index 6adbcb8b36..e9a8772e4b 100644 --- a/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp +++ b/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp @@ -106,7 +106,7 @@ bool GlobalSfMReconstructionEngine_RelativeMotions::Process() { //------------------- { const Pair_Set pairs = _matches_provider->getPairs(); - const std::set set_remainingIds = graphUtils::CleanGraph_KeepLargestBiEdge_Nodes(pairs, _sOutDirectory); + const std::set set_remainingIds = graph::CleanGraph_KeepLargestBiEdge_Nodes(pairs, _sOutDirectory); if(set_remainingIds.empty()) { std::cout << "Invalid input image graph for global SfM" << std::endl; @@ -331,7 +331,7 @@ bool GlobalSfMReconstructionEngine_RelativeMotions::Compute_Initial_Structure() { IndexT countRemoved = 0; - openMVG::Timer timer; + openMVG::system::Timer timer; const IndexT trackCountBefore = _sfm_data.GetLandmarks().size(); SfM_Data_Structure_Computation_Blind structure_estimator(true); diff --git a/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp b/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp index 2e86041a8a..535cb81089 100644 --- a/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp +++ b/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp @@ -213,7 +213,7 @@ bool SequentialSfMReconstructionEngine::ChooseInitialPair(Pair & initialPairInde } } // sort the Pairs in descending order according their correspondences count - using namespace indexed_sort; + using namespace stl::indexed_sort; std::vector< sort_index_packet_descend< size_t, size_t> > packet_vec(vec_NbMatchesPerPair.size()); sort_index_helper(packet_vec, &vec_NbMatchesPerPair[0], std::min((size_t)10, vec_NbMatchesPerPair.size())); @@ -616,7 +616,7 @@ bool SequentialSfMReconstructionEngine::FindImagesWithPossibleResection std::set reconstructed_trackId; std::transform(_sfm_data.GetLandmarks().begin(), _sfm_data.GetLandmarks().end(), std::inserter(reconstructed_trackId, reconstructed_trackId.begin()), - RetrieveKey() ); + stl::RetrieveKey()); // Estimate the image on which we could compute a resection safely // -> We first find the camera with the greatest number of matches @@ -726,7 +726,7 @@ bool SequentialSfMReconstructionEngine::Resection(size_t viewIndex) std::set reconstructed_trackId; std::transform(_sfm_data.GetLandmarks().begin(), _sfm_data.GetLandmarks().end(), std::inserter(reconstructed_trackId, reconstructed_trackId.begin()), - RetrieveKey() ); + stl::RetrieveKey()); std::set set_trackIdForResection; set_intersection(set_tracksIds.begin(), set_tracksIds.end(), diff --git a/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.hpp b/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.hpp index e9d08d61f5..4836c08bc1 100644 --- a/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.hpp +++ b/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.hpp @@ -203,8 +203,8 @@ class SfM_Data_Structure_Estimation_From_Known_Poses // Triangulate triplet tracks // - keep valid one - typedef std::vector< graphUtils::Triplet > Triplets; - const Triplets triplets = graphUtils::tripletListing(pairs); + typedef std::vector< graph::Triplet > Triplets; + const Triplets triplets = graph::tripletListing(pairs); C_Progress_display my_progress_bar( triplets.size(), std::cout, "Per triplet tracks validation (discard spurious correspondences):\n" ); @@ -222,7 +222,7 @@ class SfM_Data_Structure_Estimation_From_Known_Poses #endif // OPENMVG_USE_OPENMP {++my_progress_bar;} - const graphUtils::Triplet & triplet = *it; + const graph::Triplet & triplet = *it; const IndexT I = triplet.i, J = triplet.j , K = triplet.k; openMVG::tracks::STLMAPTracks map_tracksCommon; diff --git a/src/openMVG/sfm/sfm_data_filters.hpp b/src/openMVG/sfm/sfm_data_filters.hpp index 491d82df72..8183866e4b 100644 --- a/src/openMVG/sfm/sfm_data_filters.hpp +++ b/src/openMVG/sfm/sfm_data_filters.hpp @@ -68,7 +68,7 @@ static IndexT RemoveOutliers_PixelResidualError while (itObs != obs.end()) { const View * view = sfm_data.views[itObs->first].get(); - const Pose3 & pose = sfm_data.poses[view->id_pose]; + const Pose3 pose = sfm_data.GetPoseOrDie(view); const IntrinsicBase * intrinsic = sfm_data.intrinsics[view->id_intrinsic].get(); const Vec2 residual = intrinsic->residual(pose, iterTracks->second.X, itObs->second.x); if (residual.norm() > dThresholdPixel) @@ -105,7 +105,7 @@ static IndexT RemoveOutliers_AngleError itObs1 != obs.end(); ++itObs1) { const View * view1 = sfm_data.views[itObs1->first].get(); - const Pose3 & pose1 = sfm_data.poses[view1->id_pose]; + const Pose3 pose1 = sfm_data.GetPoseOrDie(view1); const IntrinsicBase * intrinsic1 = sfm_data.intrinsics[view1->id_intrinsic].get(); Observations::const_iterator itObs2 = itObs1; @@ -113,7 +113,7 @@ static IndexT RemoveOutliers_AngleError for (; itObs2 != obs.end(); ++itObs2) { const View * view2 = sfm_data.views[itObs2->first].get(); - const Pose3 & pose2 = sfm_data.poses[view2->id_pose]; + const Pose3 pose2 = sfm_data.GetPoseOrDie(view2); const IntrinsicBase * intrinsic2 = sfm_data.intrinsics[view2->id_intrinsic].get(); const double angle = AngleBetweenRay( @@ -183,7 +183,7 @@ static bool eraseObservationsWithMissingPoses(SfM_Data & sfm_data, const IndexT const Landmarks & landmarks = sfm_data.structure; std::set pose_Index; std::transform(sfm_data.poses.begin(), sfm_data.poses.end(), - std::inserter(pose_Index, pose_Index.begin()), std::RetrieveKey()); + std::inserter(pose_Index, pose_Index.begin()), stl::RetrieveKey()); // For each landmark: // - Check if we need to keep the observations & the track diff --git a/src/openMVG/sfm/sfm_data_filters_frustum.cpp b/src/openMVG/sfm/sfm_data_filters_frustum.cpp index 73d58729a4..64dc3767a5 100644 --- a/src/openMVG/sfm/sfm_data_filters_frustum.cpp +++ b/src/openMVG/sfm/sfm_data_filters_frustum.cpp @@ -70,7 +70,7 @@ Pair_Set Frustum_Filter::getFrustumIntersectionPairs() const std::vector viewIds; viewIds.reserve(z_near_z_far_perView.size()); std::transform(z_near_z_far_perView.begin(), z_near_z_far_perView.end(), - std::back_inserter(viewIds), std::RetrieveKey()); + std::back_inserter(viewIds), stl::RetrieveKey()); C_Progress_display my_progress_bar( viewIds.size() * (viewIds.size()-1)/2, diff --git a/src/openMVG/sfm/sfm_data_io.cpp b/src/openMVG/sfm/sfm_data_io.cpp index c24e4e4aa8..d1935ae599 100644 --- a/src/openMVG/sfm/sfm_data_io.cpp +++ b/src/openMVG/sfm/sfm_data_io.cpp @@ -25,11 +25,11 @@ bool ValidIds(const SfM_Data & sfm_data, ESfM_Data flags_part) std::set set_id_intrinsics; transform(sfm_data.GetIntrinsics().begin(), sfm_data.GetIntrinsics().end(), - std::inserter(set_id_intrinsics, set_id_intrinsics.begin()), std::RetrieveKey()); + std::inserter(set_id_intrinsics, set_id_intrinsics.begin()), stl::RetrieveKey()); std::set set_id_extrinsics; //unique so can use a set transform(sfm_data.GetPoses().begin(), sfm_data.GetPoses().end(), - std::inserter(set_id_extrinsics, set_id_extrinsics.begin()), std::RetrieveKey()); + std::inserter(set_id_extrinsics, set_id_extrinsics.begin()), stl::RetrieveKey()); // Collect existing id_intrinsic && id_extrinsic from views std::set reallyDefined_id_intrinsics; diff --git a/src/openMVG/sfm/sfm_data_triangulation.hpp b/src/openMVG/sfm/sfm_data_triangulation.hpp index d1602c96ed..d1eb7ac7a3 100644 --- a/src/openMVG/sfm/sfm_data_triangulation.hpp +++ b/src/openMVG/sfm/sfm_data_triangulation.hpp @@ -77,7 +77,7 @@ struct SfM_Data_Structure_Computation_Blind: public SfM_Data_Structure_Computati { const View * view = sfm_data.views.at(itObs->first).get(); const IntrinsicBase * cam = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); - const Pose3 & pose = sfm_data.GetPoseOrDie(view); + const Pose3 pose = sfm_data.GetPoseOrDie(view); trianObj.add( cam->get_projective_equivalent(pose), cam->get_ud_pixel(itObs->second.x)); @@ -214,7 +214,7 @@ struct SfM_Data_Structure_Computation_Robust: public SfM_Data_Structure_Computat std::advance(itObs, it); const View * view = sfm_data.views.at(itObs->first).get(); const IntrinsicBase * cam = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); - const Pose3 & pose = sfm_data.GetPoseOrDie(view); + const Pose3 pose = sfm_data.GetPoseOrDie(view); const double z = pose.depth(current_model); // TODO: cam->depth(pose(X)); bChierality &= z > 0; } @@ -230,7 +230,7 @@ struct SfM_Data_Structure_Computation_Robust: public SfM_Data_Structure_Computat { const View * view = sfm_data.views.at(itObs->first).get(); const IntrinsicBase * intrinsic = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); - const Pose3 & pose = sfm_data.GetPoseOrDie(view); + const Pose3 pose = sfm_data.GetPoseOrDie(view); const Vec2 residual = intrinsic->residual(pose, current_model, itObs->second.x); const double residual_d = residual.norm(); if (residual_d < dThresholdPixel) @@ -269,7 +269,7 @@ struct SfM_Data_Structure_Computation_Robust: public SfM_Data_Structure_Computat std::advance(itObs, idx); const View * view = sfm_data.views.at(itObs->first).get(); const IntrinsicBase * cam = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); - const Pose3 & pose = sfm_data.GetPoseOrDie(view); + const Pose3 pose = sfm_data.GetPoseOrDie(view); trianObj.add( cam->get_projective_equivalent(pose), cam->get_ud_pixel(itObs->second.x)); diff --git a/src/openMVG/stl/hash.hpp b/src/openMVG/stl/hash.hpp index fd5382eb98..28554e697d 100644 --- a/src/openMVG/stl/hash.hpp +++ b/src/openMVG/stl/hash.hpp @@ -10,7 +10,7 @@ #include -namespace std +namespace stl { // Combine hashing value @@ -22,6 +22,6 @@ inline void hash_combine(std::size_t& seed, const T& v) seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2); } -}; // namespace std +}; // namespace stl #endif // OPENMVG_STL_HASH_H diff --git a/src/openMVG/stl/indexed_sort.hpp b/src/openMVG/stl/indexed_sort.hpp index 9417ac263c..a9e14424f2 100644 --- a/src/openMVG/stl/indexed_sort.hpp +++ b/src/openMVG/stl/indexed_sort.hpp @@ -8,7 +8,7 @@ #ifndef OPENMVG_STL_INDEXED_SORT_H #define OPENMVG_STL_INDEXED_SORT_H -namespace std +namespace stl { namespace indexed_sort { @@ -61,6 +61,6 @@ namespace indexed_sort } }; // namespace indexed_sort -}; // namespace std +}; // namespace stl #endif // OPENMVG_STL_INDEXED_SORT_H diff --git a/src/openMVG/stl/split.hpp b/src/openMVG/stl/split.hpp index ac11715889..787d0a35fa 100644 --- a/src/openMVG/stl/split.hpp +++ b/src/openMVG/stl/split.hpp @@ -4,6 +4,8 @@ #include #include +namespace stl +{ /** * Split an input string with a delimiter and fill a string vector */ @@ -26,5 +28,5 @@ static bool split ( const std::string src, const std::string& delim, std::vector } return bDelimiterExist; } - +} // namespace stl #endif // SPLIT_HPP diff --git a/src/openMVG/stl/split_test.cpp b/src/openMVG/stl/split_test.cpp index e875b6d360..e6e74fb9f5 100644 --- a/src/openMVG/stl/split_test.cpp +++ b/src/openMVG/stl/split_test.cpp @@ -10,7 +10,7 @@ TEST(Split, stringEmpty) std::string sInput = ""; std::string sDelimiter = " "; std::vector vec_str; - EXPECT_FALSE( split( sInput, sDelimiter, vec_str ) ); + EXPECT_FALSE( stl::split(sInput, sDelimiter, vec_str)); EXPECT_EQ( 1, vec_str.size() ); } @@ -19,7 +19,7 @@ TEST(Split, delimiterEmpty) std::string sInput = "A string"; std::string sDelimiter = ""; std::vector vec_str; - EXPECT_FALSE( split( sInput, sDelimiter, vec_str ) ); + EXPECT_FALSE( stl::split(sInput, sDelimiter, vec_str)); EXPECT_EQ( 0, vec_str.size() ); } @@ -29,7 +29,7 @@ TEST(Split, delimiterNotExist) std::string sInput = "A string"; std::string sDelimiter = "_"; std::vector vec_str; - EXPECT_FALSE( split( sInput, sDelimiter, vec_str ) ); + EXPECT_FALSE( stl::split(sInput, sDelimiter, vec_str)); EXPECT_EQ( 1, vec_str.size() ); } @@ -38,7 +38,7 @@ TEST(Split, delimiterExist) std::string sInput = "A string"; std::string sDelimiter = " "; std::vector vec_str; - EXPECT_TRUE( split( sInput, sDelimiter, vec_str ) ); + EXPECT_TRUE( stl::split(sInput, sDelimiter, vec_str)); EXPECT_EQ( 2, vec_str.size() ); } @@ -47,7 +47,7 @@ TEST(Split, stringSplit3part) std::string sInput = "A string useless"; std::string sDelimiter = " "; std::vector vec_str; - EXPECT_TRUE( split( sInput, sDelimiter, vec_str ) ); + EXPECT_TRUE( stl::split(sInput, sDelimiter, vec_str)); EXPECT_EQ( 3, vec_str.size() ); } @@ -57,7 +57,7 @@ TEST(Split, ontheSameString) std::string sDelimiter = ";"; std::vector vec_str; vec_str.push_back("foo;"); - EXPECT_TRUE( split( vec_str[0], sDelimiter, vec_str ) ); + EXPECT_TRUE( stl::split(vec_str[0], sDelimiter, vec_str)); EXPECT_EQ( 2, vec_str.size() ); } diff --git a/src/openMVG/stl/stlMap.hpp b/src/openMVG/stl/stlMap.hpp index f9e2bd6bac..d7145db905 100644 --- a/src/openMVG/stl/stlMap.hpp +++ b/src/openMVG/stl/stlMap.hpp @@ -24,17 +24,17 @@ // m[1] = 1.6; // std::vector keys; // // Retrieve all keys -// transform(m.begin(), m.end(), back_inserter(keys), RetrieveKey()); +// transform(m.begin(), m.end(), back_inserter(keys), stl::RetrieveKey()); // // Log all keys to console // copy(keys.begin(), keys.end(), ostream_iterator(cout, "\n")); // // Retrieve all values // std::vector values; // // Retrieve all values -// transform(m.begin(), m.end(), back_inserter(values), RetrieveValue()); +// transform(m.begin(), m.end(), back_inserter(values), stl::RetrieveValue()); #include -namespace std{ +namespace stl{ /// Allow to select the Keys of a map. struct RetrieveKey @@ -56,7 +56,7 @@ struct RetrieveValue } }; -} // namespace std +} // namespace stl #endif // STL_MAP_ADDITION_H diff --git a/src/openMVG/system/timer.cpp b/src/openMVG/system/timer.cpp index dff429f81a..bf7c3c7fc6 100644 --- a/src/openMVG/system/timer.cpp +++ b/src/openMVG/system/timer.cpp @@ -19,6 +19,7 @@ #endif namespace openMVG { +namespace system { Timer::Timer() { @@ -95,5 +96,5 @@ namespace openMVG { return str << t.elapsed() << " s elapsed"; } +} // namespace system } // namespace openMVG - diff --git a/src/openMVG/system/timer.hpp b/src/openMVG/system/timer.hpp index 4e195e0776..3dfdaec543 100644 --- a/src/openMVG/system/timer.hpp +++ b/src/openMVG/system/timer.hpp @@ -20,6 +20,7 @@ #include namespace openMVG { +namespace system { //! \brief Timer class with microsecond accuracy. class Timer @@ -48,6 +49,7 @@ namespace openMVG { // print the elapsed time std::ostream& operator << (std::ostream&, const Timer&); +} // namespace system } // namespace openMVG #endif // OPENMVG_SYSTEM_TIMER_HPP diff --git a/src/openMVG_Samples/exifParsing/exifParsing.cpp b/src/openMVG_Samples/exifParsing/exifParsing.cpp index 241e4dd3e8..1f38848600 100644 --- a/src/openMVG_Samples/exifParsing/exifParsing.cpp +++ b/src/openMVG_Samples/exifParsing/exifParsing.cpp @@ -1,7 +1,7 @@ -#include "openMVG/exif_IO/exif_IO_EasyExif.hpp" +#include "openMVG/exif/exif_IO_EasyExif.hpp" +using namespace openMVG::exif; #include "third_party/cmdLine/cmdLine.h" - #include int main(int argc, char **argv) @@ -28,7 +28,7 @@ int main(int argc, char **argv) << argv[0] << std::endl << "--imafile " << sInputImage << std::endl; - std::auto_ptr exif_io( new Exif_IO_EasyExif( sInputImage ) ); + std::unique_ptr exif_io( new Exif_IO_EasyExif( sInputImage ) ); std::cout << "width : " << exif_io->getWidth() << std::endl; std::cout << "height : " << exif_io->getHeight() << std::endl; diff --git a/src/openMVG_Samples/sensorWidthDatabase/ParseDatabase.hpp b/src/openMVG_Samples/sensorWidthDatabase/ParseDatabase.hpp index 180bfe86cb..fea2eb3e94 100644 --- a/src/openMVG_Samples/sensorWidthDatabase/ParseDatabase.hpp +++ b/src/openMVG_Samples/sensorWidthDatabase/ParseDatabase.hpp @@ -28,7 +28,7 @@ bool parseDatabase( const std::string& sfileDatabase, std::vector& ve if ( line[0] != '#' ) { std::vector values; - std::split( line, ";", values ); + stl::split(line, ";", values); if ( values.size() == 3 ) { const std::string brand = values[0]; diff --git a/src/openMVG_Samples/sensorWidthDatabase/datasheet.hpp b/src/openMVG_Samples/sensorWidthDatabase/datasheet.hpp index 98e0301e83..bebe4e117d 100644 --- a/src/openMVG_Samples/sensorWidthDatabase/datasheet.hpp +++ b/src/openMVG_Samples/sensorWidthDatabase/datasheet.hpp @@ -22,7 +22,7 @@ struct Datasheet { bool isEqual = false; std::vector vec_brand; - std::split( ds._brand, " ", vec_brand ); + stl::split(ds._brand, " ", vec_brand); std::string brandlower = _brand; for ( int index = 0; index < brandlower.length(); index++ ) @@ -44,9 +44,9 @@ struct Datasheet { std::vector vec_model1; - std::split( ds._model, " ", vec_model1 ); + stl::split(ds._model, " ", vec_model1); std::vector vec_model2; - std::split( _model, " ", vec_model2 ); + stl::split(_model, " ", vec_model2); bool isAllFind = true; for ( std::vector::const_iterator iter_model1 = vec_model1.begin(); iter_model1 != vec_model1.end(); diff --git a/src/software/SfM/SfMIOHelper.hpp b/src/software/SfM/SfMIOHelper.hpp index 0456c0325e..5b5cb76a97 100644 --- a/src/software/SfM/SfMIOHelper.hpp +++ b/src/software/SfM/SfMIOHelper.hpp @@ -74,7 +74,7 @@ static bool loadImageList( std::vector & vec_camImageName, while(getline( in, sValue ) ) { vec_str.clear(); - std::split( sValue, ";", vec_str ); + stl::split(sValue, ";", vec_str); if (vec_str.size() == 1) { std::cerr << "Invalid input file" << std::endl; diff --git a/src/software/SfM/main_ComputeFeatures.cpp b/src/software/SfM/main_ComputeFeatures.cpp index 9609c07bcb..f08bb359af 100644 --- a/src/software/SfM/main_ComputeFeatures.cpp +++ b/src/software/SfM/main_ComputeFeatures.cpp @@ -207,7 +207,7 @@ int main(int argc, char **argv) // - if regions file exist continue, // - if no file, compute features { - Timer timer; + system::Timer timer; Image imageGray; C_Progress_display my_progress_bar( sfm_data.GetViews().size(), std::cout, "\n- EXTRACT FEATURES -\n" ); diff --git a/src/software/SfM/main_ComputeMatches.cpp b/src/software/SfM/main_ComputeMatches.cpp index b6178e8380..96924e1fc8 100644 --- a/src/software/SfM/main_ComputeMatches.cpp +++ b/src/software/SfM/main_ComputeMatches.cpp @@ -264,7 +264,7 @@ int main(int argc, char **argv) return EXIT_FAILURE; } // Perform the matching - Timer timer; + system::Timer timer; if (collectionMatcher->loadData(regions_type, vec_fileNames, sMatchesDirectory)) { // From matching mode compute the pair list that have to be matched: @@ -315,7 +315,7 @@ int main(int argc, char **argv) ImageCollectionGeometricFilter collectionGeomFilter(feats_provider.get()); const double maxResidualError = 4.0; { - Timer timer; + system::Timer timer; std::cout << std::endl << " - GEOMETRIC FILTERING - " << std::endl; switch (eGeometricModelToCompute) { diff --git a/src/software/SfM/main_ComputeSfM_DataColor.cpp b/src/software/SfM/main_ComputeSfM_DataColor.cpp index 78287b4105..3d5ad26d6c 100644 --- a/src/software/SfM/main_ComputeSfM_DataColor.cpp +++ b/src/software/SfM/main_ComputeSfM_DataColor.cpp @@ -48,7 +48,7 @@ void ColorizeTracks( std::set remainingTrackToColor; std::transform(sfm_data.GetLandmarks().begin(), sfm_data.GetLandmarks().end(), std::inserter(remainingTrackToColor, remainingTrackToColor.begin()), - RetrieveKey() ); + stl::RetrieveKey()); while( !remainingTrackToColor.empty() ) { @@ -80,8 +80,8 @@ void ColorizeTracks( std::transform(map_IndexCardinal.begin(), map_IndexCardinal.end(), std::back_inserter(vec_cardinal), - RetrieveValue()); - using namespace indexed_sort; + stl::RetrieveValue()); + using namespace stl::indexed_sort; std::vector< sort_index_packet_descend< IndexT, IndexT> > packet_vec(vec_cardinal.size()); sort_index_helper(packet_vec, &vec_cardinal[0], 1); diff --git a/src/software/SfM/main_ComputeStructureFromKnownPoses.cpp b/src/software/SfM/main_ComputeStructureFromKnownPoses.cpp index 017769ad01..9542b7fbfc 100644 --- a/src/software/SfM/main_ComputeStructureFromKnownPoses.cpp +++ b/src/software/SfM/main_ComputeStructureFromKnownPoses.cpp @@ -110,7 +110,7 @@ int main(int argc, char **argv) std::set valid_viewIdx = Get_Valid_Views(sfm_data); pairs = Pair_filter(pairs, valid_viewIdx); - openMVG::Timer timer; + openMVG::system::Timer timer; //------------------------------------------ // Compute Structure from known camera poses diff --git a/src/software/SfM/main_ConvertList.cpp b/src/software/SfM/main_ConvertList.cpp index 8ce3c585dd..f0fd7c3d5c 100644 --- a/src/software/SfM/main_ConvertList.cpp +++ b/src/software/SfM/main_ConvertList.cpp @@ -4,7 +4,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "openMVG/split/split.hpp" +#include "openMVG/stl/split.hpp" #include "openMVG/sfm/sfm.hpp" diff --git a/src/software/SfM/main_FrustumFiltering.cpp b/src/software/SfM/main_FrustumFiltering.cpp index ec9534502a..54c029bf98 100644 --- a/src/software/SfM/main_FrustumFiltering.cpp +++ b/src/software/SfM/main_FrustumFiltering.cpp @@ -106,7 +106,7 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - openMVG::Timer timer; + openMVG::system::Timer timer; const Pair_Set pairs = BuildPairsFromFrustumsIntersections(sfm_data, z_near, z_far, stlplus::folder_part(sOutFile)); /*const Pair_Set pairs = BuildPairsFromStructureObservations(sfm_data); */ diff --git a/src/software/SfM/main_GlobalSfM.cpp b/src/software/SfM/main_GlobalSfM.cpp index d34a8ff665..c048de524d 100644 --- a/src/software/SfM/main_GlobalSfM.cpp +++ b/src/software/SfM/main_GlobalSfM.cpp @@ -128,7 +128,7 @@ int main(int argc, char **argv) // Global SfM reconstruction process //--------------------------------------- - openMVG::Timer timer; + openMVG::system::Timer timer; GlobalSfMReconstructionEngine_RelativeMotions sfmEngine( sfm_data, sOutDir, diff --git a/src/software/SfM/main_IncrementalSfM.cpp b/src/software/SfM/main_IncrementalSfM.cpp index ccc1e03dcc..50e3865909 100644 --- a/src/software/SfM/main_IncrementalSfM.cpp +++ b/src/software/SfM/main_IncrementalSfM.cpp @@ -146,7 +146,7 @@ int main(int argc, char **argv) // Sequential reconstruction process //--------------------------------------- - openMVG::Timer timer; + openMVG::system::Timer timer; SequentialSfMReconstructionEngine sfmEngine( sfm_data, sOutDir, diff --git a/src/software/SfM/main_SfMInit_ImageListing.cpp b/src/software/SfM/main_SfMInit_ImageListing.cpp index c1310236a2..101e88e36a 100644 --- a/src/software/SfM/main_SfMInit_ImageListing.cpp +++ b/src/software/SfM/main_SfMInit_ImageListing.cpp @@ -3,7 +3,7 @@ // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "openMVG/exif_IO/exif_IO_EasyExif.hpp" +#include "openMVG/exif/exif_IO_EasyExif.hpp" #include "openMVG_Samples/sensorWidthDatabase/ParseDatabase.hpp" @@ -31,7 +31,7 @@ using namespace openMVG::exif; bool checkIntrinsicStringValidity(const std::string & Kmatrix, double & focal, double & ppx, double & ppy) { std::vector vec_str; - std::split( Kmatrix, ";", vec_str ); + stl::split(Kmatrix, ";", vec_str); if (vec_str.size() != 9) { std::cerr << "\n Missing ';' character" << std::endl; return false; diff --git a/src/software/colorHarmonize/colorHarmonizeEngineGlobal.cpp b/src/software/colorHarmonize/colorHarmonizeEngineGlobal.cpp index 9b762210a9..64a12bc958 100644 --- a/src/software/colorHarmonize/colorHarmonizeEngineGlobal.cpp +++ b/src/software/colorHarmonize/colorHarmonizeEngineGlobal.cpp @@ -114,10 +114,10 @@ bool ColorHarmonizationEngineGlobal::Process() } { - graphUtils::indexedGraph putativeGraph(getPairs(_map_Matches)); + graph::indexedGraph putativeGraph(getPairs(_map_Matches)); // Save the graph before cleaning: - graphUtils::exportToGraphvizData( + graph::exportToGraphvizData( stlplus::create_filespec(_sOutDirectory, "input_graph_poor_supportRemoved"), putativeGraph.g); } @@ -329,7 +329,7 @@ bool ColorHarmonizationEngineGlobal::Process() std::vector vec_solution_g(_vec_fileNames.size() * 2 + 1); std::vector vec_solution_b(_vec_fileNames.size() * 2 + 1); - openMVG::Timer timer; + openMVG::system::Timer timer; #ifdef OPENMVG_HAVE_MOSEK typedef MOSEK_SolveWrapper SOLVER_LP_T; @@ -500,10 +500,10 @@ bool ColorHarmonizationEngineGlobal::ReadInputData() } } - graphUtils::indexedGraph putativeGraph(getPairs(_map_Matches)); + graph::indexedGraph putativeGraph(getPairs(_map_Matches)); // Save the graph before cleaning: - graphUtils::exportToGraphvizData( + graph::exportToGraphvizData( stlplus::create_filespec( _sOutDirectory, "initialGraph" ), putativeGraph.g ); @@ -515,10 +515,10 @@ bool ColorHarmonizationEngineGlobal::CleanGraph() // Create a graph from pairwise correspondences: // - keep the largest connected component. - graphUtils::indexedGraph putativeGraph(getPairs(_map_Matches)); + graph::indexedGraph putativeGraph(getPairs(_map_Matches)); // Save the graph before cleaning: - graphUtils::exportToGraphvizData( + graph::exportToGraphvizData( stlplus::create_filespec(_sOutDirectory, "initialGraph"), putativeGraph.g); @@ -531,7 +531,7 @@ bool ColorHarmonizationEngineGlobal::CleanGraph() { // Search the largest CC index const std::map > map_subgraphs = - openMVG::graphUtils::exportGraphToMapSubgraphs(putativeGraph.g); + openMVG::graph::exportGraphToMapSubgraphs(putativeGraph.g); size_t count = std::numeric_limits::min(); std::map >::const_iterator iterLargestCC = map_subgraphs.end(); for(std::map >::const_iterator iter = map_subgraphs.begin(); @@ -578,7 +578,7 @@ bool ColorHarmonizationEngineGlobal::CleanGraph() } // Save the graph after cleaning: - graphUtils::exportToGraphvizData( + graph::exportToGraphvizData( stlplus::create_filespec(_sOutDirectory, "cleanedGraph"), putativeGraph.g); diff --git a/src/software/colorHarmonize/main_ColHarmonize.cpp b/src/software/colorHarmonize/main_ColHarmonize.cpp index 653d2cc95c..aba088057b 100644 --- a/src/software/colorHarmonize/main_ColHarmonize.cpp +++ b/src/software/colorHarmonize/main_ColHarmonize.cpp @@ -68,7 +68,7 @@ int main( int argc, char **argv ) // Harmonization process //--------------------------------------- - openMVG::Timer timer; + openMVG::system::Timer timer; sMatchesDir = stlplus::folder_part(sMatchesFile); std::auto_ptr m_colorHarmonizeEngine( From 64999cda8ad872a91a3a52ea01466a349b961c28 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Wed, 20 May 2015 13:42:12 +0200 Subject: [PATCH 13/52] [samples] rewrite undisto_Brown to use the new Pinhole_Intrinsic_Radial_K3 intrinsic camera model. #285 --- src/openMVG/image/image_container.hpp | 2 +- src/openMVG/image/pixel_types.hpp | 10 +- .../undisto_Brown/CMakeLists.txt | 6 +- .../undisto_Brown/undistoBrown.cpp | 105 +++--------------- 4 files changed, 20 insertions(+), 103 deletions(-) diff --git a/src/openMVG/image/image_container.hpp b/src/openMVG/image/image_container.hpp index 0b251bba27..85547be6f5 100644 --- a/src/openMVG/image/image_container.hpp +++ b/src/openMVG/image/image_container.hpp @@ -52,7 +52,7 @@ class Image : public Eigen::Matrix //------------------------------ //-- construction method - inline Rgb() : Base(0,0,0) {} inline Rgb(T red,T green,T blue) : Base(red, green, blue){} explicit inline Rgb(const Base& val) : Base(val) {} - explicit inline Rgb(const T t[3]) : Base(t) {} - explicit inline Rgb(const T val) : Base(val,val,val) {} + explicit inline Rgb(const T val=0) : Base(val,val,val) {} //-- construction method //------------------------------ @@ -80,12 +78,10 @@ class Rgba : public Eigen::Matrix //------------------------------ //-- construction method - inline Rgba() : Base(0,0,0,0) {} - inline Rgba(T red,T green,T blue, T alpha=0) + inline Rgba(T red,T green,T blue, T alpha=1.0) : Base(red, green, blue, alpha){} explicit inline Rgba(const Base& val) : Base(val) {} - explicit inline Rgba(const T t[4]): Base(t) {} - explicit inline Rgba(const T val): Base(val,val,val,1.0) {} + explicit inline Rgba(const T val=0): Base(val,val,val,1.0) {} inline Rgba(const RGBColor val) : Base(val.r(),val.g(),val.b(),static_cast(1)) {} //-- construction method diff --git a/src/openMVG_Samples/undisto_Brown/CMakeLists.txt b/src/openMVG_Samples/undisto_Brown/CMakeLists.txt index 7ece90893e..1b1e3fb284 100644 --- a/src/openMVG_Samples/undisto_Brown/CMakeLists.txt +++ b/src/openMVG_Samples/undisto_Brown/CMakeLists.txt @@ -1,9 +1,5 @@ ADD_EXECUTABLE(openMVG_sample_undistoBrown undistoBrown.cpp) TARGET_LINK_LIBRARIES(openMVG_sample_undistoBrown - openMVG_numeric - openMVG_image - stlplus - ${OPENMVG_LIBRARY_DEPENDENCIES}) - + ${OpenMVG_LIBS}) SET_PROPERTY(TARGET openMVG_sample_undistoBrown PROPERTY FOLDER OpenMVG/Samples) diff --git a/src/openMVG_Samples/undisto_Brown/undistoBrown.cpp b/src/openMVG_Samples/undisto_Brown/undistoBrown.cpp index dacc27f782..6441386430 100644 --- a/src/openMVG_Samples/undisto_Brown/undistoBrown.cpp +++ b/src/openMVG_Samples/undisto_Brown/undistoBrown.cpp @@ -6,7 +6,7 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include "openMVG/image/image.hpp" -#include "openMVG/numeric/numeric.h" +#include "openMVG/cameras/cameras.hpp" #include "third_party/cmdLine/cmdLine.h" #include "third_party/stlplus3/filesystemSimplified/file_system.hpp" @@ -19,79 +19,6 @@ using namespace openMVG; using namespace openMVG::image; using namespace std; -// A simple container and undistort function for the Brown's distortion model [1] -// Variables: -// (x,y): 2D point in the image (pixel) -// (u,v): the undistorted 2D point (pixel) -// radial_distortion (k1, k2, k3, ...): vector containing the radial distortion -// (cx,cy): camera principal point -// tangential factors are not considered here -// -// Equation: -// u = x + (x - cx) * (k1 * r^2 + k2 * r^4 +...) -// v = y + (y - cy) * (k1 * r^2 + k2 * r^4 +...) -// -// [1] Decentering distortion of lenses. -// Brown, Duane C -// Photometric Engineering 1966 -struct BrownDistoModel -{ - Vec2 m_disto_center; // distortion center - Vec m_radial_distortion; // radial distortion factor - double m_f; // focal - - inline void ComputeUndistortedCoordinates( double xu, double yu, double &xd, double& yd) const - { - const Vec2 point (xu, yu); - const Vec2 principal_point (m_disto_center); - const Vec2 point_centered = point - principal_point; - - const double u = point_centered.x() / m_f; - const double v = point_centered.y() / m_f; - const double radius_squared = u * u + v * v; - - double coef_radial = 0.0; - for (int i = m_radial_distortion.size() - 1; i >= 0; --i) { - coef_radial = (coef_radial + m_radial_distortion[i]) * radius_squared; - } - - const Vec2 undistorted_point = point + point_centered * coef_radial; - xd = undistorted_point(0); - yd = undistorted_point(1); - } -}; - -/// Undistort an image according a given Distortion model -template -Image undistortImage( - const Image& I, - const BrownDistoModel& d, - RGBColor fillcolor = BLACK, - bool bcenteringPPpoint = true) -{ - const int w = I.Width(); - const int h = I.Height(); - Vec2 offset(0,0); - if (bcenteringPPpoint) - offset = Vec2(w * .5, h * .5) - d.m_disto_center; - - Image J ( w,h ); - double xu, yu, xd,yd; - for ( int j=0; j vec_fileNames = stlplus::folder_wildcard(sPath, "*."+suffix, false, true); @@ -169,6 +91,9 @@ int main(int argc, char **argv) stlplus::create_filespec(sOutPath, stlplus::basename_part(vec_fileNames[j]), "JPG"); const string sInFileName = stlplus::create_filespec(sPath, stlplus::basename_part(vec_fileNames[j])); const int res = ReadImage(sInFileName.c_str(), &tmp_vec, &w, &h, &depth); + + const Pinhole_Intrinsic_Radial_K3 cam(w, h, f, c(0), c(1), k(0), k(1), k(2)); + if (res == 1) { switch(depth) @@ -176,21 +101,21 @@ int main(int argc, char **argv) case 1: //Greyscale { imageGreyIn = Eigen::Map::Base>(&tmp_vec[0], h, w); - imageGreyU = undistortImage ( imageGreyIn, distoModel); + UndistortImage(imageGreyIn, &cam, imageGreyU); WriteImage(sOutFileName.c_str(), imageGreyU); break; } case 3: //RGB { imageRGBIn = Eigen::Map::Base>((RGBColor*) &tmp_vec[0], h, w); - imageRGBU = undistortImage ( imageRGBIn, distoModel); + UndistortImage(imageRGBIn, &cam, imageRGBU); WriteImage(sOutFileName.c_str(), imageRGBU); break; } case 4: //RGBA { imageRGBAIn = Eigen::Map::Base>((RGBAColor*) &tmp_vec[0], h, w); - imageRGBAU = undistortImage ( imageRGBAIn, distoModel); + UndistortImage(imageRGBAIn, &cam, imageRGBAU); WriteImage(sOutFileName.c_str(), imageRGBAU); break; } From 4aed58c9e16831ad1e470b5c667ccb4280f49558 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Wed, 20 May 2015 18:23:58 +0200 Subject: [PATCH 14/52] [samples] rewrite robust_essential and robust_essential_ba to fit the new sfm module. #301 --- .../pipelines/sfm_robust_model_estimation.cpp | 16 +- .../pipelines/sfm_robust_model_estimation.hpp | 32 +-- .../robust_essential/CMakeLists.txt | 7 +- .../robust_essential/essential_estimation.hpp | 57 ++-- .../robust_essential/robust_essential.cpp | 213 ++++++-------- .../robust_essential_ba/CMakeLists.txt | 8 +- .../robust_essential_ba.cpp | 267 +++++++----------- 7 files changed, 246 insertions(+), 354 deletions(-) diff --git a/src/openMVG/sfm/pipelines/sfm_robust_model_estimation.cpp b/src/openMVG/sfm/pipelines/sfm_robust_model_estimation.cpp index bdbfb46648..1a8cab2ad1 100644 --- a/src/openMVG/sfm/pipelines/sfm_robust_model_estimation.cpp +++ b/src/openMVG/sfm/pipelines/sfm_robust_model_estimation.cpp @@ -22,8 +22,6 @@ namespace openMVG { -using namespace openMVG::robust; - bool estimate_Rt_fromE(const Mat3 & K1, const Mat3 & K2, const Mat & x1, const Mat & x2, const Mat3 & E, const std::vector & vec_inliers, @@ -59,31 +57,33 @@ bool estimate_Rt_fromE(const Mat3 & K1, const Mat3 & K2, for (size_t k = 0; k < vec_inliers.size(); ++k) { const Vec2 & x1_ = x1.col(vec_inliers[k]), - & x2_ = x2.col(vec_inliers[k]); + &x2_ = x2.col(vec_inliers[k]); TriangulateDLT(P1, x1_, P2, x2_, &X); // Test if point is front to the two cameras. if (Depth(R1, t1, X) > 0 && Depth(R2, t2, X) > 0) { - ++f[i]; + ++f[i]; } } } // Check the solution: const std::vector::iterator iter = max_element(f.begin(), f.end()); - if(*iter == 0) + if (*iter == 0) { std::cerr << std::endl << "/!\\There is no right solution," - <<" probably intermediate results are not correct or no points" - <<" in front of both cameras" << std::endl; + << " probably intermediate results are not correct or no points" + << " in front of both cameras" << std::endl; return false; } - const size_t index = std::distance(f.begin(),iter); + const size_t index = std::distance(f.begin(), iter); (*R) = Rs[index]; (*t) = ts[index]; return true; } +using namespace openMVG::robust; + bool robustRelativePose( const Mat3 & K1, const Mat3 & K2, const Mat & x1, const Mat & x2, diff --git a/src/openMVG/sfm/pipelines/sfm_robust_model_estimation.hpp b/src/openMVG/sfm/pipelines/sfm_robust_model_estimation.hpp index 9bb060330e..c06bdfd356 100644 --- a/src/openMVG/sfm/pipelines/sfm_robust_model_estimation.hpp +++ b/src/openMVG/sfm/pipelines/sfm_robust_model_estimation.hpp @@ -16,22 +16,22 @@ namespace openMVG { /** - * @brief Estimate the best possible Rotation/Translation from E. - * Four are possible, keep the one with most of the point in front. - * - * @param[in] K1 camera 1 intrinsics - * @param[in] K2 camera 2 intrinsics - * @param[in] x1 camera 1 image points - * @param[in] x2 camera 2 image points - * @param[in] E essential matrix - * @param[in] vec_inliers inliers indices - * @param[out] R estimated rotation - * @param[out] t estimated translation - */ -bool estimate_Rt_fromE(const Mat3 & K1, const Mat3 & K2, - const Mat & x1, const Mat & x2, - const Mat3 & E, const std::vector & vec_inliers, - Mat3 * R, Vec3 * t); +* @brief Estimate the best possible Rotation/Translation from E. +* Four are possible, keep the one with most of the point in front. +* +* @param[in] K1 camera 1 intrinsics +* @param[in] K2 camera 2 intrinsics +* @param[in] x1 camera 1 image points +* @param[in] x2 camera 2 image points +* @param[in] E essential matrix +* @param[in] vec_inliers inliers indices +* @param[out] R estimated rotation +* @param[out] t estimated translation +*/ + bool estimate_Rt_fromE(const Mat3 & K1, const Mat3 & K2, + const Mat & x1, const Mat & x2, + const Mat3 & E, const std::vector & vec_inliers, + Mat3 * R, Vec3 * t); struct RelativePose_Info { diff --git a/src/openMVG_Samples/robust_essential/CMakeLists.txt b/src/openMVG_Samples/robust_essential/CMakeLists.txt index 631798749c..2839ddf2a1 100644 --- a/src/openMVG_Samples/robust_essential/CMakeLists.txt +++ b/src/openMVG_Samples/robust_essential/CMakeLists.txt @@ -3,11 +3,6 @@ ADD_DEFINITIONS(-DTHIS_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}") ADD_EXECUTABLE(openMVG_sample_robustEssential robust_essential.cpp) TARGET_LINK_LIBRARIES(openMVG_sample_robustEssential - openMVG_image - openMVG_multiview - openMVG_features - vlsift - stlplus - ${OPENMVG_LIBRARY_DEPENDENCIES}) + ${OpenMVG_LIBS}) SET_PROPERTY(TARGET openMVG_sample_robustEssential PROPERTY FOLDER OpenMVG/Samples) diff --git a/src/openMVG_Samples/robust_essential/essential_estimation.hpp b/src/openMVG_Samples/robust_essential/essential_estimation.hpp index 705d90fe16..b4bd6aec7f 100644 --- a/src/openMVG_Samples/robust_essential/essential_estimation.hpp +++ b/src/openMVG_Samples/robust_essential/essential_estimation.hpp @@ -49,15 +49,24 @@ bool robustEssential( } -/// From the essential matrix test the 4 possible solutions -/// and return the best one. (point in front of the selected solution) -bool estimate_Rt_fromE(const Mat3 & K1, const Mat3 & K2, +/** +* @brief Estimate the best possible Rotation/Translation from E. +* Four are possible, keep the one with most of the point in front. +* +* @param[in] K1 camera 1 intrinsics +* @param[in] K2 camera 2 intrinsics +* @param[in] x1 camera 1 image points +* @param[in] x2 camera 2 image points +* @param[in] E essential matrix +* @param[in] vec_inliers inliers indices +* @param[out] R estimated rotation +* @param[out] t estimated translation +*/ +static bool estimate_Rt_fromE(const Mat3 & K1, const Mat3 & K2, const Mat & x1, const Mat & x2, const Mat3 & E, const std::vector & vec_inliers, Mat3 * R, Vec3 * t) { - bool bOk = false; - // Accumulator to find the best solution std::vector f(4, 0); @@ -78,7 +87,8 @@ bool estimate_Rt_fromE(const Mat3 & K1, const Mat3 & K2, Vec3 t1 = Vec3::Zero(); P_From_KRt(K1, R1, t1, &P1); - for (int i = 0; i < 4; ++i) { + for (unsigned int i = 0; i < 4; ++i) + { const Mat3 &R2 = Rs[i]; const Vec3 &t2 = ts[i]; P_From_KRt(K2, R2, t2, &P2); @@ -86,33 +96,30 @@ bool estimate_Rt_fromE(const Mat3 & K1, const Mat3 & K2, for (size_t k = 0; k < vec_inliers.size(); ++k) { - const Vec2 & x1_ = x1.col(vec_inliers[k]); - const Vec2 & x2_ = x2.col(vec_inliers[k]); + const Vec2 & x1_ = x1.col(vec_inliers[k]), + &x2_ = x2.col(vec_inliers[k]); TriangulateDLT(P1, x1_, P2, x2_, &X); // Test if point is front to the two cameras. - if (Depth(R1, t1, X) > 0 && Depth(R2, t2, X) > 0) { - ++f[i]; + if (Depth(R1, t1, X) > 0 && Depth(R2, t2, X) > 0) + { + ++f[i]; } } } - // Check the solution : - std::cout << "\t Number of points in front of both cameras:" - << f[0] << " " << f[1] << " " << f[2] << " " << f[3] << std::endl; - std::vector::iterator iter = max_element(f.begin(), f.end()); - if(*iter != 0) + // Check the solution: + const std::vector::iterator iter = max_element(f.begin(), f.end()); + if (*iter == 0) { - size_t index = std::distance(f.begin(), iter); - (*R) = Rs[index]; - (*t) = ts[index]; - bOk = true; - } - else { std::cerr << std::endl << "/!\\There is no right solution," - <<" probably intermediate results are not correct or no points" - <<" in front of both cameras" << std::endl; - bOk = false; + << " probably intermediate results are not correct or no points" + << " in front of both cameras" << std::endl; + return false; } - return bOk; + const size_t index = std::distance(f.begin(), iter); + (*R) = Rs[index]; + (*t) = ts[index]; + + return true; } } // namespace openMVG diff --git a/src/openMVG_Samples/robust_essential/robust_essential.cpp b/src/openMVG_Samples/robust_essential/robust_essential.cpp index f23ae1d920..424e605ac5 100644 --- a/src/openMVG_Samples/robust_essential/robust_essential.cpp +++ b/src/openMVG_Samples/robust_essential/robust_essential.cpp @@ -6,14 +6,12 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "openMVG/cameras/PinholeCamera.hpp" +#include "openMVG/sfm/sfm.hpp" #include "openMVG/image/image.hpp" #include "openMVG/features/features.hpp" #include "openMVG/matching/matcher_brute_force.hpp" #include "openMVG/matching/indMatchDecoratorXY.hpp" -#include "openMVG/multiview/projection.hpp" #include "openMVG/multiview/triangulation.hpp" -#include "openMVG_Samples/robust_essential/essential_estimation.hpp" #include "nonFree/sift/SIFT_describer.hpp" #include "openMVG_Samples/siftPutativeMatches/two_view_matches.hpp" @@ -41,18 +39,9 @@ bool exportToPly(const std::vector & vec_points, const std::vector & vec_camPos, const std::string & sFileName); -/// Triangulate and export valid point as PLY (point in front of the cameras) -void triangulateAndSaveResult( - const PinholeCamera & camL, - const PinholeCamera & camR, - const std::vector & vec_inliers, - const Mat & xL, - const Mat & xR, - std::vector & vec_3DPoints); - int main() { - std::string sInputDir = stlplus::folder_up(string(THIS_SOURCE_DIR)) + const std::string sInputDir = stlplus::folder_up(string(THIS_SOURCE_DIR)) + "/imageData/SceauxCastle/"; const string jpg_filenameL = sInputDir + "100_7101.jpg"; const string jpg_filenameR = sInputDir + "100_7102.jpg"; @@ -120,6 +109,11 @@ int main() { vec_PutativeMatches, featsL, featsR); matchDeduplicator.getDeduplicated(vec_PutativeMatches); + std::cout + << regions_perImage.at(0)->RegionCount() << " #Features on image A" << std::endl + << regions_perImage.at(1)->RegionCount() << " #Features on image B" << std::endl + << vec_PutativeMatches.size() << " #matches with Distance Ratio filter" << std::endl; + // Draw correspondences after Nearest Neighbor ratio filter svgDrawer svgStream( imageL.Width() + imageR.Width(), max(imageL.Height(), imageR.Height())); svgStream.drawImage(jpg_filenameL, imageL.Width(), imageL.Height()); @@ -132,8 +126,8 @@ int main() { svgStream.drawCircle(L.x(), L.y(), L.scale(), svgStyle().stroke("yellow", 2.0)); svgStream.drawCircle(R.x()+imageL.Width(), R.y(), R.scale(),svgStyle().stroke("yellow", 2.0)); } - string out_filename = "03_siftMatches.svg"; - ofstream svgFile( out_filename.c_str() ); + const std::string out_filename = "03_siftMatches.svg"; + std::ofstream svgFile( out_filename.c_str() ); svgFile << svgStream.closeSvgFile().str(); svgFile.close(); } @@ -158,82 +152,90 @@ int main() { xR.col(k) = imaR.coords().cast(); } - //B. robust estimation of the essential matrix - std::vector vec_inliers; - Mat3 E; + //B. Compute the relative pose thanks to a essential matrix estimation std::pair size_imaL(imageL.Width(), imageL.Height()); std::pair size_imaR(imageR.Width(), imageR.Height()); - double thresholdE = 0.0, NFA = 0.0; - if (robustEssential( - K, K, // intrinsics - xL, xR, // corresponding points - &E, // essential matrix - &vec_inliers, // inliers - size_imaL, // Left image size - size_imaR, // Right image size - &thresholdE, // Found AContrario Theshold - &NFA, // Found AContrario NFA - std::numeric_limits::infinity())) + RelativePose_Info relativePose_info; + if (!robustRelativePose(K, K, xL, xR, relativePose_info, size_imaL, size_imaR, 256)) { - std::cout << "\nFound an Essential matrix under the confidence threshold of: " - << thresholdE << " pixels\n\twith: " << vec_inliers.size() << " inliers" - << " from: " << vec_PutativeMatches.size() - << " putatives correspondences" + std::cerr << " /!\\ Robust relative pose estimation failure." << std::endl; + return EXIT_FAILURE; + } + + std::cout << "\nFound an Essential matrix:\n" + << "\tprecision: " << relativePose_info.found_residual_precision << " pixels\n" + << "\t#inliers: " << relativePose_info.vec_inliers.size() << "\n" + << "\t#matches: " << vec_PutativeMatches.size() + << std::endl; + + // Show Essential validated point + svgDrawer svgStream( imageL.Width() + imageR.Width(), max(imageL.Height(), imageR.Height())); + svgStream.drawImage(jpg_filenameL, imageL.Width(), imageL.Height()); + svgStream.drawImage(jpg_filenameR, imageR.Width(), imageR.Height(), imageL.Width()); + for (size_t i = 0; i < relativePose_info.vec_inliers.size(); ++i) { + const SIOPointFeature & LL = regionsL->Features()[vec_PutativeMatches[relativePose_info.vec_inliers[i]]._i]; + const SIOPointFeature & RR = regionsR->Features()[vec_PutativeMatches[relativePose_info.vec_inliers[i]]._j]; + const Vec2f L = LL.coords(); + const Vec2f R = RR.coords(); + svgStream.drawLine(L.x(), L.y(), R.x()+imageL.Width(), R.y(), svgStyle().stroke("green", 2.0)); + svgStream.drawCircle(L.x(), L.y(), LL.scale(), svgStyle().stroke("yellow", 2.0)); + svgStream.drawCircle(R.x()+imageL.Width(), R.y(), RR.scale(),svgStyle().stroke("yellow", 2.0)); + } + const std::string out_filename = "04_ACRansacEssential.svg"; + std::ofstream svgFile( out_filename.c_str() ); + svgFile << svgStream.closeSvgFile().str(); + svgFile.close(); + + //C. Triangulate and export inliers as a PLY scene + std::vector vec_3DPoints; + + // Setup camera intrinsic and poses + Pinhole_Intrinsic intrinsic0(imageL.Width(), imageL.Height(), K(0, 0), K(0, 2), K(1, 2)); + Pinhole_Intrinsic intrinsic1(imageR.Width(), imageR.Height(), K(0, 0), K(0, 2), K(1, 2)); + + const Pose3 pose0 = Pose3(Mat3::Identity(), Vec3::Zero()); + const Pose3 pose1 = relativePose_info.relativePose; + + // Init structure by inlier triangulation + const Mat34 P1 = intrinsic0.get_projective_equivalent(pose0); + const Mat34 P2 = intrinsic1.get_projective_equivalent(pose1); + std::vector vec_residuals; + vec_residuals.reserve(relativePose_info.vec_inliers.size() * 4); + for (size_t i = 0; i < relativePose_info.vec_inliers.size(); ++i) { + const SIOPointFeature & LL = regionsL->Features()[vec_PutativeMatches[relativePose_info.vec_inliers[i]]._i]; + const SIOPointFeature & RR = regionsR->Features()[vec_PutativeMatches[relativePose_info.vec_inliers[i]]._j]; + // Point triangulation + Vec3 X; + TriangulateDLT(P1, LL.coords().cast(), P2, RR.coords().cast(), &X); + // Reject point that is behind the camera + if (pose0.depth(X) < 0 && pose1.depth(X) < 0) + continue; + const Vec2 residual0 = intrinsic0.residual(pose0, X, LL.coords().cast()); + const Vec2 residual1 = intrinsic1.residual(pose1, X, RR.coords().cast()); + vec_residuals.push_back(fabs(residual0(0))); + vec_residuals.push_back(fabs(residual0(1))); + vec_residuals.push_back(fabs(residual1(0))); + vec_residuals.push_back(fabs(residual1(1))); + } - // Show Essential validated point - svgDrawer svgStream( imageL.Width() + imageR.Width(), max(imageL.Height(), imageR.Height())); - svgStream.drawImage(jpg_filenameL, imageL.Width(), imageL.Height()); - svgStream.drawImage(jpg_filenameR, imageR.Width(), imageR.Height(), imageL.Width()); - for ( size_t i = 0; i < vec_inliers.size(); ++i) { - const SIOPointFeature & LL = regionsL->Features()[vec_PutativeMatches[vec_inliers[i]]._i]; - const SIOPointFeature & RR = regionsR->Features()[vec_PutativeMatches[vec_inliers[i]]._j]; - const Vec2f L = LL.coords(); - const Vec2f R = RR.coords(); - svgStream.drawLine(L.x(), L.y(), R.x()+imageL.Width(), R.y(), svgStyle().stroke("green", 2.0)); - svgStream.drawCircle(L.x(), L.y(), LL.scale(), svgStyle().stroke("yellow", 2.0)); - svgStream.drawCircle(R.x()+imageL.Width(), R.y(), RR.scale(),svgStyle().stroke("yellow", 2.0)); - } - string out_filename = "04_ACRansacEssential.svg"; - ofstream svgFile( out_filename.c_str() ); - svgFile << svgStream.closeSvgFile().str(); - svgFile.close(); - - //C. Extract the rotation and translation of the camera from the essential matrix - Mat3 R; - Vec3 t; - if (!estimate_Rt_fromE(K, K, xL, xR, E, vec_inliers, - &R, &t)) - { - std::cerr << " /!\\ Failed to compute initial R|t for the initial pair" << std::endl; - return false; - } - std::cout << std::endl - << "-- Rotation|Translation matrices: --" << std::endl - << R << std::endl << std::endl << t << std::endl; - - // Build Left and Right Camera - PinholeCamera camL(K, Mat3::Identity(), Vec3::Zero()); - PinholeCamera camR(K, R, t); - - //C. Triangulate and export inliers as a PLY scene - std::vector vec_3DPoints; - triangulateAndSaveResult( - camL, camR, - vec_inliers, - xL, xR, vec_3DPoints); + // Display some statistics of reprojection errors + float dMin, dMax, dMean, dMedian; + minMaxMeanMedian(vec_residuals.begin(), vec_residuals.end(), + dMin, dMax, dMean, dMedian); + + std::cout << std::endl + << "Triangulation residuals statistics:" << "\n" + << "\t-- Residual min:\t" << dMin << "\n" + << "\t-- Residual median:\t" << dMedian << "\n" + << "\t-- Residual max:\t " << dMax << "\n" + << "\t-- Residual mean:\t " << dMean << std::endl; // Export as PLY (camera pos + 3Dpoints) std::vector vec_camPos; - vec_camPos.push_back( camL._C ); - vec_camPos.push_back( camR._C ); + vec_camPos.push_back( pose0.center() ); + vec_camPos.push_back( pose1.center() ); exportToPly(vec_3DPoints, vec_camPos, "EssentialGeometry.ply"); - - } - else { - std::cout << "ACRANSAC was unable to estimate a rigid essential matrix" - << std::endl; - } } return EXIT_SUCCESS; } @@ -289,50 +291,3 @@ bool exportToPly(const std::vector & vec_points, outfile.close(); return bOk; } - -/// Triangulate and export valid point as PLY (point in front of the cameras) -void triangulateAndSaveResult( - const PinholeCamera & camL, - const PinholeCamera & camR, - const std::vector & vec_inliers, - const Mat & xL, - const Mat & xR, - std::vector & vec_3DPoints) -{ - std::vector vec_residuals; - size_t nbPointWithNegativeDepth = 0; - for (size_t k = 0; k < vec_inliers.size(); ++k) { - const Vec2 & xL_ = xL.col(vec_inliers[k]); - const Vec2 & xR_ = xR.col(vec_inliers[k]); - - Vec3 X = Vec3::Zero(); - TriangulateDLT(camL._P, xL_, camR._P, xR_, &X); - - // Compute residual: - double dResidual = (camL.Residual(X, xL_) + camR.Residual(X, xR_))/2.0; - vec_residuals.push_back(dResidual); - if (camL.Depth(X) < 0 && camR.Depth(X) < 0) { - ++nbPointWithNegativeDepth; - } - else { - vec_3DPoints.push_back(X); - } - } - if (nbPointWithNegativeDepth > 0) - { - std::cout << nbPointWithNegativeDepth - << " correspondence(s) with negative depth have been discarded." - << std::endl; - } - // Display some statistics of reprojection errors - float dMin, dMax, dMean, dMedian; - minMaxMeanMedian(vec_residuals.begin(), vec_residuals.end(), - dMin, dMax, dMean, dMedian); - - std::cout << std::endl - << "Essential matrix estimation, residuals statistics:" << "\n" - << "\t-- Residual min:\t" << dMin << std::endl - << "\t-- Residual median:\t" << dMedian << std::endl - << "\t-- Residual max:\t " << dMax << std::endl - << "\t-- Residual mean:\t " << dMean << std::endl; -} diff --git a/src/openMVG_Samples/robust_essential_ba/CMakeLists.txt b/src/openMVG_Samples/robust_essential_ba/CMakeLists.txt index 744d39232e..8eaf19ab37 100644 --- a/src/openMVG_Samples/robust_essential_ba/CMakeLists.txt +++ b/src/openMVG_Samples/robust_essential_ba/CMakeLists.txt @@ -3,12 +3,6 @@ ADD_DEFINITIONS(-DTHIS_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}") ADD_EXECUTABLE(openMVG_sample_robustEssential_ba robust_essential_ba.cpp) TARGET_LINK_LIBRARIES(openMVG_sample_robustEssential_ba - openMVG_image - openMVG_multiview - openMVG_features - vlsift - stlplus - ceres - ${OPENMVG_LIBRARY_DEPENDENCIES}) + ${OpenMVG_LIBS}) SET_PROPERTY(TARGET openMVG_sample_robustEssential_ba PROPERTY FOLDER OpenMVG/Samples) diff --git a/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp b/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp index e730e024fa..189c59eb10 100644 --- a/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp +++ b/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp @@ -6,22 +6,18 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "openMVG/cameras/PinholeCamera.hpp" +#include "openMVG/cameras/cameras.hpp" #include "openMVG/image/image.hpp" #include "openMVG/features/features.hpp" +#include "openMVG/sfm/sfm.hpp" + #include "openMVG/matching/matcher_brute_force.hpp" #include "openMVG/matching/indMatchDecoratorXY.hpp" -#include "openMVG/multiview/projection.hpp" #include "openMVG/multiview/triangulation.hpp" #include "openMVG_Samples/robust_essential/essential_estimation.hpp" #include "openMVG_Samples/siftPutativeMatches/two_view_matches.hpp" -// Bundle Adjustment includes -#include "openMVG/bundle_adjustment/problem_data_container.hpp" -#include "openMVG/bundle_adjustment/pinhole_ceres_functor.hpp" -#include "openMVG/bundle_adjustment/pinhole_brown_Rt_ceres_functor.hpp" - #include "nonFree/sift/SIFT_describer.hpp" #include "third_party/stlplus3/filesystemSimplified/file_system.hpp" @@ -33,7 +29,6 @@ using namespace openMVG; using namespace openMVG::image; using namespace openMVG::matching; -using namespace openMVG::bundle_adjustment; using namespace svg; using namespace std; @@ -43,49 +38,6 @@ using namespace std; /// 0 0 1 bool readIntrinsic(const std::string & fileName, Mat3 & K); -/// Export 3D point vector and camera position to PLY format -bool exportToPly(const std::vector & vec_points, - const std::vector & vec_camPos, - const std::string & sFileName); - -/// Triangulate and export valid point as PLY (point in front of the cameras) -void triangulateAndSaveResult( - const PinholeCamera & camL, - const PinholeCamera & camR, - std::vector & vec_inliers, - const Mat & xL, - const Mat & xR, - std::vector & vec_3DPoints); - -/// Perform a Bundle Adjustment: Refine the camera [R|t|focal] and the structure -void do_bundle_adjustment( - PinholeCamera & camL, - PinholeCamera & camR, - const Mat & xL, - const Mat & xR, - const std::vector & vec_inliers, - std::vector & vec_3DPoints); - -/// Perform a Bundle Adjustment: Refine the cameras [R|t], -/// and common pinhole intrinsic [focal,ppx,ppy] and the structure -void do_bundle_adjustment_common_intrinsic_pinhole( - PinholeCamera & camL, - PinholeCamera & camR, - const Mat & xL, - const Mat & xR, - const std::vector & vec_inliers, - std::vector & vec_3DPoints); - -/// Perform a Bundle Adjustment: Refine the cameras [R|t] -/// and common intrinsics [focal,ppx,ppy,k1,k2,k3] and the structure -void do_bundle_adjustment_common_intrinsics_brown_pinhole( - PinholeCamera & camL, - PinholeCamera & camR, - const Mat & xL, - const Mat & xR, - const std::vector & vec_inliers, - std::vector & vec_3DPoints); - /// Show : /// how computing an essential with know internal calibration matrix K /// how refine the camera motion, focal and structure with Bundle Adjustment @@ -93,7 +45,7 @@ void do_bundle_adjustment_common_intrinsics_brown_pinhole( /// way 2: independent cameras motion [R|t], shared focal [f] and structure int main() { - std::string sInputDir = stlplus::folder_up(string(THIS_SOURCE_DIR)) + const std::string sInputDir = stlplus::folder_up(string(THIS_SOURCE_DIR)) + "/imageData/SceauxCastle/"; Image image; const string jpg_filenameL = sInputDir + "100_7101.jpg"; @@ -162,6 +114,11 @@ int main() { vec_PutativeMatches, featsL, featsR); matchDeduplicator.getDeduplicated(vec_PutativeMatches); + std::cout + << regions_perImage.at(0)->RegionCount() << " #Features on image A" << std::endl + << regions_perImage.at(1)->RegionCount() << " #Features on image B" << std::endl + << vec_PutativeMatches.size() << " #matches with Distance Ratio filter" << std::endl; + // Draw correspondences after Nearest Neighbor ratio filter svgDrawer svgStream( imageL.Width() + imageR.Width(), max(imageL.Height(), imageR.Height())); svgStream.drawImage(jpg_filenameL, imageL.Width(), imageL.Height()); @@ -200,127 +157,110 @@ int main() { xR.col(k) = imaR.coords().cast(); } - //B. robust estimation of the essential matrix - std::vector vec_inliers; - Mat3 E; + //B. Compute the relative pose thanks to a essential matrix estimation std::pair size_imaL(imageL.Width(), imageL.Height()); std::pair size_imaR(imageR.Width(), imageR.Height()); - double thresholdE = 0.0, NFA = 0.0; - if (robustEssential( - K, K, // intrinsics - xL, xR, // corresponding points - &E, // essential matrix - &vec_inliers, // inliers - size_imaL, // Left image size - size_imaR, // Right image size - &thresholdE, // Found AContrario Theshold - &NFA, // Found AContrario NFA - std::numeric_limits::infinity())) + RelativePose_Info relativePose_info; + if (!robustRelativePose(K, K, xL, xR, relativePose_info, size_imaL, size_imaR, 256)) { - std::cout << "\nFound an Essential matrix under the confidence threshold of: " - << thresholdE << " pixels\n\twith: " << vec_inliers.size() << " inliers" - << " from: " << vec_PutativeMatches.size() - << " putatives correspondences" + std::cerr << " /!\\ Robust relative pose estimation failure." << std::endl; + return EXIT_FAILURE; + } - // Show Essential validated point - svgDrawer svgStream( imageL.Width() + imageR.Width(), max(imageL.Height(), imageR.Height())); - svgStream.drawImage(jpg_filenameL, imageL.Width(), imageL.Height()); - svgStream.drawImage(jpg_filenameR, imageR.Width(), imageR.Height(), imageL.Width()); - for ( size_t i = 0; i < vec_inliers.size(); ++i) { - const SIOPointFeature & LL = regionsL->Features()[vec_PutativeMatches[vec_inliers[i]]._i]; - const SIOPointFeature & RR = regionsR->Features()[vec_PutativeMatches[vec_inliers[i]]._j]; - const Vec2f L = LL.coords(); - const Vec2f R = RR.coords(); - svgStream.drawLine(L.x(), L.y(), R.x()+imageL.Width(), R.y(), svgStyle().stroke("green", 2.0)); - svgStream.drawCircle(L.x(), L.y(), LL.scale(), svgStyle().stroke("yellow", 2.0)); - svgStream.drawCircle(R.x()+imageL.Width(), R.y(), RR.scale(),svgStyle().stroke("yellow", 2.0)); - } - string out_filename = "04_ACRansacEssential.svg"; - ofstream svgFile( out_filename.c_str() ); - svgFile << svgStream.closeSvgFile().str(); - svgFile.close(); - - //C. Extract the rotation and translation of the camera from the essential matrix - Mat3 R; - Vec3 t; - if (!estimate_Rt_fromE(K, K, xL, xR, E, vec_inliers, - &R, &t)) - { - std::cerr << " /!\\ Failed to compute initial R|t for the initial pair" << std::endl; - return false; - } - std::cout << std::endl - << "-- Rotation|Translation matrices: --" << std::endl - << R << std::endl << std::endl << t << std::endl; - - // Build Left and Right Camera - PinholeCamera camL(K, Mat3::Identity(), Vec3::Zero()); - PinholeCamera camR(K, R, t); - - //C. Triangulate and check valid points - // invalid point that do not respect cheirality are discarded (removed - // from the list of inliers. - std::vector vec_3DPoints; - triangulateAndSaveResult( - camL, camR, - vec_inliers, - xL, xR, vec_3DPoints); - - //D. Refine the computed structure and cameras - std::cout << "Which BA do you want ? " << std::endl - << "\t 1: Refine [X],[f,R|t] (individual cameras)\n" - << "\t 2: Refine [X],[R|t], shared [f, ppx, ppy]\n" - << "\t 3: Refine [X],[R|t], shared brown disto models [f,ppx,ppy,k1,k2,k3]\n" << std::endl; - int iBAType = -1; - std::cin >> iBAType; - switch(iBAType) - { - case 1: - { - do_bundle_adjustment( - camL, camR, - xL, xR, - vec_inliers, - vec_3DPoints); - } - break; + std::cout << "\nFound an Essential matrix:\n" + << "\tprecision: " << relativePose_info.found_residual_precision << " pixels\n" + << "\t#inliers: " << relativePose_info.vec_inliers.size() << "\n" + << "\t#matches: " << vec_PutativeMatches.size() + << std::endl; - case 2: - { - do_bundle_adjustment_common_intrinsic_pinhole( - camL, camR, - xL, xR, - vec_inliers, - vec_3DPoints); - } - break; + // Show Essential validated point + svgDrawer svgStream( imageL.Width() + imageR.Width(), max(imageL.Height(), imageR.Height())); + svgStream.drawImage(jpg_filenameL, imageL.Width(), imageL.Height()); + svgStream.drawImage(jpg_filenameR, imageR.Width(), imageR.Height(), imageL.Width()); + for (size_t i = 0; i < relativePose_info.vec_inliers.size(); ++i) { + const SIOPointFeature & LL = regionsL->Features()[vec_PutativeMatches[relativePose_info.vec_inliers[i]]._i]; + const SIOPointFeature & RR = regionsR->Features()[vec_PutativeMatches[relativePose_info.vec_inliers[i]]._j]; + const Vec2f L = LL.coords(); + const Vec2f R = RR.coords(); + svgStream.drawLine(L.x(), L.y(), R.x()+imageL.Width(), R.y(), svgStyle().stroke("green", 2.0)); + svgStream.drawCircle(L.x(), L.y(), LL.scale(), svgStyle().stroke("yellow", 2.0)); + svgStream.drawCircle(R.x()+imageL.Width(), R.y(), RR.scale(),svgStyle().stroke("yellow", 2.0)); + } + const std::string out_filename = "04_ACRansacEssential.svg"; + std::ofstream svgFile( out_filename.c_str() ); + svgFile << svgStream.closeSvgFile().str(); + svgFile.close(); - case 3: - { - do_bundle_adjustment_common_intrinsics_brown_pinhole( - camL, camR, - xL, xR, - vec_inliers, - vec_3DPoints); - } + std::cout << std::endl + << "-- Rotation|Translation matrices: --" << "\n" + << relativePose_info.relativePose.rotation() << "\n\n" + << relativePose_info.relativePose.translation() << "\n" << std::endl; + + //C. Triangulate and check valid points + // invalid points that do not respect cheirality are discarded (removed + // from the list of inliers). + + std::cout << "Which BA do you want ?\n" + << "\t 1: Refine [X],[f,ppx,ppy,R|t] (individual cameras)\n" + << "\t 2: Refine [X],[R|t], shared [f, ppx, ppy]\n" + << "\t 3: Refine [X],[R|t], shared brown K3 distortion model [f,ppx,ppy,k1,k2,k3]\n" << std::endl; + int iBAType = -1; + std::cin >> iBAType; + const bool bSharedIntrinsic = (iBAType == 2 || iBAType == 3) ? true : false; + + // Setup a SfM scene with two view corresponding the pictures + SfM_Data tiny_scene; + tiny_scene.views[0].reset(new View("", 0, bSharedIntrinsic ? 0 : 1, 0, imageL.Width(), imageL.Height())); + tiny_scene.views[1].reset(new View("", 1, bSharedIntrinsic ? 0 : 1, 1, imageR.Width(), imageR.Height())); + // Setup intrinsics camera data + switch (iBAType) + { + case 1: // Each view use it's own pinhole camera intrinsic + tiny_scene.intrinsics[0].reset(new Pinhole_Intrinsic(imageL.Width(), imageL.Height(), K(0, 0), K(0, 2), K(1, 2))); + tiny_scene.intrinsics[1].reset(new Pinhole_Intrinsic(imageR.Width(), imageR.Height(), K(0, 0), K(0, 2), K(1, 2))); + break; + case 2: // Shared pinhole camera intrinsic + tiny_scene.intrinsics[0].reset(new Pinhole_Intrinsic(imageL.Width(), imageL.Height(), K(0, 0), K(0, 2), K(1, 2))); + break; + case 3: // Shared pinhole camera intrinsic with radial K3 distortion + tiny_scene.intrinsics[0].reset(new Pinhole_Intrinsic_Radial_K3(imageL.Width(), imageL.Height(), K(0, 0), K(0, 2), K(1, 2))); break; - default: - std::cerr << "Invalid input number" << std::endl; - } + default: + std::cerr << "Invalid input number" << std::endl; + return EXIT_FAILURE; + } + + // Setup poses camera data + const Pose3 pose0 = tiny_scene.poses[tiny_scene.views[0]->id_pose] = Pose3(Mat3::Identity(), Vec3::Zero()); + const Pose3 pose1 = tiny_scene.poses[tiny_scene.views[1]->id_pose] = relativePose_info.relativePose; + + // Init structure by inlier triangulation + const Mat34 P1 = tiny_scene.intrinsics[tiny_scene.views[0]->id_intrinsic]->get_projective_equivalent(pose0); + const Mat34 P2 = tiny_scene.intrinsics[tiny_scene.views[1]->id_intrinsic]->get_projective_equivalent(pose1); + Landmarks & landmarks = tiny_scene.structure; + for (size_t i = 0; i < relativePose_info.vec_inliers.size(); ++i) { + const SIOPointFeature & LL = regionsL->Features()[vec_PutativeMatches[relativePose_info.vec_inliers[i]]._i]; + const SIOPointFeature & RR = regionsR->Features()[vec_PutativeMatches[relativePose_info.vec_inliers[i]]._j]; + // Point triangulation + Vec3 X; + TriangulateDLT(P1, LL.coords().cast(), P2, RR.coords().cast(), &X); + // Reject point that is behind the camera + if (pose0.depth(X) < 0 && pose1.depth(X) < 0) + continue; + // Add a new landmark (3D point with it's 2d observations) + landmarks[i].obs[tiny_scene.views[0]->id_view] = Observation(LL.coords().cast(), vec_PutativeMatches[relativePose_info.vec_inliers[i]]._i); + landmarks[i].obs[tiny_scene.views[1]->id_view] = Observation(RR.coords().cast(), vec_PutativeMatches[relativePose_info.vec_inliers[i]]._j); + landmarks[i].X = X; + } + Save(tiny_scene, "EssentialGeometry_start.ply", ESfM_Data(ALL)); + //D. Perform Bundle Adjustment of the scene - //E. Export as PLY the refined scene (camera pos + 3Dpoints) - std::vector vec_camPos; - vec_camPos.push_back( camL._C ); - vec_camPos.push_back( camR._C ); - exportToPly(vec_3DPoints, vec_camPos, "EssentialGeometry.ply"); + Bundle_Adjustment_Ceres bundle_adjustment_obj; + bundle_adjustment_obj.Adjust(tiny_scene); - } - else { - std::cout << "ACRANSAC was unable to estimate a rigid essential matrix" - << std::endl; - } + Save(tiny_scene, "EssentialGeometry_refined.ply", ESfM_Data(ALL)); } return EXIT_SUCCESS; } @@ -342,7 +282,7 @@ bool readIntrinsic(const std::string & fileName, Mat3 & K) } return true; } - +/* /// Export 3D point vector and camera position to PLY format bool exportToPly(const std::vector & vec_points, const std::vector & vec_camPos, @@ -952,3 +892,4 @@ void do_bundle_adjustment_common_intrinsics_brown_pinhole( } } } +*/ \ No newline at end of file From 2c1ab05f9550a8c9a408de2f37a999fa38184bba Mon Sep 17 00:00:00 2001 From: pmoulon Date: Thu, 21 May 2015 09:16:52 +0200 Subject: [PATCH 15/52] Remove deprecated bundle_adjustment module. #302 --- .../bundle_adjustment/bundle_adjustment.rst | 59 -- docs/sphinx/rst/openMVG/cameras/cameras.rst | 27 +- docs/sphinx/rst/openMVG/openMVG.rst | 1 - docs/sphinx/rst/openMVG/sfm/sfm.rst | 21 +- src/openMVG/CMakeLists.txt | 1 - src/openMVG/bundle_adjustment/CMakeLists.txt | 2 - .../bundle_adjustment_test.cpp | 150 ----- .../pinhole_brown_Rt_ceres_functor.hpp | 124 ---- .../pinhole_ceres_functor.hpp | 227 ------- .../problem_data_container.hpp | 139 ---- src/openMVG/cameras/BrownPinholeCamera.hpp | 168 ----- src/openMVG/cameras/Camera_IO.hpp | 65 -- src/openMVG/cameras/Camera_IO_test.cpp | 24 - .../robust_essential_ba.cpp | 611 ------------------ 14 files changed, 29 insertions(+), 1590 deletions(-) delete mode 100644 docs/sphinx/rst/openMVG/bundle_adjustment/bundle_adjustment.rst delete mode 100644 src/openMVG/bundle_adjustment/CMakeLists.txt delete mode 100644 src/openMVG/bundle_adjustment/bundle_adjustment_test.cpp delete mode 100644 src/openMVG/bundle_adjustment/pinhole_brown_Rt_ceres_functor.hpp delete mode 100644 src/openMVG/bundle_adjustment/pinhole_ceres_functor.hpp delete mode 100644 src/openMVG/bundle_adjustment/problem_data_container.hpp delete mode 100644 src/openMVG/cameras/BrownPinholeCamera.hpp diff --git a/docs/sphinx/rst/openMVG/bundle_adjustment/bundle_adjustment.rst b/docs/sphinx/rst/openMVG/bundle_adjustment/bundle_adjustment.rst deleted file mode 100644 index 7daeb6990f..0000000000 --- a/docs/sphinx/rst/openMVG/bundle_adjustment/bundle_adjustment.rst +++ /dev/null @@ -1,59 +0,0 @@ -************************** -bundle_adjustment -************************** - -Bundle Adjustment (ajustement de faisceaux), is a non linear optimization problem. -It looks to minimizing the residual error of the observed tracks (the reprojection errors of the structure :math:`X_j` to the images measures :math:`x_j^i`. -According: - -* :math:`X_j` the Jnth 3D point of the structure of the scene, -* :math:`x_j^i` the observation of the projection of the 3D point :math:`X_j` in the image :math:`i`, -* :math:`P_i` the projection matrix of the image :math:`i` - -For initial guess of the vector of parameters: :math:`\{X_j,P_i\}_{i,j}`: camera parameters :math:`\{P_i\}_i` and the scene structure :math:`\{X_j\}_j`. -An iterative algorithm *Levenberg-Marquardt* updates the parameters vector according a gradient descent to minimizes the residual reprojection cost: - -.. math:: - \underset{ \{P_i\}_i, \{X_j\}_j}{minimize} \left\| \sum_{j=0}^{m} \sum_{i=0}^{n} x_j^i - P_i X_j \right\|_2 - -When subtle changes are observed on the cost function or on the norm of the parameters vector the algorithm is stopped. - -* Pros : - - * convergence is observed when the initial vector is close to the optimal solution. - -* Cons : - - * solution could be a local solution, if the cost function is not convex and the provided solution is not in the optimal convex set. - -openMVG bundle_adjustment framework -===================================== - -OpenMVG relies on the [Ceres]_ Google library to perform the Bundle Adjustment. -In order to ease its usage openMVG provides: - -* data container to setup the problem, -* functor (metric for various camera models), -* samples to show how to use them. - -bundle_adjustment container -______________________________ - -Two containers are defined in order to refine : - -* Cameras that have nothing in common: - - * A container to refine structure and cameras that do not share any common data. - - * The camera vector parameter is a 7 length vector: [Rotation(angle,axis), t, focal] - * ``template class BA_Problem_data`` - -* Cameras that share common data (intrinsics parameters): - - * A container to refine structure and cameras that share common data - - * To be used in the case of intrinsic parameters are shared between some cameras. - * The camera euclidean motion is ``NExternalParam`` values long: [R(angle axis)|t] - * The number intrinsic parameters ``NIntrinsicParam`` (i.e. 1): [focal] - * ``template class BA_Problem_data_camMotionAndIntrinsic`` - diff --git a/docs/sphinx/rst/openMVG/cameras/cameras.rst b/docs/sphinx/rst/openMVG/cameras/cameras.rst index 8cd799e4a0..648e550959 100644 --- a/docs/sphinx/rst/openMVG/cameras/cameras.rst +++ b/docs/sphinx/rst/openMVG/cameras/cameras.rst @@ -79,22 +79,6 @@ A 3D point is projected in a image with the following formula (homogeneous coord OpenMVG Pinhole camera models ------------------------------ -* Simple pinhole camera models (intrinsic + extrinsic(pose)) -* Pinhole camera models with radial distortion (intrinsic + extrinsic(pose)) - -.. code-block:: c++ - - // Setup a simple pinhole camera at origin - // Pinhole camera P = K[R|t], t = -RC - Mat3 K; - K << 1000, 0, 500, - 0, 1000, 500, - 0, 0, 1; - PinholeCamera cam(K, Mat3::Identity(), Vec3::Zero()); - - // Radial distortion (brown model -> polynomial distortion (K1 to k3)) - BrownPinholeCamera(K, Mat3::Identity(), Vec3::Zero(), k1, k2 , k3); - * Pinhole intrinsic * :class:`Pinhole_Intrinsic : public IntrinsicBase` @@ -111,3 +95,14 @@ OpenMVG Pinhole camera models * classic pinhole camera (Focal + principal point and image size) + radial distortion by three factors. * can add and remove distortion +* Simple pinhole camera models (intrinsic + extrinsic(pose)) + +.. code-block:: c++ + + // Setup a simple pinhole camera at origin + // Pinhole camera P = K[R|t], t = -RC + Mat3 K; + K << 1000, 0, 500, + 0, 1000, 500, + 0, 0, 1; + PinholeCamera cam(K, Mat3::Identity(), Vec3::Zero()); diff --git a/docs/sphinx/rst/openMVG/openMVG.rst b/docs/sphinx/rst/openMVG/openMVG.rst index 039a292bc1..b7c94af532 100644 --- a/docs/sphinx/rst/openMVG/openMVG.rst +++ b/docs/sphinx/rst/openMVG/openMVG.rst @@ -16,7 +16,6 @@ openMVG provide a collection of tiny libraries that allow to solve computer visi robust_estimation/robust_estimation.rst matching/matching.rst tracks/tracks.rst - bundle_adjustment/bundle_adjustment.rst geometry/geometry.rst diff --git a/docs/sphinx/rst/openMVG/sfm/sfm.rst b/docs/sphinx/rst/openMVG/sfm/sfm.rst index 8db6ea4d61..c7f094a221 100644 --- a/docs/sphinx/rst/openMVG/sfm/sfm.rst +++ b/docs/sphinx/rst/openMVG/sfm/sfm.rst @@ -110,9 +110,9 @@ Non linear refinement, Bundle Adjustment OpenMVG provides a generic bundle_adjustment framework to refine or keep as constant the following parameters: -* internal parameters, -* external parameters, -* 3D structure. +* internal orientation parameters (intrinsics: camera projection model), +* external orientation parameters (extrinsics: camera poses), +* structure (3D points). .. code-block:: c++ @@ -128,6 +128,21 @@ OpenMVG provides a generic bundle_adjustment framework to refine or keep as cons const double dResidual_after = RMSE(sfm_data); +Bundle Adjustment (ajustement de faisceaux), is a non linear optimization problem. +It looks to minimizing the residual error of a series of user cost functions (the reprojection errors of the structure :math:`X_j` to the images measures :math:`x_j^i`). +According: + +* :math:`X_j` the Jnth 3D point of the structure of the scene, +* :math:`x_j^i` the observation of the projection of the 3D point :math:`X_j` in the image :math:`i`, +* :math:`P_i` the projection matrix of the image :math:`i` + +From a user provided initial guess the vector of parameters: :math:`\{X_j,P_i\}_{i,j}`: camera parameters :math:`\{P_i\}_i` and the scene structure :math:`\{X_j\}_j` are refined in order to minimizes the residual reprojection cost: + +.. math:: + \underset{ \{P_i\}_i, \{X_j\}_j}{minimize} \left\| \sum_{j=0}^{m} \sum_{i=0}^{n} x_j^i - P_i X_j \right\|_2 + +OpenMVG proposes options in order to tell if a parameter group must be kept as constant or refined during the minimization. + SfM Pipelines ============== diff --git a/src/openMVG/CMakeLists.txt b/src/openMVG/CMakeLists.txt index 1f96653085..4d8aaced3c 100644 --- a/src/openMVG/CMakeLists.txt +++ b/src/openMVG/CMakeLists.txt @@ -1,4 +1,3 @@ -ADD_SUBDIRECTORY(bundle_adjustment) ADD_SUBDIRECTORY(cameras) ADD_SUBDIRECTORY(exif) ADD_SUBDIRECTORY(features) diff --git a/src/openMVG/bundle_adjustment/CMakeLists.txt b/src/openMVG/bundle_adjustment/CMakeLists.txt deleted file mode 100644 index e9fac4b780..0000000000 --- a/src/openMVG/bundle_adjustment/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ - -UNIT_TEST(openMVG bundle_adjustment "openMVG_multiview_test_data;openMVG_multiview;ceres") diff --git a/src/openMVG/bundle_adjustment/bundle_adjustment_test.cpp b/src/openMVG/bundle_adjustment/bundle_adjustment_test.cpp deleted file mode 100644 index 3ee8f109be..0000000000 --- a/src/openMVG/bundle_adjustment/bundle_adjustment_test.cpp +++ /dev/null @@ -1,150 +0,0 @@ - -// Copyright (c) 2012, 2013 Pierre MOULON. - -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -// An example of a minimal, self-contained bundle adjuster using Ceres -// It refines Focal, Rotation and Translation of the cameras. -// => A synthetic scene is used: -// a random noise between [-.5,.5] is added on observed data points - -#include "testing/testing.h" - -#include "openMVG/multiview/test_data_sets.hpp" -#include "openMVG/multiview/projection.hpp" - -// Bundle Adjustment includes -#include "openMVG/bundle_adjustment/pinhole_ceres_functor.hpp" -#include "openMVG/bundle_adjustment/problem_data_container.hpp" - -using namespace openMVG; -using namespace openMVG::bundle_adjustment; - -#include -#include -#include - -TEST(BUNDLE_ADJUSTMENT, EffectiveMinimization_RTf) { - - int nviews = 3; - int npoints = 6; - NViewDataSet d = NRealisticCamerasRing(nviews, npoints); - - // Setup a BA problem - BA_Problem_data<9> ba_problem; - - // Configure the size of the problem - ba_problem.num_cameras_ = nviews; - ba_problem.num_points_ = npoints; - ba_problem.num_observations_ = nviews * npoints; - - ba_problem.point_index_.reserve(ba_problem.num_observations_); - ba_problem.camera_index_.reserve(ba_problem.num_observations_); - ba_problem.observations_.reserve(2 * ba_problem.num_observations_); - - ba_problem.num_parameters_ = - 9 * ba_problem.num_cameras_ // #[Rotation|translation|K] = [3x1]|[3x1]|[3x1] - + 3 * ba_problem.num_points_; // #[X] = [3x1] - ba_problem.parameters_.reserve(ba_problem.num_parameters_); - - double ppx = 500, ppy = 500; - // Fill it with data (tracks and points coords) - for (int i = 0; i < npoints; ++i) { - // Collect the image of point i in each frame. - for (int j = 0; j < nviews; ++j) { - ba_problem.camera_index_.push_back(j); - ba_problem.point_index_.push_back(i); - const Vec2 & pt = d._x[j].col(i); - // => random noise between [-.5,.5] is added - ba_problem.observations_.push_back( pt(0) - ppx + rand()/RAND_MAX - .5); - ba_problem.observations_.push_back( pt(1) - ppy + rand()/RAND_MAX - .5); - } - } - - // Add camera parameters (R, t, K) - for (int j = 0; j < nviews; ++j) { - // Rotation matrix to angle axis - std::vector angleAxis(3); - ceres::RotationMatrixToAngleAxis((const double*)d._R[j].data(), &angleAxis[0]); - // translation - Vec3 t = d._t[j]; - double focal = d._K[j](0,0); - ba_problem.parameters_.push_back(angleAxis[0]); - ba_problem.parameters_.push_back(angleAxis[1]); - ba_problem.parameters_.push_back(angleAxis[2]); - ba_problem.parameters_.push_back(t[0]); - ba_problem.parameters_.push_back(t[1]); - ba_problem.parameters_.push_back(t[2]); - ba_problem.parameters_.push_back(focal); - ba_problem.parameters_.push_back(ppx); - ba_problem.parameters_.push_back(ppy); - } - - // Add 3D points coordinates parameters - for (int i = 0; i < npoints; ++i) { - Vec3 pt3D = d._X.col(i); - ba_problem.parameters_.push_back(pt3D[0]); - ba_problem.parameters_.push_back(pt3D[1]); - ba_problem.parameters_.push_back(pt3D[2]); - } - - // Create residuals for each observation in the bundle adjustment problem. The - // parameters for cameras and points are added automatically. - ceres::Problem problem; - for (int i = 0; i < ba_problem.num_observations(); ++i) { - // Each Residual block takes a point and a camera as input and outputs a 2 - // dimensional residual. Internally, the cost function stores the observed - // image location and compares the reprojection against the observation. - ceres::CostFunction* cost_function = - new ceres::AutoDiffCostFunction( - new pinhole_reprojectionError::ErrorFunc_Refine_Camera_3DPoints( - & ba_problem.observations()[2 * i])); - - problem.AddResidualBlock(cost_function, - NULL, // squared loss - ba_problem.mutable_camera_for_observation(i), - ba_problem.mutable_point_for_observation(i)); - } - - // Make Ceres automatically detect the bundle structure. Note that the - // standard solver, SPARSE_NORMAL_CHOLESKY, also works fine but it is slower - // for standard bundle adjustment problems. - ceres::Solver::Options options; - options.linear_solver_type = ceres::SPARSE_SCHUR; - if (ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::SUITE_SPARSE)) - options.sparse_linear_algebra_library_type = ceres::SUITE_SPARSE; - else - if (ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::CX_SPARSE)) - options.sparse_linear_algebra_library_type = ceres::CX_SPARSE; - else - { - // No sparse backend for Ceres. - // Use dense solving - options.linear_solver_type = ceres::DENSE_SCHUR; - } - options.minimizer_progress_to_stdout = false; - options.logging_type = ceres::SILENT; - - ceres::Solver::Summary summary; - ceres::Solve(options, &problem, &summary); - std::cout << summary.FullReport() << "\n"; - - double dResidual_before = std::sqrt( summary.initial_cost / (ba_problem.num_observations_*2.)); - double dResidual_after = std::sqrt( summary.final_cost / (ba_problem.num_observations_*2.)); - - std::cout << std::endl - << " Initial RMSE : " << dResidual_before << "\n" - << " Final RMSE : " << dResidual_after << "\n" - << std::endl; - - CHECK(summary.IsSolutionUsable()); - - EXPECT_TRUE( dResidual_before > dResidual_after); -} - -/* ************************************************************************* */ -int main() { TestResult tr; return TestRegistry::runAllTests(tr);} -/* ************************************************************************* */ diff --git a/src/openMVG/bundle_adjustment/pinhole_brown_Rt_ceres_functor.hpp b/src/openMVG/bundle_adjustment/pinhole_brown_Rt_ceres_functor.hpp deleted file mode 100644 index 210abbdeeb..0000000000 --- a/src/openMVG/bundle_adjustment/pinhole_brown_Rt_ceres_functor.hpp +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (c) 2013 Pierre MOULON. - -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef OPENMVG_BUNDLE_ADJUSTMENT_PINHOLE_BROWN_RT_CERES_FUNCTOR_HPP -#define OPENMVG_BUNDLE_ADJUSTMENT_PINHOLE_BROWN_RT_CERES_FUNCTOR_HPP - -#include "ceres/ceres.h" -#include "ceres/rotation.h" -#include "openMVG/cameras/BrownPinholeCamera.hpp" - -// Definition of a Functor for minimization of the reprojection error -// according the Brown's distortion model. -// A decentered distortion model. -// (||x^j_i - disto(f,ppx,ppx,k1,k2,k3,[R|t]_{ij}(X_j))||) -// A 3D point X_j is projected on a image plane i and compare to the observation -// x^j_i in the original image. - -namespace openMVG{ -namespace bundle_adjustment{ - -namespace pinhole_brown_reprojectionError { - -// Enum to order the intrinsics parameters into a single parameter block -enum { - OFFSET_FOCAL_LENGTH, - OFFSET_PRINCIPAL_POINT_X, - OFFSET_PRINCIPAL_POINT_Y, - OFFSET_K1, - OFFSET_K2, - OFFSET_K3//, -// OFFSET_P1, -// OFFSET_P2, -}; - -/** - * @brief Ceres functor to refine a pinhole camera using a brown radial - * distortion model, 3D points and focal. - * - * - first the intrinsic data block [focal;ppx;ppy;k1;k2;k3] - * - second the camera extrinsic block(camera orientation and position) [R;t] - * - 3 for rotation (angle axis), 3 for translation. - * - third the 3D point data block - * - * @see ApplyRadialDistortionIntrinsics - */ - -struct ErrorFunc_Refine_Camera_3DPoints -{ - ErrorFunc_Refine_Camera_3DPoints(const double* const pos_2dpoint) - { - m_pos_2dpoint[0] = pos_2dpoint[0]; - m_pos_2dpoint[1] = pos_2dpoint[1]; - } - - /// Compute the residual error after reprojection - /// residual = observed - BrownDistortion([R|t] X) - /** - * @param[in] cam_intrinsics: Camera intrinsics - * @param[in] cam_Rt: Camera extrinsics using one block of 6 parameters [R;t]: - * - 3 for rotation(angle axis), 3 for translation - * @param[in] pos_3dpoint - * @param[out] out_residuals - */ - template - bool operator()( - const T* const cam_intrinsics, - const T* const cam_Rt, - const T* const pos_3dpoint, - T* out_residuals) const - { - // Rt[0,1,2] : angle-axis camera rotation. - T x[3]; - ceres::AngleAxisRotatePoint(cam_Rt, pos_3dpoint, x); - - // Rt[3,4,5] : the camera translation. - x[0] += cam_Rt[3]; - x[1] += cam_Rt[4]; - x[2] += cam_Rt[5]; - - // Point from homogeneous to euclidean. - T xe = x[0] / x[2]; - T ye = x[1] / x[2]; - - // Unpack the intrinsics. - const T& focal_length = cam_intrinsics[OFFSET_FOCAL_LENGTH]; - const T& principal_point_x = cam_intrinsics[OFFSET_PRINCIPAL_POINT_X]; - const T& principal_point_y = cam_intrinsics[OFFSET_PRINCIPAL_POINT_Y]; - const T& k1 = cam_intrinsics[OFFSET_K1]; - const T& k2 = cam_intrinsics[OFFSET_K2]; - const T& k3 = cam_intrinsics[OFFSET_K3]; -// const T& p1 = cam_intrinsics[OFFSET_P1]; -// const T& p2 = cam_intrinsics[OFFSET_P2]; - - T predicted_x, predicted_y; - - // Apply distortion to the normalized points. - ApplyRadialDistortionIntrinsics( - focal_length, - focal_length, - principal_point_x, - principal_point_y, - k1, k2, k3, - xe, ye, - &predicted_x, - &predicted_y); - - // The error is the difference between the predicted and observed position. - out_residuals[0] = predicted_x - T(m_pos_2dpoint[0]); - out_residuals[1] = predicted_y - T(m_pos_2dpoint[1]); - - return true; - } - - double m_pos_2dpoint[2]; // The 2D observation -}; - -} // namespace pinhole_brown_reprojectionError -} // namespace bundle_adjustment -} // namespace openMVG - -#endif // OPENMVG_BUNDLE_ADJUSTMENT_PINHOLE_BROWN_RT_CERES_FUNCTOR_HPP diff --git a/src/openMVG/bundle_adjustment/pinhole_ceres_functor.hpp b/src/openMVG/bundle_adjustment/pinhole_ceres_functor.hpp deleted file mode 100644 index 7f5669a377..0000000000 --- a/src/openMVG/bundle_adjustment/pinhole_ceres_functor.hpp +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright (c) 2013 Pierre MOULON. - -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef OPENMVG_BUNDLE_ADJUSTMENT_PINHOLE_CERES_FUNCTOR_HPP -#define OPENMVG_BUNDLE_ADJUSTMENT_PINHOLE_CERES_FUNCTOR_HPP - -#include "ceres/ceres.h" -#include "ceres/rotation.h" - -namespace openMVG{ -namespace bundle_adjustment{ - -/** - * @group pinhole_reprojectionError - * @{ - * Definition of a Functor for minimization of the reprojection error - * (||x^j_i - P_{ij}(X_j)||) - * A 3D point X_j is projected on a image plane i and compare to the observation - * x^j_i. - */ -namespace pinhole_reprojectionError { - -// Enum to order the intrinsics parameters into a single parameter block -enum { - OFFSET_FOCAL_LENGTH = 0, - OFFSET_PRINCIPAL_POINT_X = 1, - OFFSET_PRINCIPAL_POINT_Y = 2 -}; - -/** - * @brief Compute the residual error after reprojection. - * residual = observed - euclidean( K * [R|t] X) - * - * @warning Principal point is assumed being applied on observed points. - * - * @param[in] cam_R Angle-axis camera rotation - * @param[in] cam_t (x, y, z) Camera translation - * @param[in] cam_K (f, ppx, ppy) Intrinsic data: (Focal length, principal point x and principal point y) - * @param[in] pos_3dpoint The observed 3D point - * @param[in] pos_2dpoint The image plane observation - * @param[out] out_residuals The residuals along the x and y axis - */ -template -void computeResidual( - const T* const cam_R, - const T* const cam_t, - const T* const cam_K, - const T* const pos_3dpoint, - const double* pos_2dpoint, - T* out_residuals ) -{ - T pos_proj[3]; - - // Apply the angle-axis camera rotation - ceres::AngleAxisRotatePoint(cam_R, pos_3dpoint, pos_proj); - - // Apply the camera translation - pos_proj[0] += cam_t[0]; - pos_proj[1] += cam_t[1]; - pos_proj[2] += cam_t[2]; - - // Transform the point from homogeneous to euclidean - T xe = pos_proj[0] / pos_proj[2]; - T ye = pos_proj[1] / pos_proj[2]; - - // Apply the focal length - const T& focal = cam_K[OFFSET_FOCAL_LENGTH]; - const T& principal_point_x = cam_K[OFFSET_PRINCIPAL_POINT_X]; - const T& principal_point_y = cam_K[OFFSET_PRINCIPAL_POINT_Y]; - - T predicted_x = focal * xe + principal_point_x; - T predicted_y = focal * ye + principal_point_y; - - // Compute and return the error is the difference between the predicted - // and observed position - out_residuals[0] = predicted_x - T(pos_2dpoint[0]); - out_residuals[1] = predicted_y - T(pos_2dpoint[1]); -} - -/** - * @brief Ceres functor to refine a pinhole camera model and 3D points. - * - * - first the intrinsic data block [focal, principal point x, principal point y] - * - second the camera extrinsic block (camera orientation and position) [R;t] - * - 3 for rotation(angle axis), 3 for translation. - * - third the 3D point data block - * - */ -struct ErrorFunc_Refine_Intrinsic_Motion_3DPoints -{ - ErrorFunc_Refine_Intrinsic_Motion_3DPoints(const double* const pos_2dpoint) - { - m_pos_2dpoint[0] = pos_2dpoint[0]; - m_pos_2dpoint[1] = pos_2dpoint[1]; - } - - ErrorFunc_Refine_Intrinsic_Motion_3DPoints(const float* const pos_2dpoint) - { - m_pos_2dpoint[0] = (double)pos_2dpoint[0]; - m_pos_2dpoint[1] = (double)pos_2dpoint[1]; - } - - /** - * @param[in] cam_K: Camera intrinsics( focal, principal point [x,y] ) - * @param[in] cam_Rt: Camera parameterized using one block of 6 parameters [R;t]: - * - 3 for rotation(angle axis), 3 for translation - * @param[in] pos_3dpoint - * @param[out] out_residuals - */ - template - bool operator()( - const T* const cam_K, - const T* const cam_Rt, - const T* const pos_3dpoint, - T* out_residuals) const - { - computeResidual( - cam_Rt, // => cam_R - & cam_Rt[3], // => cam_t - cam_K, - pos_3dpoint, - m_pos_2dpoint, - out_residuals ); - - return true; - } - - double m_pos_2dpoint[2]; // The 2D observation -}; - -/** - * @brief Ceres functor to refine a pinhole camera model and 3D points. - * - * @see computeResidual - */ -struct ErrorFunc_Refine_Camera_3DPoints -{ - ErrorFunc_Refine_Camera_3DPoints(const double* const pos_2dpoint) - { - m_pos_2dpoint[0] = pos_2dpoint[0]; - m_pos_2dpoint[1] = pos_2dpoint[1]; - } - - /** - * @param[in] cam_Rtf: Camera parameterized using one block of 9 parameters [R;t;K]: - * - 3 for rotation(angle axis), 3 for translation, 3 for intrinsics. - * @param[in] pos_3dpoint - * @param[out] out_residuals - */ - template - bool operator()( - const T* const cam_RtK, // [R;t;K] - const T* const pos_3dpoint, - T* out_residuals) const - { - computeResidual( - cam_RtK, // => cam_R - & cam_RtK[3], // => cam_t - & cam_RtK[6], // => cam_K - pos_3dpoint, - m_pos_2dpoint, - out_residuals); - - return true; - } - - double m_pos_2dpoint[2]; // The 2D observation -}; - -/** - * @brief Ceres functor to refine a pinhole camera model with static - * 2D 3D observation. - * - * @see computeResidual - */ -struct ErrorFunc_Refine_Camera -{ - ErrorFunc_Refine_Camera(const double* const pos_2dpoint, const double* const pos_3dpoint) - { - m_pos_2dpoint[0] = pos_2dpoint[0]; - m_pos_2dpoint[1] = pos_2dpoint[1]; - - m_pos_3dpoint[0] = pos_3dpoint[0]; - m_pos_3dpoint[1] = pos_3dpoint[1]; - m_pos_3dpoint[2] = pos_3dpoint[2]; - } - - /** - * @param[in] cam_Rtf: Camera parameterized using one block of 9 parameters [R;t;f]: - * - 3 for rotation(angle axis), 3 for translation, 3 for the intrinsics. - * @param[out] out_residuals - */ - template - bool operator()( - const T* const cam_RtK, // [R;t;K] - T* out_residuals) const - { - T pos_3dpoint[3]; - pos_3dpoint[0] = T(m_pos_3dpoint[0]); - pos_3dpoint[1] = T(m_pos_3dpoint[1]); - pos_3dpoint[2] = T(m_pos_3dpoint[2]); - - computeResidual( - cam_RtK, // => cam_R - & cam_RtK[3], // => cam_t - & cam_RtK[6], // => cam_K [f,ppx,ppy] - pos_3dpoint, - m_pos_2dpoint, - out_residuals); - - return true; - } - - double m_pos_2dpoint[2]; // The 2D observation - double m_pos_3dpoint[3]; // The 3D observation -}; - -} // namespace pinhole_reprojectionError -/// @} -} // namespace bundle_adjustment -} // namespace openMVG - -#endif - diff --git a/src/openMVG/bundle_adjustment/problem_data_container.hpp b/src/openMVG/bundle_adjustment/problem_data_container.hpp deleted file mode 100644 index 5c2b9f307b..0000000000 --- a/src/openMVG/bundle_adjustment/problem_data_container.hpp +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright (c) 2013 Pierre MOULON. - -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef OPENMVG_BUNDLE_ADJUSTMENT_PROBLEM_DATA_CONTAINER_HPP -#define OPENMVG_BUNDLE_ADJUSTMENT_PROBLEM_DATA_CONTAINER_HPP - -#include - -namespace openMVG{ -namespace bundle_adjustment{ - -/// Container for a Bundle Adjustment dataset -/// Allows to refine NCamParam per camera and the structure (3Dpts) -/// Used with 7 parameters by default: -/// (Rotation(angle,axis), t, focal) -template -class BA_Problem_data { - public: - - // Number of camera parameters - static const unsigned char NCAMPARAM = NCamParam; - - /// Return the number of observed 3D points - size_t num_observations() const { return num_observations_; } - /// Return a pointer to observed points [X_0, ... ,X_n] - const double* observations() const { return &observations_[0]; } - /// Return pointer to camera data - double* mutable_cameras() { - return ¶meters_[0];} - /// Return point to points data - double* mutable_points() { - return ¶meters_[0] + NCamParam * num_cameras_;} - - /// Return a pointer to the camera that observe the Inth observation - double* mutable_camera_for_observation(size_t i) { - return mutable_cameras() + camera_index_[i] * NCamParam; - } - /// Return a pointer to the point that observe the Inth observation - double* mutable_point_for_observation(size_t i) { - return mutable_points() + point_index_[i] * 3; - } - - size_t num_cameras_; // # of cameras - size_t num_points_; // # of 3D points - size_t num_observations_; // # of observations - size_t num_parameters_; // # of parameters ( NCamParam * #Cam + 3 * #Points) - - std::vector point_index_; // re-projection linked to the Inth 2d point - std::vector camera_index_; // re-projection linked to the Inth camera - std::vector observations_; // 3D points - - std::vector parameters_; // Camera parametrization -}; - -/// Container for a Bundle Adjustment dataset -/// Allows to refine cameras, shared intrinsics and the structure -/// Camera can be parametrized by the number of desired values -/// External parameter => 6: [Rotation(angle,axis), t] -/// Intrinsic => 1: [Focal] -template< - unsigned char NExternalParam = 6, - unsigned char NIntrinsicParam = 1> -class BA_Problem_data_camMotionAndIntrinsic { - public: - - // Number of camera parameters - static const unsigned char NEXTERNALPARAM = NExternalParam; - static const unsigned char NINTRINSICPARAM = NIntrinsicParam; - - /// Return the number of observed 3D points - size_t num_observations() const { return num_observations_; } - /// Return a pointer to observed points [X_0, ... ,X_n] - const double* observations() const { return &observations_[0]; } - - /// Return the number of extrinsic groups - size_t num_extrinsics() const { return num_cameras_ ;} - /// Return the number of intrinsic groups - size_t num_intrinsics() const { return num_intrinsics_;} - - /// Return a pointer to external camera data - double* mutable_cameras_extrinsic() { - return ¶meters_[0];} - /// Return a pointer to intrinsic camera data - double* mutable_cameras_intrinsic() { - return ¶meters_[0] + NExternalParam * num_cameras_;} - /// Return a pointer to 3D points data - double* mutable_points() { - return ¶meters_[0] - + NExternalParam * num_cameras_ - + NIntrinsicParam * num_intrinsics_;} - - /// Return a pointer to the camera extrinsic that observe the Inth observation - double* mutable_camera_extrinsic_for_observation(size_t i) { - return mutable_cameras_extrinsic() + camera_index_extrinsic[i] * NExternalParam; - } - /// Return a pointer to the camera intrinsic that observe the Inth observation - double* mutable_camera_intrinsic_for_observation(size_t i) { - return mutable_cameras_intrinsic() + camera_index_intrinsic[i] * NIntrinsicParam; - } - - /// Return a pointer to the Inth intrinsic parameters - double* mutable_cameras_intrinsic(size_t i) { - return mutable_cameras_intrinsic() + i * NIntrinsicParam; - } - /// Return a pointer to the Inth extrinsic parameters - double* mutable_cameras_extrinsic(size_t i) { - return mutable_cameras_extrinsic() + i * NExternalParam; - } - - - /// Return a pointer to the point that observe the Inth observation - double* mutable_point_for_observation(size_t i) { - return mutable_points() + point_index_[i] * 3; - } - - size_t num_cameras_; // # of cameras - size_t num_intrinsics_; // # of intrinsic groups - size_t num_points_; // # of 3D points - size_t num_observations_; // # of observations - // # of parameters: NIntrinsicParam * num_cameras_ + NIntrinsicParam * num_intrinsics_ + 3 * num_points_ - size_t num_parameters_; - - std::vector point_index_; // re-projection linked to the Inth 2d point - std::vector camera_index_extrinsic; // re-projection linked to the Inth camera extrinsic - std::vector camera_index_intrinsic; // re-projection linked to the Inth camera intrinsic - std::vector observations_; // 3D points - - // Camera parametrization ([R|t]_0,...,[R|t]_n,[f]_0,...,[f]_n) - std::vector parameters_; - -}; - -} // namespace bundle_adjustment -} // namespace openMVG - -#endif // OPENMVG_BUNDLE_ADJUSTMENT_PROBLEM_DATA_CONTAINER_HPP diff --git a/src/openMVG/cameras/BrownPinholeCamera.hpp b/src/openMVG/cameras/BrownPinholeCamera.hpp deleted file mode 100644 index 225a07c826..0000000000 --- a/src/openMVG/cameras/BrownPinholeCamera.hpp +++ /dev/null @@ -1,168 +0,0 @@ - -// Copyright (c) 2013 Pierre MOULON. - -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef OPENMVG_CAMERA_BROWNPINHOLECAMERA_H -#define OPENMVG_CAMERA_BROWNPINHOLECAMERA_H - -#include "openMVG/numeric/numeric.h" -#include "openMVG/multiview/projection.hpp" - -namespace openMVG{ - -// Apply camera intrinsics to the normalized point to get image coordinates. -// This applies the radial lens distortion to a point which is in normalized -// camera coordinates (i.e. the principal point is at (0, 0)) to get image -// coordinates in pixels. Templated for use with autodifferentiation. -template -inline void ApplyRadialDistortionIntrinsics( - const T &focal_length_x, - const T &focal_length_y, - const T &principal_point_x, - const T &principal_point_y, - const T &k1, - const T &k2, - const T &k3, - const T &normalized_x, - const T &normalized_y, - T *image_x, - T *image_y) { - T x = normalized_x; - T y = normalized_y; - - // Apply distortion to the normalized points to get (xd, yd). - T r2 = x*x + y*y; - T r4 = r2 * r2; - T r6 = r4 * r2; - T r_coeff = (T(1) + k1*r2 + k2*r4 + k3*r6); - T xd = x * r_coeff;// + T(2)*p1*x*y + p2*(r2 + T(2)*x*x); - T yd = y * r_coeff;// + T(2)*p2*x*y + p1*(r2 + T(2)*y*y); - - // Apply focal length and principal point to get the final image coordinates. - *image_x = principal_point_x + focal_length_x * xd; - *image_y = principal_point_y + focal_length_y * yd; -} - -/// Camera : euclidean motion [R|t] and Brown radial decentered distortion model -struct BrownPinholeCamera -{ - BrownPinholeCamera( - double focal = 1, - double ppx = 0, - double ppy = 0, - const Mat3 & R = Mat3::Identity(), - const Vec3 & t = Vec3::Zero(), - double k1 = 0.0, - double k2 = 0.0, - double k3 = 0.0) - : _R(R), _t(t), _f(focal), _ppx(ppx), _ppy(ppy), - _k1(k1), _k2(k2), _k3(k3) - { - _C = -R.transpose() * t; - _K << _f, 0, _ppx, - 0, _f, _ppy, - 0, 0, 1; - P_From_KRt(_K, _R, _t, &_P); - } - - BrownPinholeCamera( - const Mat3 & K, // = Mat3::Identity(), to remove ambiguity about the default constructor - const Mat3 & R, // = Mat3::Identity(), to remove ambiguity about the default constructor - const Vec3 & t, // = Vec3::Zero(), to remove ambiguity about the default constructor - double k1 = 0.0, - double k2 = 0.0, - double k3 = 0.0) - : _K(K), _R(R), _t(t), - _k1(k1), _k2(k2), _k3(k3) - { - _C = -R.transpose() * t; - _f = _K(0,0); - _ppx = _K(0,2); - _ppy = _K(1,2); - P_From_KRt(_K, _R, _t, &_P); - } - - BrownPinholeCamera(const PinholeCamera & P): - _P(P._P), _R(P._R), _t(P._t), _K(P._K), _k1(0.0), _k2(0.0), _k3(0.0) - { - _f = _K(0,0); - _ppx = _K(0,2); - _ppy = _K(1,2); - _C = -_R.transpose() * _t; - } - - /// Intrinsic parameters (Focal, principal point and radial distortion) - double _f, _ppx, _ppy, _k1, _k2, _k3; - - ///Extrinsic Rotation - Mat3 _R; - - /// Extrinsic translation - Vec3 _t; - - /// Camera center - Vec3 _C; - - Mat34 _P; - Mat3 _K; - - /// Projection of a 3D point into the camera plane (member function) - Vec2 Project(const Vec3 & pt3D) const - { - Vec3 X = _R * pt3D + _t; - // Point from homogeneous to euclidean. - double xe = X[0] / X[2]; - double ye = X[1] / X[2]; - - double xd, yd; - ApplyRadialDistortionIntrinsics( - _f, _f, _ppx, _ppy, _k1, _k2, _k3, - xe, ye, - &xd, &yd); - - return Vec2(xd, yd); - } - - /// Return the residual value to the given 2d point - double Residual(const Vec3 & pt3D, const Vec2 & ref) const { - return (ref - Project(pt3D)).norm(); - } - - /// Return the squared value of the residual to the givel 2d point - double ResidualSquared(const Vec3 & pt3D, const Vec2 & ref) const { - return (ref - Project(pt3D)).squaredNorm(); - } - - // Compute the depth of the X point. R*X[2]+t[2]. - double Depth(const Vec3 &X) const{ - return openMVG::Depth(_R, _t, X); - } - - /// Return the angle (degree) between two pinhole point rays - static double AngleBetweenRay( - const BrownPinholeCamera & cam1, - const BrownPinholeCamera & cam2, - const Vec2 & x1, const Vec2 & x2) - { - // x = (u, v, 1.0) // image coordinates - // X = R.t() * K.inv() * x + C // Camera world point - // getting the ray: - // ray = X - C = R.t() * K.inv() * x - Vec3 ray1 = (cam1._R.transpose() * - (cam1._K.inverse() * Vec3(x1(0), x1(1), 1.))).normalized(); - Vec3 ray2 = (cam2._R.transpose() * - (cam2._K.inverse() * Vec3(x2(0), x2(1), 1.))).normalized(); - double mag = std::sqrt(ray1.squaredNorm() * ray2.squaredNorm()); - double dotAngle = ray1.dot(ray2); - return R2D(acos(clamp(dotAngle/mag, -1.0 + 1.e-8, 1.0 - 1.e-8))); - } - -}; - -} // namespace openMVG - -#endif // #ifndef OPENMVG_CAMERA_BROWNPINHOLECAMERA_H - diff --git a/src/openMVG/cameras/Camera_IO.hpp b/src/openMVG/cameras/Camera_IO.hpp index 80044c686b..5d5fef0c46 100644 --- a/src/openMVG/cameras/Camera_IO.hpp +++ b/src/openMVG/cameras/Camera_IO.hpp @@ -9,7 +9,6 @@ #define OPENMVG_CAMERA_IO_H #include "openMVG/cameras/PinholeCamera.hpp" -#include "openMVG/cameras/BrownPinholeCamera.hpp" #include "third_party/stlplus3/filesystemSimplified/file_system.hpp" @@ -75,70 +74,6 @@ static bool load( return false; } -/// Load a BrownPinholeCamera saved as ascii file -static bool load( - const std::string & scameraFile, - BrownPinholeCamera & cam) -{ - if (stlplus::extension_part(scameraFile) != "txt") - return false; - - std::ifstream in(scameraFile.c_str(), std::ios::in); - if (!in.is_open()) { - std::cerr << "Error: failed to open file '" << scameraFile - << "' for reading" << std::endl; - return false; - } - double f, ppx, ppy, k1, k2, k3; - Mat3 R; - Vec3 t; - in >> f >> ppx >> ppy >> k1 >> k2 >> k3; - for (int i=0; i<3; ++i) { - for (int j=0; j<3; ++j) { - in >> R(i,j); - } - } - - for (int i=0; i<3; ++i) { - in >> t(i); - } - in.close(); - - if (!in.good()) { - return false; - } - - cam = BrownPinholeCamera(f, ppx, ppy, R, t, k1, k2, k3); - return true; -} - -/// Save a BrownPinholeCamera to a ascii file -static bool save( - const std::string & scameraFile, - const BrownPinholeCamera & cam) -{ - if (stlplus::extension_part(scameraFile) != "txt") - return false; - - std::ofstream file(scameraFile.c_str(), std::ios::out); - // Save intrinsic data: - file << cam._f << " " - << cam._ppx << " " - << cam._ppy << " " - << cam._k1 << " " - << cam._k2 << " " - << cam._k3 << "\n"; - // Save extrinsic data - const Mat3 & R = cam._R; - file << R(0,0) << " " << R(0,1) << " " << R(0,2) << "\n" - << R(1,0) << " " << R(1,1) << " " << R(1,2) << "\n" - << R(2,0) << " " << R(2,1) << " " << R(2,2) << "\n"; - file << cam._t(0) << " " << cam._t(1) << " " << cam._t(2) << "\n"; - bool bOk = (!file.fail()); - file.close(); - return bOk; -} - } // namespace openMVG #endif // OPENMVG_CAMERA_IO_H diff --git a/src/openMVG/cameras/Camera_IO_test.cpp b/src/openMVG/cameras/Camera_IO_test.cpp index 7a2946c011..ac6132b093 100644 --- a/src/openMVG/cameras/Camera_IO_test.cpp +++ b/src/openMVG/cameras/Camera_IO_test.cpp @@ -27,30 +27,6 @@ TEST(Camera_IO, PinholeSaveRead) { EXPECT_MATRIX_NEAR(camGT._P, cam._P, 1e-3); } -TEST(Camera_IO, BrownPinholeSaveRead) { - - const BrownPinholeCamera camGT( - 1000, 500, 500, - Mat3(Eigen::AngleAxisd(rand(), Vec3::UnitX()) - * Eigen::AngleAxisd(rand(), Vec3::UnitY()) - * Eigen::AngleAxisd(rand(), Vec3::UnitZ())), - Vec3(0,1,2), 0.2, 0.1, 0.05); - - EXPECT_TRUE( save( "BrownPinholeCam.txt", camGT)); - EXPECT_FALSE( save( "BrownPinholeCam.bin", camGT)); // extension must be .bin - - BrownPinholeCamera cam; - EXPECT_TRUE( load( "BrownPinholeCam.txt", cam)); - EXPECT_MATRIX_NEAR(camGT._P, cam._P, 1e-3); - EXPECT_EQ( camGT._f, cam._f); - EXPECT_EQ( camGT._ppx, cam._ppx); - EXPECT_EQ( camGT._ppy, cam._ppy); - EXPECT_EQ( camGT._k1, cam._k1); - EXPECT_EQ( camGT._k2, cam._k2); - EXPECT_EQ( camGT._k3, cam._k3); -} - - /* ************************************************************************* */ int main() { TestResult tr; return TestRegistry::runAllTests(tr);} /* ************************************************************************* */ diff --git a/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp b/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp index 189c59eb10..199b0fddef 100644 --- a/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp +++ b/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp @@ -282,614 +282,3 @@ bool readIntrinsic(const std::string & fileName, Mat3 & K) } return true; } -/* -/// Export 3D point vector and camera position to PLY format -bool exportToPly(const std::vector & vec_points, - const std::vector & vec_camPos, - const std::string & sFileName) -{ - std::ofstream outfile; - outfile.open(sFileName.c_str(), std::ios_base::out); - - outfile << "ply" - << '\n' << "format ascii 1.0" - << '\n' << "element vertex " << vec_points.size()+vec_camPos.size() - << '\n' << "property float x" - << '\n' << "property float y" - << '\n' << "property float z" - << '\n' << "property uchar red" - << '\n' << "property uchar green" - << '\n' << "property uchar blue" - << '\n' << "end_header" << std::endl; - - for (size_t i=0; i < vec_points.size(); ++i) { - outfile << vec_points[i].transpose() - << " 255 255 255" << "\n"; - } - - for (size_t i=0; i < vec_camPos.size(); ++i) { - outfile << vec_camPos[i].transpose() - << " 0 255 0" << "\n"; - } - outfile.flush(); - bool bOk = outfile.good(); - outfile.close(); - return bOk; -} - -/// Triangulate and export valid point as PLY (point in front of the cameras) -void triangulateAndSaveResult( - const PinholeCamera & camL, - const PinholeCamera & camR, - std::vector & vec_inliers, - const Mat & xL, - const Mat & xR, - std::vector & vec_3DPoints) -{ - size_t nb_invalid3DPoints = 0; - std::vector vec_valid3DPoints; - std::vector vec_residuals; - for (size_t k = 0; k < vec_inliers.size(); ++k) { - const Vec2 & xL_ = xL.col(vec_inliers[k]); - const Vec2 & xR_ = xR.col(vec_inliers[k]); - - Vec3 X = Vec3::Zero(); - TriangulateDLT(camL._P, xL_, camR._P, xR_, &X); - - // Compute residual: - double dResidual = (camL.Residual(X, xL_) + camR.Residual(X, xR_))/2.0; - vec_residuals.push_back(dResidual); - if (camL.Depth(X) < 0 && camR.Depth(X) < 0) { - ++nb_invalid3DPoints; - } - else { - vec_3DPoints.push_back(X); - vec_valid3DPoints.push_back(vec_inliers[k]); - } - } - if (nb_invalid3DPoints > 0) - { - std::cout << nb_invalid3DPoints - << " correspondence(s) with negative depth have been discarded." - << std::endl; - // remove from the inliers list the point that are behind the camera - vec_inliers = vec_valid3DPoints; - } - - // Display some statistics of reprojection errors - float dMin, dMax, dMean, dMedian; - minMaxMeanMedian(vec_residuals.begin(), vec_residuals.end(), - dMin, dMax, dMean, dMedian); - - std::cout << std::endl - << "Essential matrix estimation, residuals statistics:" << "\n" - << "\t-- Residual min:\t" << dMin << std::endl - << "\t-- Residual median:\t" << dMedian << std::endl - << "\t-- Residual max:\t " << dMax << std::endl - << "\t-- Residual mean:\t " << dMean << std::endl; -} - -void do_bundle_adjustment( - PinholeCamera & camL, - PinholeCamera & camR, - const Mat & xL, - const Mat & xR, - const std::vector & vec_inliers, - std::vector & vec_3DPoints) -{ - int nviews = 2; - int n3Dpoints = vec_inliers.size(); - - // Setup a BA problem - BA_Problem_data<7> ba_problem; - - // Configure the size of the problem - ba_problem.num_cameras_ = nviews; - ba_problem.num_points_ = n3Dpoints; - ba_problem.num_observations_ = nviews * n3Dpoints; - - ba_problem.point_index_.reserve(ba_problem.num_observations_); - ba_problem.camera_index_.reserve(ba_problem.num_observations_); - ba_problem.observations_.reserve(2 * ba_problem.num_observations_); - - ba_problem.num_parameters_ = 7 * ba_problem.num_cameras_ + 3 * ba_problem.num_points_; - ba_problem.parameters_.reserve(ba_problem.num_parameters_); - - // Fill it with data (For each 3D point setup the tracks : the 2D visbility) - PinholeCamera vec_cam[2] = {camL, camR}; - for (int i = 0; i < n3Dpoints; ++i) { - // Collect the image of point i in each frame (xL, xR). - const Vec2 & xL_ = xL.col(vec_inliers[i]); - const Vec2 & xR_ = xR.col(vec_inliers[i]); - - // Left 2D observations - double ppx = vec_cam[0]._K(0,2), ppy = vec_cam[0]._K(1,2); - ba_problem.camera_index_.push_back(0); - ba_problem.point_index_.push_back(i); - ba_problem.observations_.push_back( xL_(0) - ppx); - ba_problem.observations_.push_back( xL_(1) - ppy); - - // Right 2D observations - ppx = vec_cam[1]._K(0,2); - ppy = vec_cam[1]._K(1,2); - ba_problem.camera_index_.push_back(1); - ba_problem.point_index_.push_back(i); - ba_problem.observations_.push_back( xR_(0) - ppx); - ba_problem.observations_.push_back( xR_(1) - ppy); - } - - // Add camera parameters (R, t, focal) - for (int j = 0; j < nviews; ++j) { - // Rotation matrix to angle axis - std::vector angleAxis(3); - ceres::RotationMatrixToAngleAxis((const double*)vec_cam[j]._R.data(), &angleAxis[0]); - // translation - Vec3 t = vec_cam[j]._t; - double focal = vec_cam[j]._K(0,0); - ba_problem.parameters_.push_back(angleAxis[0]); - ba_problem.parameters_.push_back(angleAxis[1]); - ba_problem.parameters_.push_back(angleAxis[2]); - ba_problem.parameters_.push_back(t[0]); - ba_problem.parameters_.push_back(t[1]); - ba_problem.parameters_.push_back(t[2]); - ba_problem.parameters_.push_back(focal); - } - - // Add 3D points coordinates parameters - for (int i = 0; i < n3Dpoints; ++i) { - Vec3 pt3D = vec_3DPoints[i]; - ba_problem.parameters_.push_back(pt3D[0]); - ba_problem.parameters_.push_back(pt3D[1]); - ba_problem.parameters_.push_back(pt3D[2]); - } - - // Create residuals for each observation in the bundle adjustment problem. The - // parameters for cameras and points are added automatically. - ceres::Problem problem; - for (int i = 0; i < ba_problem.num_observations(); ++i) { - - // Each Residual block takes a point and a camera as input and outputs a 2 - // dimensional residual. Internally, the cost function stores the observed - // image location and compares the reprojection against the observation. - ceres::CostFunction* cost_function = - new ceres::AutoDiffCostFunction( - new pinhole_reprojectionError::ErrorFunc_Refine_Camera_3DPoints( - & ba_problem.observations()[2 * i])); - - problem.AddResidualBlock(cost_function, - NULL, // squared loss - ba_problem.mutable_camera_for_observation(i), - ba_problem.mutable_point_for_observation(i)); - } - - // Make Ceres automatically detect the bundle structure. Note that the - // standard solver, SPARSE_NORMAL_CHOLESKY, also works fine but it is slower - // for standard bundle adjustment problems. - ceres::Solver::Options options; - options.linear_solver_type = ceres::SPARSE_SCHUR; - if (ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::SUITE_SPARSE)) - options.sparse_linear_algebra_library_type = ceres::SUITE_SPARSE; - else - if (ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::CX_SPARSE)) - options.sparse_linear_algebra_library_type = ceres::CX_SPARSE; - else - { - // No sparse backend for Ceres. - // Use dense solving - options.linear_solver_type = ceres::DENSE_SCHUR; - } - options.minimizer_progress_to_stdout = false; - options.logging_type = ceres::SILENT; - - ceres::Solver::Summary summary; - ceres::Solve(options, &problem, &summary); - - double dResidual_before = std::sqrt( summary.initial_cost / (ba_problem.num_observations_*2.)); - double dResidual_after = std::sqrt( summary.final_cost / (ba_problem.num_observations_*2.)); - - std::cout << std::endl - << "Bundle Adjustment of cameras [R|t|f] and Structure : \n" - << " Initial RMSE : " << dResidual_before << "\n" - << " Final RMSE : " << dResidual_after << std::endl; - - // If no error, get back refined parameters - if (summary.IsSolutionUsable()) - { - // Get back 3D points - size_t cpt = 0; - for (std::vector::iterator iter = vec_3DPoints.begin(); - iter != vec_3DPoints.end(); ++iter, ++cpt) - { - const double * pt = ba_problem.mutable_points() + cpt*3; - Vec3 & pt3D = *iter; - pt3D = Vec3(pt[0], pt[1], pt[2]); - } - // Get back camera - for (cpt = 0; cpt < nviews; ++cpt) - { - const double * cam = ba_problem.mutable_cameras() + cpt*7; - Mat3 R; - // angle axis to rotation matrix - ceres::AngleAxisToRotationMatrix(cam, R.data()); - Vec3 t(cam[3], cam[4], cam[5]); - double focal = cam[6]; - - // Update the camera - PinholeCamera & sCam = vec_cam[cpt]; - Mat3 K = sCam._K; - K(0,0) = K(1,1) = focal; - std::cout << "Refined focal[" << cpt << "]: " << focal << std::endl; - sCam = PinholeCamera(K, R, t); - } - } -} - -/// Perform a Bundle Adjustment: Refine the cameras [R|t], -/// common intrinsic [focal,ppx,ppy] and the structure -void do_bundle_adjustment_common_intrinsic_pinhole( - PinholeCamera & camL, - PinholeCamera & camR, - const Mat & xL, - const Mat & xR, - const std::vector & vec_inliers, - std::vector & vec_3DPoints) -{ - int nCameraMotion = 2; - int nCameraIntrinsic = 1; - int n3Dpoints = vec_inliers.size(); - - // Setup a BA problem - BA_Problem_data_camMotionAndIntrinsic<6,3> ba_problem; - - // Configure the size of the problem - ba_problem.num_cameras_ = nCameraMotion; - ba_problem.num_intrinsics_ = nCameraIntrinsic; - ba_problem.num_points_ = n3Dpoints; - ba_problem.num_observations_ = nCameraMotion * n3Dpoints; - - ba_problem.point_index_.reserve(ba_problem.num_observations_); - ba_problem.camera_index_extrinsic.reserve(ba_problem.num_observations_); - ba_problem.camera_index_intrinsic.reserve(ba_problem.num_observations_); - ba_problem.observations_.reserve(2 * ba_problem.num_observations_); - - ba_problem.num_parameters_ = - 6 * ba_problem.num_cameras_ + 3 * ba_problem.num_intrinsics_ + 3 * ba_problem.num_points_; - ba_problem.parameters_.reserve(ba_problem.num_parameters_); - - // Fill it with data (For each 3D point setup the tracks : the 2D visbility) - // The two camera share the same intrinsic - PinholeCamera vec_cam[2] = {camL, camR}; - for (int i = 0; i < n3Dpoints; ++i) { - // Collect the image of point i in each frame (xL, xR). - const Vec2 & xL_ = xL.col(vec_inliers[i]); - const Vec2 & xR_ = xR.col(vec_inliers[i]); - - // Left 2D observations - - ba_problem.camera_index_extrinsic.push_back(0); - ba_problem.camera_index_intrinsic.push_back(0); - ba_problem.point_index_.push_back(i); - ba_problem.observations_.push_back(xL_(0)); - ba_problem.observations_.push_back(xL_(1)); - - // Right 2D observations - ba_problem.camera_index_extrinsic.push_back(1); - ba_problem.camera_index_intrinsic.push_back(0); // same intrinsic group - ba_problem.point_index_.push_back(i); - ba_problem.observations_.push_back(xR_(0)); - ba_problem.observations_.push_back(xR_(1)); - } - - // Add camera extrinsics [R,t] - for (int j = 0; j < nCameraMotion; ++j) { - // Rotation matrix to angle axis - std::vector angleAxis(3); - ceres::RotationMatrixToAngleAxis((const double*)vec_cam[j]._R.data(), &angleAxis[0]); - // translation - Vec3 t = vec_cam[j]._t; - ba_problem.parameters_.push_back(angleAxis[0]); - ba_problem.parameters_.push_back(angleAxis[1]); - ba_problem.parameters_.push_back(angleAxis[2]); - ba_problem.parameters_.push_back(t[0]); - ba_problem.parameters_.push_back(t[1]); - ba_problem.parameters_.push_back(t[2]); - } - // Add camera intrinsic (focal) - double - focal = (vec_cam[0]._K(0,0) + vec_cam[0]._K(1,1) - + vec_cam[1]._K(1,1) + vec_cam[1]._K(0,0)) / 4.0; - double ppx = (vec_cam[0]._K(0,2) + vec_cam[1]._K(0,2)) / 2.0; - double ppy = (vec_cam[0]._K(1,2) + vec_cam[1]._K(1,2)) / 2.0; - // Setup the intrinsic in the ba_problem - ba_problem.parameters_.push_back(focal); - ba_problem.parameters_.push_back(ppx); - ba_problem.parameters_.push_back(ppy); - - // Add 3D points coordinates parameters - for (int i = 0; i < n3Dpoints; ++i) { - Vec3 pt3D = vec_3DPoints[i]; - ba_problem.parameters_.push_back(pt3D[0]); - ba_problem.parameters_.push_back(pt3D[1]); - ba_problem.parameters_.push_back(pt3D[2]); - } - - // Create residuals for each observation in the bundle adjustment problem. The - // parameters for cameras and points are added automatically. - ceres::Problem problem; - for (int i = 0; i < ba_problem.num_observations(); ++i) { - - // Each Residual block takes a point and a camera as input and outputs a 2 - // dimensional residual. Internally, the cost function stores the observed - // image location and compares the reprojection against the observation. - ceres::CostFunction* cost_function = - new ceres::AutoDiffCostFunction( - new pinhole_reprojectionError::ErrorFunc_Refine_Intrinsic_Motion_3DPoints( - & ba_problem.observations()[2 * i])); - - problem.AddResidualBlock(cost_function, - NULL, // squared loss - ba_problem.mutable_camera_intrinsic_for_observation(i), - ba_problem.mutable_camera_extrinsic_for_observation(i), - ba_problem.mutable_point_for_observation(i)); - } - - // Make Ceres automatically detect the bundle structure. Note that the - // standard solver, SPARSE_NORMAL_CHOLESKY, also works fine but it is slower - // for standard bundle adjustment problems. - ceres::Solver::Options options; - options.linear_solver_type = ceres::SPARSE_SCHUR; - if (ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::SUITE_SPARSE)) - options.sparse_linear_algebra_library_type = ceres::SUITE_SPARSE; - else - if (ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::CX_SPARSE)) - options.sparse_linear_algebra_library_type = ceres::CX_SPARSE; - else - { - // No sparse backend for Ceres. - // Use dense solving - options.linear_solver_type = ceres::DENSE_SCHUR; - } - options.minimizer_progress_to_stdout = false; - options.logging_type = ceres::SILENT; - - ceres::Solver::Summary summary; - ceres::Solve(options, &problem, &summary); - - double dResidual_before = std::sqrt( summary.initial_cost / (ba_problem.num_observations_*2.)); - double dResidual_after = std::sqrt( summary.final_cost / (ba_problem.num_observations_*2.)); - - std::cout << std::endl - << "Bundle Adjustment of cameras [R|t], shared [f] and Structure : \n" - << " Initial RMSE : " << dResidual_before << "\n" - << " Final RMSE : " << dResidual_after << "\n" - << "Initial focal : " << focal << "\n" - << "Initial ppx : " << ppx << "\n" - << "Initial ppy : " << ppy << std::endl; - - // If no error, get back refined parameters - if (summary.IsSolutionUsable()) - { - // Get back 3D points - size_t cpt = 0; - for (std::vector::iterator iter = vec_3DPoints.begin(); - iter != vec_3DPoints.end(); ++iter, ++cpt) - { - const double * pt = ba_problem.mutable_points() + cpt*3; - Vec3 & pt3D = *iter; - pt3D = Vec3(pt[0], pt[1], pt[2]); - } - // Get back camera - for (cpt = 0; cpt < nCameraMotion; ++cpt) - { - const double * cam = ba_problem.mutable_cameras_extrinsic() + cpt*6; - Mat3 R; - // angle axis to rotation matrix - ceres::AngleAxisToRotationMatrix(cam, R.data()); - Vec3 t(cam[3], cam[4], cam[5]); - - // Update the camera - PinholeCamera & sCam = vec_cam[cpt]; - Mat3 K = sCam._K; - double * intrinsics = ba_problem.mutable_cameras_intrinsic(); - std::cout << "Refined focal[" << cpt << "]: " << intrinsics[pinhole_reprojectionError::OFFSET_FOCAL_LENGTH] << std::endl; - std::cout << "Refined ppx[" << cpt << "]: " << intrinsics[pinhole_reprojectionError::OFFSET_PRINCIPAL_POINT_X] << std::endl; - std::cout << "Refined ppy[" << cpt << "]: " << intrinsics[pinhole_reprojectionError::OFFSET_PRINCIPAL_POINT_Y] << std::endl; - K(0,0) = K(1,1) = focal; - sCam = PinholeCamera(K, R, t); - } - } -} - -/// Perform a Bundle Adjustment: Refine the cameras [R|t] -/// and common intrinsics [focal,ppx,ppy,k1,k2,k3] and the structure -void do_bundle_adjustment_common_intrinsics_brown_pinhole( - PinholeCamera & camL, - PinholeCamera & camR, - const Mat & xL, - const Mat & xR, - const std::vector & vec_inliers, - std::vector & vec_3DPoints) -{ - int nCameraMotion = 2; - int nCameraIntrinsic = 1; - int n3Dpoints = vec_inliers.size(); - - // Setup a BA problem - BA_Problem_data_camMotionAndIntrinsic<6, 6> ba_problem; - - // Configure the size of the problem - ba_problem.num_cameras_ = nCameraMotion; - ba_problem.num_intrinsics_ = nCameraIntrinsic; - ba_problem.num_points_ = n3Dpoints; - ba_problem.num_observations_ = nCameraMotion * n3Dpoints; - - ba_problem.point_index_.reserve(ba_problem.num_observations_); - ba_problem.camera_index_extrinsic.reserve(ba_problem.num_observations_); - ba_problem.camera_index_intrinsic.reserve(ba_problem.num_observations_); - ba_problem.observations_.reserve(2 * ba_problem.num_observations_); - - ba_problem.num_parameters_ = - 6 * ba_problem.num_cameras_ + 6 * ba_problem.num_intrinsics_ + 3 * ba_problem.num_points_; - ba_problem.parameters_.reserve(ba_problem.num_parameters_); - - // Fill it with data (For each 3D point setup the tracks : the 2D visibility) - // The two camera share the same intrinsic - PinholeCamera vec_cam[2] = {camL, camR}; - for (int i = 0; i < n3Dpoints; ++i) { - // Collect the image of point i in each frame (xL, xR). - const Vec2 & xL_ = xL.col(vec_inliers[i]); - const Vec2 & xR_ = xR.col(vec_inliers[i]); - - // Left 2D observations - ba_problem.camera_index_extrinsic.push_back(0); - ba_problem.camera_index_intrinsic.push_back(0); - ba_problem.point_index_.push_back(i); - ba_problem.observations_.push_back(xL_(0)); - ba_problem.observations_.push_back(xL_(1)); - - // Right 2D observations - ba_problem.camera_index_extrinsic.push_back(1); - ba_problem.camera_index_intrinsic.push_back(0); // same intrinsic group - ba_problem.point_index_.push_back(i); - ba_problem.observations_.push_back(xR_(0)); - ba_problem.observations_.push_back(xR_(1)); - } - - // Add camera extrinsics [R,t] - for (int j = 0; j < nCameraMotion; ++j) { - // Rotation matrix to angle axis - std::vector angleAxis(3); - ceres::RotationMatrixToAngleAxis((const double*)vec_cam[j]._R.data(), &angleAxis[0]); - // translation - Vec3 t = vec_cam[j]._t; - ba_problem.parameters_.push_back(angleAxis[0]); - ba_problem.parameters_.push_back(angleAxis[1]); - ba_problem.parameters_.push_back(angleAxis[2]); - ba_problem.parameters_.push_back(t[0]); - ba_problem.parameters_.push_back(t[1]); - ba_problem.parameters_.push_back(t[2]); - } - - // Add camera intrinsics (focal, ppx, ppy, k1, k2, k3) - { - double focal = (vec_cam[0]._K(0,0) + vec_cam[0]._K(1,1) - + vec_cam[1]._K(1,1) + vec_cam[1]._K(0,0)) / 4.0; - double ppx = (vec_cam[0]._K(0,2) + vec_cam[1]._K(0,2)) / 2.0; - double ppy = (vec_cam[0]._K(1,2) + vec_cam[1]._K(1,2)) / 2.0; - double k1 = 0.0, k2 = 0.0, k3 = 0.0; - - // Setup intrinsics in the ba_problem - ba_problem.parameters_.push_back(focal); - ba_problem.parameters_.push_back(ppx); - ba_problem.parameters_.push_back(ppy); - ba_problem.parameters_.push_back(k1); - ba_problem.parameters_.push_back(k2); - ba_problem.parameters_.push_back(k3); - } - - - // Add 3D points coordinates parameters - for (int i = 0; i < n3Dpoints; ++i) { - Vec3 pt3D = vec_3DPoints[i]; - double * ptr3D = ba_problem.mutable_points() + i * 3; - ba_problem.parameters_.push_back(pt3D[0]); - ba_problem.parameters_.push_back(pt3D[1]); - ba_problem.parameters_.push_back(pt3D[2]); - } - - // Create residuals for each observation in the bundle adjustment problem. The - // parameters for cameras and points are added automatically. - ceres::Problem problem; - for (int i = 0; i < ba_problem.num_observations(); ++i) { - - // Each Residual block takes a point and a camera as input and outputs a 2 - // dimensional residual. Internally, the cost function stores the observed - // image location and compares the reprojection against the observation. - ceres::CostFunction* cost_function = - new ceres::AutoDiffCostFunction( - new pinhole_brown_reprojectionError::ErrorFunc_Refine_Camera_3DPoints( - & ba_problem.observations()[2 * i + 0])); - - problem.AddResidualBlock(cost_function, - NULL, // squared loss - ba_problem.mutable_camera_intrinsic_for_observation(i), - ba_problem.mutable_camera_extrinsic_for_observation(i), - ba_problem.mutable_point_for_observation(i)); - } - - // Make Ceres automatically detect the bundle structure. Note that the - // standard solver, SPARSE_NORMAL_CHOLESKY, also works fine but it is slower - // for standard bundle adjustment problems. - ceres::Solver::Options options; - options.linear_solver_type = ceres::SPARSE_SCHUR; - if (ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::SUITE_SPARSE)) - options.sparse_linear_algebra_library_type = ceres::SUITE_SPARSE; - else - if (ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::CX_SPARSE)) - options.sparse_linear_algebra_library_type = ceres::CX_SPARSE; - else - { - // No sparse backend for Ceres. - // Use dense solving - options.linear_solver_type = ceres::DENSE_SCHUR; - } - options.minimizer_progress_to_stdout = false; - options.logging_type = ceres::SILENT; - - ceres::Solver::Summary summary; - ceres::Solve(options, &problem, &summary); - //std::cout << summary.FullReport() << std::endl; - - double dResidual_before = std::sqrt( summary.initial_cost / (ba_problem.num_observations_*2.)); - double dResidual_after = std::sqrt( summary.final_cost / (ba_problem.num_observations_*2.)); - - std::cout << std::endl - << "Bundle Adjustment of struture [X], cameras extrinsics [R|t]," - << " and shared intrinsics [f,ppx,ppy,k1,k2,k3]: \n" - << " Initial RMSE : " << dResidual_before << "\n" - << " Final RMSE : " << dResidual_after << "\n" - << "Refined intrinsics : " << std::endl; - - // If no error, get back refined parameters - if (summary.IsSolutionUsable()) - { - // Get back 3D points - size_t cpt = 0; - for (std::vector::iterator iter = vec_3DPoints.begin(); - iter != vec_3DPoints.end(); ++iter, ++cpt) - { - const double * pt = ba_problem.mutable_points() + cpt*3; - Vec3 & pt3D = *iter; - pt3D = Vec3(pt[0], pt[1], pt[2]); - } - // Get back camera - for (cpt = 0; cpt < nCameraMotion; ++cpt) - { - const double * cam = ba_problem.mutable_cameras_extrinsic() + cpt*6; - Mat3 R; - // angle axis to rotation matrix - ceres::AngleAxisToRotationMatrix(cam, R.data()); - Vec3 t(cam[3], cam[4], cam[5]); - - using namespace pinhole_brown_reprojectionError; - // Update the camera - PinholeCamera & sCam = vec_cam[cpt]; - const double * camIntrinsics = ba_problem.mutable_cameras_intrinsic(); - std::cout << " for camera Idx=[" << cpt << "]: " << std::endl - << "\t focal: " << camIntrinsics[OFFSET_FOCAL_LENGTH] << std::endl - << "\t ppx: " << camIntrinsics[OFFSET_PRINCIPAL_POINT_X] << std::endl - << "\t ppy: " << camIntrinsics[OFFSET_PRINCIPAL_POINT_Y] << std::endl - << "\t k1: " << camIntrinsics[OFFSET_K1] << std::endl - << "\t k2: " << camIntrinsics[OFFSET_K2] << std::endl - << "\t k3: " << camIntrinsics[OFFSET_K3] << std::endl - << "\t initial: focal: " << sCam._K(0,0) << ", ppx: " << sCam._K(0,2) - << ", ppy: " << sCam._K(1,2) < Date: Thu, 21 May 2015 10:28:10 +0200 Subject: [PATCH 16/52] Move some code from headers to source files. --- .../sfm/pipelines/sfm_regions_provider.hpp | 1 + .../structure_estimator.cpp | 322 ++++++++++++++++++ .../structure_estimator.hpp | 293 +--------------- src/openMVG/sfm/sfm_data_triangulation.cpp | 256 ++++++++++++++ src/openMVG/sfm/sfm_data_triangulation.hpp | 230 +------------ 5 files changed, 592 insertions(+), 510 deletions(-) create mode 100644 src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.cpp create mode 100644 src/openMVG/sfm/sfm_data_triangulation.cpp diff --git a/src/openMVG/sfm/pipelines/sfm_regions_provider.hpp b/src/openMVG/sfm/pipelines/sfm_regions_provider.hpp index 000c1e2888..84eca40812 100644 --- a/src/openMVG/sfm/pipelines/sfm_regions_provider.hpp +++ b/src/openMVG/sfm/pipelines/sfm_regions_provider.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include "third_party/progress/progress.hpp" #include diff --git a/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.cpp b/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.cpp new file mode 100644 index 0000000000..c2e376dec4 --- /dev/null +++ b/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.cpp @@ -0,0 +1,322 @@ +// Copyright (c) 2015 Pierre Moulon. + +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.hpp" + +#include "openMVG/matching/metric.hpp" +#include "openMVG/robust_estimation/guided_matching.hpp" +#include "openMVG/multiview/solver_fundamental_kernel.hpp" +#include "openMVG/multiview/triangulation_nview.hpp" +#include "openMVG/graph/graph.hpp" +#include "openMVG/tracks/tracks.hpp" +#include "openMVG/sfm/sfm_data_triangulation.hpp" + +#include "third_party/progress/progress.hpp" + +namespace openMVG { + +/// Camera pair epipole (Projection of camera center 2 in the image plane 1) +static Vec3 epipole_from_P(const Mat34& P1, const Pose3& P2) +{ + const Vec3 c = P2.center(); + Vec4 center; + center << c(0), c(1), c(2), 1.0; + return P1*center; +} + +/// Export point feature based vector to a matrix [(x,y)'T, (x,y)'T] +/// Use the camera intrinsics in order to get undistorted pixel coordinates +template +static void PointsToMat( + const IntrinsicBase * cam, + const PointFeatures & vec_feats, + MatT & m) +{ + m.resize(2, vec_feats.size()); + typedef typename MatT::Scalar Scalar; // Output matrix type + + size_t i = 0; + for( PointFeatures::const_iterator iter = vec_feats.begin(); + iter != vec_feats.end(); ++iter, ++i) + { + m.col(i) = cam->get_ud_pixel(Vec2(iter->x(), iter->y())); + } +} + +/// Use geometry of the views to compute a putative structure from features and descriptors. +void SfM_Data_Structure_Estimation_From_Known_Poses::run( + SfM_Data & sfm_data, + const Pair_Set & pairs, + const std::shared_ptr & regions_provider) +{ + sfm_data.structure.clear(); + + match(sfm_data, pairs, regions_provider); + filter(sfm_data, pairs, regions_provider); + triangulate(sfm_data, regions_provider); +} + +/// Use guided matching to find corresponding 2-view correspondences +void SfM_Data_Structure_Estimation_From_Known_Poses::match( + const SfM_Data & sfm_data, + const Pair_Set & pairs, + const std::shared_ptr & regions_provider) +{ + C_Progress_display my_progress_bar( pairs.size(), std::cout, + "Compute pairwise fundamental guided matching:\n" ); +#ifdef OPENMVG_USE_OPENMP + #pragma omp parallel +#endif // OPENMVG_USE_OPENMP + for (Pair_Set::const_iterator it = pairs.begin(); it != pairs.end(); ++it) + { +#ifdef OPENMVG_USE_OPENMP + #pragma omp single nowait +#endif // OPENMVG_USE_OPENMP + { + // -- + // Perform GUIDED MATCHING + // -- + // Use the computed model to check valid correspondences + // - by considering geometric error and descriptor distance ratio. + std::vector vec_corresponding_indexes; + + const View * viewL = sfm_data.GetViews().at(it->first).get(); + const Pose3 poseL = sfm_data.GetPoseOrDie(viewL); + const Intrinsics::const_iterator iterIntrinsicL = sfm_data.GetIntrinsics().find(viewL->id_intrinsic); + const View * viewR = sfm_data.GetViews().at(it->second).get(); + const Pose3 poseR = sfm_data.GetPoseOrDie(viewR); + const Intrinsics::const_iterator iterIntrinsicR = sfm_data.GetIntrinsics().find(viewR->id_intrinsic); + + Mat xL, xR; + PointsToMat(iterIntrinsicL->second.get(), regions_provider->regions_per_view.at(it->first)->GetRegionsPositions(), xL); + PointsToMat(iterIntrinsicR->second.get(), regions_provider->regions_per_view.at(it->second)->GetRegionsPositions(), xR); + + const Mat34 P_L = iterIntrinsicL->second.get()->get_projective_equivalent(poseL); + const Mat34 P_R = iterIntrinsicR->second.get()->get_projective_equivalent(poseR); + + const Mat3 F_lr = F_from_P(P_L, P_R); + const double thresholdF = 4.0; + +#if defined(EXHAUSTIVE_MATCHING) + // Guided matching considering geometric error and descriptor distance ratio + geometry_aware::GuidedMatching + >( + F_lr, xL, desc_provider.at(it->first), xR, desc_provider.at(it->second), + Square(thresholdF), Square(0.8), + vec_corresponding_indexes); +#else + const Vec3 epipole2 = epipole_from_P(P_R, poseL); + + const features::Regions * regions = regions_provider->regions_per_view.at(it->first).get(); + if (regions->IsScalar()) + { + // L2 Metric (Handle descriptor internal type) + if(regions->Type_id() == typeid(unsigned char).name()) + { + geometry_aware::GuidedMatching_Fundamental_Fast< + openMVG::fundamental::kernel::EpipolarDistanceError, + L2_Vectorized > + ( F_lr, + epipole2, + regions_provider->regions_per_view.at(it->first).get(), + iterIntrinsicR->second.get()->w(), iterIntrinsicR->second.get()->h(), + regions_provider->regions_per_view.at(it->second).get(), + Square(thresholdF), Square(0.8), + vec_corresponding_indexes); + } + else + if(regions->Type_id() == typeid(float).name()) + { + geometry_aware::GuidedMatching_Fundamental_Fast< + openMVG::fundamental::kernel::EpipolarDistanceError, + L2_Vectorized > + ( F_lr, + epipole2, + regions_provider->regions_per_view.at(it->first).get(), + iterIntrinsicR->second.get()->w(), iterIntrinsicR->second.get()->h(), + regions_provider->regions_per_view.at(it->second).get(), + Square(thresholdF), Square(0.8), + vec_corresponding_indexes); + } + else + if(regions->Type_id() == typeid(double).name()) + { + geometry_aware::GuidedMatching_Fundamental_Fast< + openMVG::fundamental::kernel::EpipolarDistanceError, + L2_Vectorized > + ( F_lr, + epipole2, + regions_provider->regions_per_view.at(it->first).get(), + iterIntrinsicR->second.get()->w(), iterIntrinsicR->second.get()->h(), + regions_provider->regions_per_view.at(it->second).get(), + Square(thresholdF), Square(0.8), + vec_corresponding_indexes); + } + } + else + if (regions->IsBinary() && regions->Type_id() == typeid(unsigned char).name()) + { + // Hamming metric + geometry_aware::GuidedMatching_Fundamental_Fast< + openMVG::fundamental::kernel::EpipolarDistanceError, + Hamming > + ( F_lr, + epipole2, + regions_provider->regions_per_view.at(it->first).get(), + iterIntrinsicR->second.get()->w(), iterIntrinsicR->second.get()->h(), + regions_provider->regions_per_view.at(it->second).get(), + Square(thresholdF), 0.8, + vec_corresponding_indexes); + } + +#endif + +#ifdef OPENMVG_USE_OPENMP + #pragma omp critical +#endif // OPENMVG_USE_OPENMP + { + ++my_progress_bar; + for (size_t i = 0; i < vec_corresponding_indexes.size(); ++i) + putatives_matches[*it].push_back(vec_corresponding_indexes[i]); + } + } + } +} + +/// Filter inconsistent correspondences by using 3-view correspondences on view triplets +void SfM_Data_Structure_Estimation_From_Known_Poses::filter( + const SfM_Data & sfm_data, + const Pair_Set & pairs, + const std::shared_ptr & regions_provider) +{ + // Compute triplets + // Triangulate triplet tracks + // - keep valid one + + typedef std::vector< graph::Triplet > Triplets; + const Triplets triplets = graph::tripletListing(pairs); + + C_Progress_display my_progress_bar( triplets.size(), std::cout, + "Per triplet tracks validation (discard spurious correspondences):\n" ); +#ifdef OPENMVG_USE_OPENMP + #pragma omp parallel +#endif // OPENMVG_USE_OPENMP + for( Triplets::const_iterator it = triplets.begin(); it != triplets.end(); ++it) + { +#ifdef OPENMVG_USE_OPENMP + #pragma omp single nowait +#endif // OPENMVG_USE_OPENMP + { + #ifdef OPENMVG_USE_OPENMP + #pragma omp critical + #endif // OPENMVG_USE_OPENMP + {++my_progress_bar;} + + const graph::Triplet & triplet = *it; + const IndexT I = triplet.i, J = triplet.j , K = triplet.k; + + openMVG::tracks::STLMAPTracks map_tracksCommon; + openMVG::tracks::TracksBuilder tracksBuilder; + { + PairWiseMatches map_matchesIJK; + if(putatives_matches.find(std::make_pair(I,J)) != putatives_matches.end()) + map_matchesIJK.insert(*putatives_matches.find(std::make_pair(I,J))); + + if(putatives_matches.find(std::make_pair(I,K)) != putatives_matches.end()) + map_matchesIJK.insert(*putatives_matches.find(std::make_pair(I,K))); + + if(putatives_matches.find(std::make_pair(J,K)) != putatives_matches.end()) + map_matchesIJK.insert(*putatives_matches.find(std::make_pair(J,K))); + + if (map_matchesIJK.size() >= 2) { + tracksBuilder.Build(map_matchesIJK); + tracksBuilder.Filter(3); + tracksBuilder.ExportToSTL(map_tracksCommon); + } + + // Triangulate the tracks + for (tracks::STLMAPTracks::const_iterator iterTracks = map_tracksCommon.begin(); + iterTracks != map_tracksCommon.end(); ++iterTracks) { + { + const tracks::submapTrack & subTrack = iterTracks->second; + Triangulation trianObj; + for (tracks::submapTrack::const_iterator iter = subTrack.begin(); iter != subTrack.end(); ++iter) { + const size_t imaIndex = iter->first; + const size_t featIndex = iter->second; + const View * view = sfm_data.GetViews().at(imaIndex).get(); + const IntrinsicBase * cam = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); + const Pose3 pose = sfm_data.GetPoseOrDie(view); + const Vec2 pt = regions_provider->regions_per_view.at(imaIndex)->GetRegionPosition(featIndex); + trianObj.add(cam->get_projective_equivalent(pose), cam->get_ud_pixel(pt)); + } + const Vec3 Xs = trianObj.compute(); + if (trianObj.minDepth() > 0 && trianObj.error() < 4.0) + // TODO: Add an angular check ? + { + #ifdef OPENMVG_USE_OPENMP + #pragma omp critical + #endif // OPENMVG_USE_OPENMP + { + openMVG::tracks::submapTrack::const_iterator iterI, iterJ, iterK; + iterI = iterJ = iterK = subTrack.begin(); + std::advance(iterJ,1); + std::advance(iterK,2); + + triplets_matches[std::make_pair(I,J)].push_back(IndMatch(iterI->second, iterJ->second)); + triplets_matches[std::make_pair(J,K)].push_back(IndMatch(iterJ->second, iterK->second)); + triplets_matches[std::make_pair(I,K)].push_back(IndMatch(iterI->second, iterK->second)); + } + } + } + } + } + } + } + // Clear putatives matches since they are no longer required + matching::PairWiseMatches().swap(putatives_matches); +} + +/// Init & triangulate landmark observations from validated 3-view correspondences +void SfM_Data_Structure_Estimation_From_Known_Poses::triangulate( + SfM_Data & sfm_data, + const std::shared_ptr & regions_provider) +{ + openMVG::tracks::STLMAPTracks map_tracksCommon; + openMVG::tracks::TracksBuilder tracksBuilder; + tracksBuilder.Build(triplets_matches); + tracksBuilder.Filter(3); + tracksBuilder.ExportToSTL(map_tracksCommon); + matching::PairWiseMatches().swap(triplets_matches); + + // Generate new Structure tracks + sfm_data.structure.clear(); + + // Fill sfm_data with the computed tracks (no 3D yet) + Landmarks & structure = sfm_data.structure; + IndexT idx(0); + for (tracks::STLMAPTracks::const_iterator itTracks = map_tracksCommon.begin(); + itTracks != map_tracksCommon.end(); + ++itTracks, ++idx) + { + const tracks::submapTrack & track = itTracks->second; + structure[idx] = Landmark(); + Observations & obs = structure.at(idx).obs; + for (tracks::submapTrack::const_iterator it = track.begin(); it != track.end(); ++it) + { + const size_t imaIndex = it->first; + const size_t featIndex = it->second; + const Vec2 pt = regions_provider->regions_per_view.at(imaIndex)->GetRegionPosition(featIndex); + obs[imaIndex] = Observation(pt, featIndex); + } + } + + // Triangulate them using a robust triangulation scheme + SfM_Data_Structure_Computation_Robust structure_estimator(true); + structure_estimator.triangulate(sfm_data); +} + +} // namespace openMVG diff --git a/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.hpp b/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.hpp index 4836c08bc1..b8a723a943 100644 --- a/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.hpp +++ b/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.hpp @@ -6,46 +6,11 @@ #pragma once -#include "openMVG/matching/metric.hpp" #include "openMVG/sfm/pipelines/sfm_regions_provider.hpp" -#include "openMVG/robust_estimation/guided_matching.hpp" -#include "openMVG/multiview/solver_fundamental_kernel.hpp" #include "openMVG/matching/indMatch.hpp" -#include "openMVG/graph/graph.hpp" -#include "openMVG/tracks/tracks.hpp" - -#include "third_party/progress/progress.hpp" namespace openMVG { -/// Camera pair epipole (Projection of camera center 2 in the image plane 1) -static Vec3 epipole_from_P(const Mat34& P1, const Pose3& P2) -{ - const Vec3 c = P2.center(); - Vec4 center; - center << c(0), c(1), c(2), 1.0; - return P1*center; -} - -/// Export point feature based vector to a matrix [(x,y)'T, (x,y)'T] -/// Use the camera intrinsics in order to get undistorted pixel coordinates -template -static void PointsToMat( - const IntrinsicBase * cam, - const PointFeatures & vec_feats, - MatT & m) -{ - m.resize(2, vec_feats.size()); - typedef typename MatT::Scalar Scalar; // Output matrix type - - size_t i = 0; - for( PointFeatures::const_iterator iter = vec_feats.begin(); - iter != vec_feats.end(); ++iter, ++i) - { - m.col(i) = cam->get_ud_pixel(Vec2(iter->x(), iter->y())); - } -} - class SfM_Data_Structure_Estimation_From_Known_Poses { public: @@ -54,14 +19,7 @@ class SfM_Data_Structure_Estimation_From_Known_Poses void run( SfM_Data & sfm_data, const Pair_Set & pairs, - const std::shared_ptr & regions_provider) - { - sfm_data.structure.clear(); - - match(sfm_data, pairs, regions_provider); - filter(sfm_data, pairs, regions_provider); - triangulate(sfm_data, regions_provider); - } + const std::shared_ptr & regions_provider); private: @@ -69,261 +27,18 @@ class SfM_Data_Structure_Estimation_From_Known_Poses void match( const SfM_Data & sfm_data, const Pair_Set & pairs, - const std::shared_ptr & regions_provider) - { - C_Progress_display my_progress_bar( pairs.size(), std::cout, - "Compute pairwise fundamental guided matching:\n" ); - #ifdef OPENMVG_USE_OPENMP - #pragma omp parallel - #endif // OPENMVG_USE_OPENMP - for (Pair_Set::const_iterator it = pairs.begin(); it != pairs.end(); ++it) - { - #ifdef OPENMVG_USE_OPENMP - #pragma omp single nowait - #endif // OPENMVG_USE_OPENMP - { - // -- - // Perform GUIDED MATCHING - // -- - // Use the computed model to check valid correspondences - // - by considering geometric error and descriptor distance ratio. - std::vector vec_corresponding_indexes; - - const View * viewL = sfm_data.GetViews().at(it->first).get(); - const Pose3 poseL = sfm_data.GetPoseOrDie(viewL); - const Intrinsics::const_iterator iterIntrinsicL = sfm_data.GetIntrinsics().find(viewL->id_intrinsic); - const View * viewR = sfm_data.GetViews().at(it->second).get(); - const Pose3 poseR = sfm_data.GetPoseOrDie(viewR); - const Intrinsics::const_iterator iterIntrinsicR = sfm_data.GetIntrinsics().find(viewR->id_intrinsic); - - Mat xL, xR; - PointsToMat(iterIntrinsicL->second.get(), regions_provider->regions_per_view.at(it->first)->GetRegionsPositions(), xL); - PointsToMat(iterIntrinsicR->second.get(), regions_provider->regions_per_view.at(it->second)->GetRegionsPositions(), xR); - - const Mat34 P_L = iterIntrinsicL->second.get()->get_projective_equivalent(poseL); - const Mat34 P_R = iterIntrinsicR->second.get()->get_projective_equivalent(poseR); - - const Mat3 F_lr = F_from_P(P_L, P_R); - const double thresholdF = 4.0; - -#if defined(EXHAUSTIVE_MATCHING) - // Guided matching considering geometric error and descriptor distance ratio - geometry_aware::GuidedMatching - >( - F_lr, xL, desc_provider.at(it->first), xR, desc_provider.at(it->second), - Square(thresholdF), Square(0.8), - vec_corresponding_indexes); -#else - const Vec3 epipole2 = epipole_from_P(P_R, poseL); - - const features::Regions * regions = regions_provider->regions_per_view.at(it->first).get(); - if (regions->IsScalar()) - { - // L2 Metric (Handle descriptor internal type) - if(regions->Type_id() == typeid(unsigned char).name()) - { - geometry_aware::GuidedMatching_Fundamental_Fast< - openMVG::fundamental::kernel::EpipolarDistanceError, - L2_Vectorized > - ( F_lr, - epipole2, - regions_provider->regions_per_view.at(it->first).get(), - iterIntrinsicR->second.get()->w(), iterIntrinsicR->second.get()->h(), - regions_provider->regions_per_view.at(it->second).get(), - Square(thresholdF), Square(0.8), - vec_corresponding_indexes); - } - else - if(regions->Type_id() == typeid(float).name()) - { - geometry_aware::GuidedMatching_Fundamental_Fast< - openMVG::fundamental::kernel::EpipolarDistanceError, - L2_Vectorized > - ( F_lr, - epipole2, - regions_provider->regions_per_view.at(it->first).get(), - iterIntrinsicR->second.get()->w(), iterIntrinsicR->second.get()->h(), - regions_provider->regions_per_view.at(it->second).get(), - Square(thresholdF), Square(0.8), - vec_corresponding_indexes); - } - else - if(regions->Type_id() == typeid(double).name()) - { - geometry_aware::GuidedMatching_Fundamental_Fast< - openMVG::fundamental::kernel::EpipolarDistanceError, - L2_Vectorized > - ( F_lr, - epipole2, - regions_provider->regions_per_view.at(it->first).get(), - iterIntrinsicR->second.get()->w(), iterIntrinsicR->second.get()->h(), - regions_provider->regions_per_view.at(it->second).get(), - Square(thresholdF), Square(0.8), - vec_corresponding_indexes); - } - } - else - if (regions->IsBinary() && regions->Type_id() == typeid(unsigned char).name()) - { - // Hamming metric - geometry_aware::GuidedMatching_Fundamental_Fast< - openMVG::fundamental::kernel::EpipolarDistanceError, - Hamming > - ( F_lr, - epipole2, - regions_provider->regions_per_view.at(it->first).get(), - iterIntrinsicR->second.get()->w(), iterIntrinsicR->second.get()->h(), - regions_provider->regions_per_view.at(it->second).get(), - Square(thresholdF), 0.8, - vec_corresponding_indexes); - } - -#endif - - #ifdef OPENMVG_USE_OPENMP - #pragma omp critical - #endif // OPENMVG_USE_OPENMP - { - ++my_progress_bar; - for (size_t i = 0; i < vec_corresponding_indexes.size(); ++i) - putatives_matches[*it].push_back(vec_corresponding_indexes[i]); - } - } - } - } + const std::shared_ptr & regions_provider); /// Filter inconsistent correspondences by using 3-view correspondences on view triplets void filter( const SfM_Data & sfm_data, const Pair_Set & pairs, - const std::shared_ptr & regions_provider) - { - // Compute triplets - // Triangulate triplet tracks - // - keep valid one - - typedef std::vector< graph::Triplet > Triplets; - const Triplets triplets = graph::tripletListing(pairs); - - C_Progress_display my_progress_bar( triplets.size(), std::cout, - "Per triplet tracks validation (discard spurious correspondences):\n" ); - #ifdef OPENMVG_USE_OPENMP - #pragma omp parallel - #endif // OPENMVG_USE_OPENMP - for( Triplets::const_iterator it = triplets.begin(); it != triplets.end(); ++it) - { - #ifdef OPENMVG_USE_OPENMP - #pragma omp single nowait - #endif // OPENMVG_USE_OPENMP - { - #ifdef OPENMVG_USE_OPENMP - #pragma omp critical - #endif // OPENMVG_USE_OPENMP - {++my_progress_bar;} - - const graph::Triplet & triplet = *it; - const IndexT I = triplet.i, J = triplet.j , K = triplet.k; - - openMVG::tracks::STLMAPTracks map_tracksCommon; - openMVG::tracks::TracksBuilder tracksBuilder; - { - PairWiseMatches map_matchesIJK; - if(putatives_matches.find(std::make_pair(I,J)) != putatives_matches.end()) - map_matchesIJK.insert(*putatives_matches.find(std::make_pair(I,J))); - - if(putatives_matches.find(std::make_pair(I,K)) != putatives_matches.end()) - map_matchesIJK.insert(*putatives_matches.find(std::make_pair(I,K))); - - if(putatives_matches.find(std::make_pair(J,K)) != putatives_matches.end()) - map_matchesIJK.insert(*putatives_matches.find(std::make_pair(J,K))); - - if (map_matchesIJK.size() >= 2) { - tracksBuilder.Build(map_matchesIJK); - tracksBuilder.Filter(3); - tracksBuilder.ExportToSTL(map_tracksCommon); - } - - // Triangulate the tracks - for (tracks::STLMAPTracks::const_iterator iterTracks = map_tracksCommon.begin(); - iterTracks != map_tracksCommon.end(); ++iterTracks) { - { - const tracks::submapTrack & subTrack = iterTracks->second; - Triangulation trianObj; - for (tracks::submapTrack::const_iterator iter = subTrack.begin(); iter != subTrack.end(); ++iter) { - const size_t imaIndex = iter->first; - const size_t featIndex = iter->second; - const View * view = sfm_data.GetViews().at(imaIndex).get(); - const IntrinsicBase * cam = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); - const Pose3 pose = sfm_data.GetPoseOrDie(view); - const Vec2 pt = regions_provider->regions_per_view.at(imaIndex)->GetRegionPosition(featIndex); - trianObj.add(cam->get_projective_equivalent(pose), cam->get_ud_pixel(pt)); - } - const Vec3 Xs = trianObj.compute(); - if (trianObj.minDepth() > 0 && trianObj.error() < 4.0) - // TODO: Add an angular check ? - { - #ifdef OPENMVG_USE_OPENMP - #pragma omp critical - #endif // OPENMVG_USE_OPENMP - { - openMVG::tracks::submapTrack::const_iterator iterI, iterJ, iterK; - iterI = iterJ = iterK = subTrack.begin(); - std::advance(iterJ,1); - std::advance(iterK,2); - - triplets_matches[std::make_pair(I,J)].push_back(IndMatch(iterI->second, iterJ->second)); - triplets_matches[std::make_pair(J,K)].push_back(IndMatch(iterJ->second, iterK->second)); - triplets_matches[std::make_pair(I,K)].push_back(IndMatch(iterI->second, iterK->second)); - } - } - } - } - } - } - } - // Clear putatives matches since they are no longer required - matching::PairWiseMatches().swap(putatives_matches); - } + const std::shared_ptr & regions_provider); /// Init & triangulate landmark observations from validated 3-view correspondences void triangulate( SfM_Data & sfm_data, - const std::shared_ptr & regions_provider) - { - openMVG::tracks::STLMAPTracks map_tracksCommon; - openMVG::tracks::TracksBuilder tracksBuilder; - tracksBuilder.Build(triplets_matches); - tracksBuilder.Filter(3); - tracksBuilder.ExportToSTL(map_tracksCommon); - matching::PairWiseMatches().swap(triplets_matches); - - // Generate new Structure tracks - sfm_data.structure.clear(); - - // Fill sfm_data with the computed tracks (no 3D yet) - Landmarks & structure = sfm_data.structure; - IndexT idx(0); - for (tracks::STLMAPTracks::const_iterator itTracks = map_tracksCommon.begin(); - itTracks != map_tracksCommon.end(); - ++itTracks, ++idx) - { - const tracks::submapTrack & track = itTracks->second; - structure[idx] = Landmark(); - Observations & obs = structure.at(idx).obs; - for (tracks::submapTrack::const_iterator it = track.begin(); it != track.end(); ++it) - { - const size_t imaIndex = it->first; - const size_t featIndex = it->second; - const Vec2 pt = regions_provider->regions_per_view.at(imaIndex)->GetRegionPosition(featIndex); - obs[imaIndex] = Observation(pt, featIndex); - } - } - - // Triangulate them using a robust triangulation scheme - SfM_Data_Structure_Computation_Robust structure_estimator(true); - structure_estimator.triangulate(sfm_data); - } + const std::shared_ptr & regions_provider); private: //-- diff --git a/src/openMVG/sfm/sfm_data_triangulation.cpp b/src/openMVG/sfm/sfm_data_triangulation.cpp new file mode 100644 index 0000000000..0366c834eb --- /dev/null +++ b/src/openMVG/sfm/sfm_data_triangulation.cpp @@ -0,0 +1,256 @@ +// Copyright (c) 2015 Pierre Moulon. + +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "openMVG/sfm/sfm_data_triangulation.hpp" + +#include "openMVG/multiview/triangulation_nview.hpp" +#include "openMVG/robust_estimation/rand_sampling.hpp" +#include "third_party/progress/progress.hpp" + +#include +#include + +namespace openMVG { + +SfM_Data_Structure_Computation_Basis::SfM_Data_Structure_Computation_Basis(bool bConsoleVerbose) + :_bConsoleVerbose(bConsoleVerbose) +{ +} + +SfM_Data_Structure_Computation_Blind::SfM_Data_Structure_Computation_Blind(bool bConsoleVerbose) + :SfM_Data_Structure_Computation_Basis(bConsoleVerbose) +{ +} + +void SfM_Data_Structure_Computation_Blind::triangulate(SfM_Data & sfm_data) const +{ + std::deque rejectedId; + std::unique_ptr my_progress_bar; + if (_bConsoleVerbose) + my_progress_bar.reset( new C_Progress_display( + sfm_data.structure.size(), + std::cout, + "Blind triangulation progress:\n" )); +#ifdef OPENMVG_USE_OPENMP + #pragma omp parallel +#endif + for(Landmarks::iterator iterTracks = sfm_data.structure.begin(); + iterTracks != sfm_data.structure.end(); + ++iterTracks) + { +#ifdef OPENMVG_USE_OPENMP + #pragma omp single nowait +#endif + { + if (_bConsoleVerbose) + { +#ifdef OPENMVG_USE_OPENMP + #pragma omp critical +#endif + ++(*my_progress_bar); + } + // Triangulate each landmark + Triangulation trianObj; + const Observations & obs = iterTracks->second.obs; + for(Observations::const_iterator itObs = obs.begin(); + itObs != obs.end(); ++itObs) + { + const View * view = sfm_data.views.at(itObs->first).get(); + const IntrinsicBase * cam = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); + const Pose3 pose = sfm_data.GetPoseOrDie(view); + trianObj.add( + cam->get_projective_equivalent(pose), + cam->get_ud_pixel(itObs->second.x)); + } + // Compute the 3D point + const Vec3 X = trianObj.compute(); + if (trianObj.minDepth() > 0) // Keep the point only if it have a positive depth + { + iterTracks->second.X = X; + } + else + { +#ifdef OPENMVG_USE_OPENMP + #pragma omp critical +#endif + { + rejectedId.push_front(iterTracks->first); + } + } + } + } + // Erase the unsuccessful triangulated tracks + for (auto& it : rejectedId) + { + sfm_data.structure.erase(it); + } +} + +SfM_Data_Structure_Computation_Robust::SfM_Data_Structure_Computation_Robust(bool bConsoleVerbose) + :SfM_Data_Structure_Computation_Basis(bConsoleVerbose) +{ +} + +void SfM_Data_Structure_Computation_Robust::triangulate(SfM_Data & sfm_data) const +{ + robust_triangulation(sfm_data); +} + +/// Robust triangulation of track data contained in the structure +/// All observations must have View with valid Intrinsic and Pose data +/// Invalid landmark are removed. +void SfM_Data_Structure_Computation_Robust::robust_triangulation(SfM_Data & sfm_data) const +{ + std::deque rejectedId; + std::unique_ptr my_progress_bar; + if (_bConsoleVerbose) + my_progress_bar.reset( new C_Progress_display( + sfm_data.structure.size(), + std::cout, + "Robust triangulation progress:\n" )); +#ifdef OPENMVG_USE_OPENMP + #pragma omp parallel +#endif + for(Landmarks::iterator iterTracks = sfm_data.structure.begin(); + iterTracks != sfm_data.structure.end(); + ++iterTracks) + { +#ifdef OPENMVG_USE_OPENMP + #pragma omp single nowait +#endif + { + if (_bConsoleVerbose) + { +#ifdef OPENMVG_USE_OPENMP + #pragma omp critical +#endif + ++(*my_progress_bar); + } + Vec3 X; + if (robust_triangulation(sfm_data, iterTracks->second.obs, X)) { + iterTracks->second.X = X; + } + else { + iterTracks->second.X = Vec3::Zero(); +#ifdef OPENMVG_USE_OPENMP + #pragma omp critical +#endif + { + rejectedId.push_front(iterTracks->first); + } + } + } + } + // Erase the unsuccessful triangulated tracks + for (auto& it : rejectedId) + { + sfm_data.structure.erase(it); + } +} + +/// Robustly try to estimate the best 3D point using a ransac Scheme +/// Return true for a successful triangulation +bool SfM_Data_Structure_Computation_Robust::robust_triangulation( + const SfM_Data & sfm_data, + const Observations & obs, + Vec3 & X, + const IndexT min_required_inliers, + const IndexT min_sample_index) const +{ + const double dThresholdPixel = 4.0; // TODO: make this parameter customizable + + const IndexT nbIter = obs.size(); // TODO: automatic computation of the number of iterations? + + // - Ransac variables + Vec3 best_model; + std::set best_inlier_set; + double best_error = std::numeric_limits::max(); + + // - Ransac loop + for (IndexT i = 0; i < nbIter; ++i) + { + std::vector vec_samples; + robust::UniformSample(min_sample_index, obs.size(), &vec_samples); + const std::set samples(vec_samples.begin(), vec_samples.end()); + + // Hypothesis generation. + const Vec3 current_model = track_sample_triangulation(sfm_data, obs, samples); + + // Test validity of the hypothesis + // - chierality (for the samples) + // - residual error + + // Chierality (Check the point is in front of the sampled cameras) + bool bChierality = true; + for (auto& it : samples){ + Observations::const_iterator itObs = obs.begin(); + std::advance(itObs, it); + const View * view = sfm_data.views.at(itObs->first).get(); + const IntrinsicBase * cam = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); + const Pose3 pose = sfm_data.GetPoseOrDie(view); + const double z = pose.depth(current_model); // TODO: cam->depth(pose(X)); + bChierality &= z > 0; + } + + if (!bChierality) + continue; + + std::set inlier_set; + double current_error = 0.0; + // Classification as inlier/outlier according pixel residual errors. + for (Observations::const_iterator itObs = obs.begin(); + itObs != obs.end(); ++itObs) + { + const View * view = sfm_data.views.at(itObs->first).get(); + const IntrinsicBase * intrinsic = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); + const Pose3 pose = sfm_data.GetPoseOrDie(view); + const Vec2 residual = intrinsic->residual(pose, current_model, itObs->second.x); + const double residual_d = residual.norm(); + if (residual_d < dThresholdPixel) + { + inlier_set.insert(itObs->first); + current_error += residual_d; + } + else + { + current_error += dThresholdPixel; + } + } + // Does the hypothesis is the best one we have seen and have sufficient inliers. + if (current_error < best_error && inlier_set.size() >= min_required_inliers) + { + X = best_model = current_model; + best_inlier_set = inlier_set; + best_error = current_error; + } + } + return !best_inlier_set.empty(); +} + + +/// Triangulate a given track from a selection of observations +Vec3 SfM_Data_Structure_Computation_Robust::track_sample_triangulation( + const SfM_Data & sfm_data, + const Observations & obs, + const std::set & samples) const +{ + Triangulation trianObj; + for (auto& it : samples) + { + const IndexT & idx = it; + Observations::const_iterator itObs = obs.begin(); + std::advance(itObs, idx); + const View * view = sfm_data.views.at(itObs->first).get(); + const IntrinsicBase * cam = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); + const Pose3 pose = sfm_data.GetPoseOrDie(view); + trianObj.add( + cam->get_projective_equivalent(pose), + cam->get_ud_pixel(itObs->second.x)); + } + return trianObj.compute(); +} + +} // namespace openMVG diff --git a/src/openMVG/sfm/sfm_data_triangulation.hpp b/src/openMVG/sfm/sfm_data_triangulation.hpp index d1eb7ac7a3..2f9417cf89 100644 --- a/src/openMVG/sfm/sfm_data_triangulation.hpp +++ b/src/openMVG/sfm/sfm_data_triangulation.hpp @@ -7,12 +7,7 @@ #ifndef OPENMVG_SFM_DATA_TRIANGULATION_HPP #define OPENMVG_SFM_DATA_TRIANGULATION_HPP -#include "openMVG/multiview/triangulation_nview.hpp" -#include "openMVG/robust_estimation/rand_sampling.hpp" -#include "third_party/progress/progress.hpp" - -#include -#include +#include "openMVG/sfm/sfm_data.hpp" namespace openMVG { @@ -22,10 +17,7 @@ struct SfM_Data_Structure_Computation_Basis { bool _bConsoleVerbose; - SfM_Data_Structure_Computation_Basis(bool bConsoleVerbose = false) - :_bConsoleVerbose(bConsoleVerbose) - { - } + SfM_Data_Structure_Computation_Basis(bool bConsoleVerbose = false); virtual void triangulate(SfM_Data & sfm_data) const = 0; }; @@ -37,74 +29,9 @@ struct SfM_Data_Structure_Computation_Basis // - Inlier/Outlier classification is done by a cheirality test struct SfM_Data_Structure_Computation_Blind: public SfM_Data_Structure_Computation_Basis { - SfM_Data_Structure_Computation_Blind(bool bConsoleVerbose = false) - :SfM_Data_Structure_Computation_Basis(bConsoleVerbose) - { - } + SfM_Data_Structure_Computation_Blind(bool bConsoleVerbose = false); - virtual void triangulate(SfM_Data & sfm_data) const - { - std::deque rejectedId; - std::unique_ptr my_progress_bar; - if (_bConsoleVerbose) - my_progress_bar.reset( new C_Progress_display( - sfm_data.structure.size(), - std::cout, - "Blind triangulation progress:\n" )); -#ifdef OPENMVG_USE_OPENMP - #pragma omp parallel -#endif - for(Landmarks::iterator iterTracks = sfm_data.structure.begin(); - iterTracks != sfm_data.structure.end(); - ++iterTracks) - { -#ifdef OPENMVG_USE_OPENMP - #pragma omp single nowait -#endif - { - if (_bConsoleVerbose) - { -#ifdef OPENMVG_USE_OPENMP - #pragma omp critical -#endif - ++(*my_progress_bar); - } - // Triangulate each landmark - Triangulation trianObj; - const Observations & obs = iterTracks->second.obs; - for(Observations::const_iterator itObs = obs.begin(); - itObs != obs.end(); ++itObs) - { - const View * view = sfm_data.views.at(itObs->first).get(); - const IntrinsicBase * cam = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); - const Pose3 pose = sfm_data.GetPoseOrDie(view); - trianObj.add( - cam->get_projective_equivalent(pose), - cam->get_ud_pixel(itObs->second.x)); - } - // Compute the 3D point - const Vec3 X = trianObj.compute(); - if (trianObj.minDepth() > 0) // Keep the point only if it have a positive depth - { - iterTracks->second.X = X; - } - else - { -#ifdef OPENMVG_USE_OPENMP - #pragma omp critical -#endif - { - rejectedId.push_front(iterTracks->first); - } - } - } - } - // Erase the unsuccessful triangulated tracks - for (auto& it : rejectedId) - { - sfm_data.structure.erase(it); - } - } + virtual void triangulate(SfM_Data & sfm_data) const; }; /// Triangulation of track data contained in the structure of a SfM_Data scene. @@ -113,67 +40,14 @@ struct SfM_Data_Structure_Computation_Blind: public SfM_Data_Structure_Computati // - Check cheirality and a pixel residual error (TODO: make it a parameter) struct SfM_Data_Structure_Computation_Robust: public SfM_Data_Structure_Computation_Basis { - SfM_Data_Structure_Computation_Robust(bool bConsoleVerbose = false) - :SfM_Data_Structure_Computation_Basis(bConsoleVerbose) - { - } + SfM_Data_Structure_Computation_Robust(bool bConsoleVerbose = false); - virtual void triangulate(SfM_Data & sfm_data) const - { - robust_triangulation(sfm_data); - } + virtual void triangulate(SfM_Data & sfm_data) const; /// Robust triangulation of track data contained in the structure /// All observations must have View with valid Intrinsic and Pose data /// Invalid landmark are removed. - void robust_triangulation(SfM_Data & sfm_data) const - { - std::deque rejectedId; - std::unique_ptr my_progress_bar; - if (_bConsoleVerbose) - my_progress_bar.reset( new C_Progress_display( - sfm_data.structure.size(), - std::cout, - "Robust triangulation progress:\n" )); -#ifdef OPENMVG_USE_OPENMP - #pragma omp parallel -#endif - for(Landmarks::iterator iterTracks = sfm_data.structure.begin(); - iterTracks != sfm_data.structure.end(); - ++iterTracks) - { -#ifdef OPENMVG_USE_OPENMP - #pragma omp single nowait -#endif - { - if (_bConsoleVerbose) - { -#ifdef OPENMVG_USE_OPENMP - #pragma omp critical -#endif - ++(*my_progress_bar); - } - Vec3 X; - if (robust_triangulation(sfm_data, iterTracks->second.obs, X)) { - iterTracks->second.X = X; - } - else { - iterTracks->second.X = Vec3::Zero(); -#ifdef OPENMVG_USE_OPENMP - #pragma omp critical -#endif - { - rejectedId.push_front(iterTracks->first); - } - } - } - } - // Erase the unsuccessful triangulated tracks - for (auto& it : rejectedId) - { - sfm_data.structure.erase(it); - } - } + void robust_triangulation(SfM_Data & sfm_data) const; /// Robustly try to estimate the best 3D point using a ransac Scheme /// Return true for a successful triangulation @@ -182,100 +56,14 @@ struct SfM_Data_Structure_Computation_Robust: public SfM_Data_Structure_Computat const Observations & obs, Vec3 & X, const IndexT min_required_inliers = 3, - const IndexT min_sample_index = 3) const - { - const double dThresholdPixel = 4.0; // TODO: make this parameter customizable - - const IndexT nbIter = obs.size(); // TODO: automatic computation of the number of iterations? - - // - Ransac variables - Vec3 best_model; - std::set best_inlier_set; - double best_error = std::numeric_limits::max(); - - // - Ransac loop - for (IndexT i = 0; i < nbIter; ++i) - { - std::vector vec_samples; - robust::UniformSample(min_sample_index, obs.size(), &vec_samples); - const std::set samples(vec_samples.begin(), vec_samples.end()); - - // Hypothesis generation. - const Vec3 current_model = track_sample_triangulation(sfm_data, obs, samples); - - // Test validity of the hypothesis - // - chierality (for the samples) - // - residual error - - // Chierality (Check the point is in front of the sampled cameras) - bool bChierality = true; - for (auto& it : samples){ - Observations::const_iterator itObs = obs.begin(); - std::advance(itObs, it); - const View * view = sfm_data.views.at(itObs->first).get(); - const IntrinsicBase * cam = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); - const Pose3 pose = sfm_data.GetPoseOrDie(view); - const double z = pose.depth(current_model); // TODO: cam->depth(pose(X)); - bChierality &= z > 0; - } - - if (!bChierality) - continue; - - std::set inlier_set; - double current_error = 0.0; - // Classification as inlier/outlier according pixel residual errors. - for (Observations::const_iterator itObs = obs.begin(); - itObs != obs.end(); ++itObs) - { - const View * view = sfm_data.views.at(itObs->first).get(); - const IntrinsicBase * intrinsic = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); - const Pose3 pose = sfm_data.GetPoseOrDie(view); - const Vec2 residual = intrinsic->residual(pose, current_model, itObs->second.x); - const double residual_d = residual.norm(); - if (residual_d < dThresholdPixel) - { - inlier_set.insert(itObs->first); - current_error += residual_d; - } - else - { - current_error += dThresholdPixel; - } - } - // Does the hypothesis is the best one we have seen and have sufficient inliers. - if (current_error < best_error && inlier_set.size() >= min_required_inliers) - { - X = best_model = current_model; - best_inlier_set = inlier_set; - best_error = current_error; - } - } - return !best_inlier_set.empty(); - } + const IndexT min_sample_index = 3) const; private: /// Triangulate a given track from a selection of observations Vec3 track_sample_triangulation( const SfM_Data & sfm_data, const Observations & obs, - const std::set & samples) const - { - Triangulation trianObj; - for (auto& it : samples) - { - const IndexT & idx = it; - Observations::const_iterator itObs = obs.begin(); - std::advance(itObs, idx); - const View * view = sfm_data.views.at(itObs->first).get(); - const IntrinsicBase * cam = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); - const Pose3 pose = sfm_data.GetPoseOrDie(view); - trianObj.add( - cam->get_projective_equivalent(pose), - cam->get_ud_pixel(itObs->second.x)); - } - return trianObj.compute(); - } + const std::set & samples) const; }; } // namespace openMVG From 7c9b6bd3feccacb8d106cafd3f2b23a7cd85a7ba Mon Sep 17 00:00:00 2001 From: pmoulon Date: Thu, 21 May 2015 14:15:17 +0200 Subject: [PATCH 17/52] Fix gcc build. --- src/openMVG/graph/graph_graphviz_export.hpp | 2 +- .../robust_essential/essential_estimation.hpp | 127 ------------------ .../robust_essential_ba.cpp | 3 +- .../SfM/main_ComputeFeatures_OpenCV.cpp | 2 +- 4 files changed, 3 insertions(+), 131 deletions(-) delete mode 100644 src/openMVG_Samples/robust_essential/essential_estimation.hpp diff --git a/src/openMVG/graph/graph_graphviz_export.hpp b/src/openMVG/graph/graph_graphviz_export.hpp index d0f6c44792..4dc560c9b5 100644 --- a/src/openMVG/graph/graph_graphviz_export.hpp +++ b/src/openMVG/graph/graph_graphviz_export.hpp @@ -105,7 +105,7 @@ bool exportToGraphvizFormat_Image( } os << "edge [style=bold]" << std::endl; - for ( map< std::pair, IndexT>::const_iterator iter = map_arcs.begin(); + for ( std::map< std::pair, IndexT>::const_iterator iter = map_arcs.begin(); iter != map_arcs.end(); ++iter) { diff --git a/src/openMVG_Samples/robust_essential/essential_estimation.hpp b/src/openMVG_Samples/robust_essential/essential_estimation.hpp deleted file mode 100644 index b4bd6aec7f..0000000000 --- a/src/openMVG_Samples/robust_essential/essential_estimation.hpp +++ /dev/null @@ -1,127 +0,0 @@ - -#ifndef OPENMVG_SAMPLES_ROBUST_ESSENTIAL_HPP -#define OPENMVG_SAMPLES_ROBUST_ESSENTIAL_HPP - -#include "openMVG/multiview/solver_essential_kernel.hpp" -#include "openMVG/robust_estimation/robust_estimator_ACRansac.hpp" -#include "openMVG/robust_estimation/robust_estimator_ACRansacKernelAdaptator.hpp" - -using namespace openMVG::robust; - -namespace openMVG -{ - -/// Estimate the essential matrix from point matches and K matrices. -bool robustEssential( - const Mat3 & K1, const Mat3 & K2, - const Mat & x1, const Mat & x2, - Mat3 * pE, - std::vector * pvec_inliers, - const std::pair & size_ima1, - const std::pair & size_ima2, - double * errorMax, - double * NFA, - double precision = std::numeric_limits::infinity()) -{ - assert(pvec_inliers != NULL); - assert(pE != NULL); - - // Use the 5 point solver to estimate E - typedef openMVG::essential::kernel::FivePointKernel SolverType; - // Define the AContrario adaptor - typedef ACKernelAdaptorEssential< - SolverType, - openMVG::fundamental::kernel::EpipolarDistanceError, - UnnormalizerT, - Mat3> - KernelType; - - KernelType kernel(x1, size_ima1.first, size_ima1.second, - x2, size_ima2.first, size_ima2.second, K1, K2); - - // Robustly estimation of the Essential matrix and it's precision - std::pair ACRansacOut = ACRANSAC(kernel, *pvec_inliers, - 4096, pE, precision, true); - *errorMax = ACRansacOut.first; - *NFA = ACRansacOut.second; - - return pvec_inliers->size() > 2.5 * SolverType::MINIMUM_SAMPLES; -} - - -/** -* @brief Estimate the best possible Rotation/Translation from E. -* Four are possible, keep the one with most of the point in front. -* -* @param[in] K1 camera 1 intrinsics -* @param[in] K2 camera 2 intrinsics -* @param[in] x1 camera 1 image points -* @param[in] x2 camera 2 image points -* @param[in] E essential matrix -* @param[in] vec_inliers inliers indices -* @param[out] R estimated rotation -* @param[out] t estimated translation -*/ -static bool estimate_Rt_fromE(const Mat3 & K1, const Mat3 & K2, - const Mat & x1, const Mat & x2, - const Mat3 & E, const std::vector & vec_inliers, - Mat3 * R, Vec3 * t) -{ - // Accumulator to find the best solution - std::vector f(4, 0); - - std::vector Es; // Essential, - std::vector Rs; // Rotation matrix. - std::vector ts; // Translation matrix. - - Es.push_back(E); - // Recover best rotation and translation from E. - MotionFromEssential(E, &Rs, &ts); - - //-> Test the 4 solutions will all the point - assert(Rs.size() == 4); - assert(ts.size() == 4); - - Mat34 P1, P2; - Mat3 R1 = Mat3::Identity(); - Vec3 t1 = Vec3::Zero(); - P_From_KRt(K1, R1, t1, &P1); - - for (unsigned int i = 0; i < 4; ++i) - { - const Mat3 &R2 = Rs[i]; - const Vec3 &t2 = ts[i]; - P_From_KRt(K2, R2, t2, &P2); - Vec3 X; - - for (size_t k = 0; k < vec_inliers.size(); ++k) - { - const Vec2 & x1_ = x1.col(vec_inliers[k]), - &x2_ = x2.col(vec_inliers[k]); - TriangulateDLT(P1, x1_, P2, x2_, &X); - // Test if point is front to the two cameras. - if (Depth(R1, t1, X) > 0 && Depth(R2, t2, X) > 0) - { - ++f[i]; - } - } - } - // Check the solution: - const std::vector::iterator iter = max_element(f.begin(), f.end()); - if (*iter == 0) - { - std::cerr << std::endl << "/!\\There is no right solution," - << " probably intermediate results are not correct or no points" - << " in front of both cameras" << std::endl; - return false; - } - const size_t index = std::distance(f.begin(), iter); - (*R) = Rs[index]; - (*t) = ts[index]; - - return true; -} - -} // namespace openMVG - -#endif // OPENMVG_SAMPLES_ROBUST_ESSENTIAL_HPP diff --git a/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp b/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp index 199b0fddef..68d7c66833 100644 --- a/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp +++ b/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp @@ -14,7 +14,6 @@ #include "openMVG/matching/matcher_brute_force.hpp" #include "openMVG/matching/indMatchDecoratorXY.hpp" #include "openMVG/multiview/triangulation.hpp" -#include "openMVG_Samples/robust_essential/essential_estimation.hpp" #include "openMVG_Samples/siftPutativeMatches/two_view_matches.hpp" @@ -230,7 +229,7 @@ int main() { std::cerr << "Invalid input number" << std::endl; return EXIT_FAILURE; } - + // Setup poses camera data const Pose3 pose0 = tiny_scene.poses[tiny_scene.views[0]->id_pose] = Pose3(Mat3::Identity(), Vec3::Zero()); const Pose3 pose1 = tiny_scene.poses[tiny_scene.views[1]->id_pose] = relativePose_info.relativePose; diff --git a/src/software/SfM/main_ComputeFeatures_OpenCV.cpp b/src/software/SfM/main_ComputeFeatures_OpenCV.cpp index f6bcb0b8dc..80c91e5ced 100644 --- a/src/software/SfM/main_ComputeFeatures_OpenCV.cpp +++ b/src/software/SfM/main_ComputeFeatures_OpenCV.cpp @@ -234,7 +234,7 @@ int main(int argc, char **argv) // - if regions file exist continue, // - if no file, compute features { - Timer timer; + system::Timer timer; Image imageGray; C_Progress_display my_progress_bar( sfm_data.GetViews().size(), std::cout, "\n- EXTRACT FEATURES -\n" ); From afa3bb2c4119631e13eb8dfd3c76e82466a9ddd5 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Thu, 21 May 2015 14:52:14 +0200 Subject: [PATCH 18/52] Fix some issue found by Visual Studio static code analyzer. --- src/third_party/CppUnitLite/Failure.cpp | 2 +- src/third_party/lemon/lemon/list_graph.h | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/third_party/CppUnitLite/Failure.cpp b/src/third_party/CppUnitLite/Failure.cpp index 454210e822..b4d0142389 100644 --- a/src/third_party/CppUnitLite/Failure.cpp +++ b/src/third_party/CppUnitLite/Failure.cpp @@ -44,7 +44,7 @@ Failure::Failure (const SimpleString& theTestName, message = SimpleString(stage); - delete stage; + delete [] stage; } diff --git a/src/third_party/lemon/lemon/list_graph.h b/src/third_party/lemon/lemon/list_graph.h index 2a236cf91d..00c9927b8e 100644 --- a/src/third_party/lemon/lemon/list_graph.h +++ b/src/third_party/lemon/lemon/list_graph.h @@ -582,7 +582,7 @@ namespace lemon { snapshot.addNode(node); } virtual void add(const std::vector& nodes) { - for (int i = nodes.size() - 1; i >= 0; ++i) { + for (int i = nodes.size() - 1; i >= 0; --i) { snapshot.addNode(nodes[i]); } } @@ -632,7 +632,7 @@ namespace lemon { snapshot.addArc(arc); } virtual void add(const std::vector& arcs) { - for (int i = arcs.size() - 1; i >= 0; ++i) { + for (int i = arcs.size() - 1; i >= 0; --i) { snapshot.addArc(arcs[i]); } } @@ -1394,7 +1394,7 @@ namespace lemon { snapshot.addNode(node); } virtual void add(const std::vector& nodes) { - for (int i = nodes.size() - 1; i >= 0; ++i) { + for (int i = nodes.size() - 1; i >= 0; --i) { snapshot.addNode(nodes[i]); } } @@ -1444,7 +1444,7 @@ namespace lemon { snapshot.addEdge(edge); } virtual void add(const std::vector& edges) { - for (int i = edges.size() - 1; i >= 0; ++i) { + for (int i = edges.size() - 1; i >= 0; --i) { snapshot.addEdge(edges[i]); } } @@ -2299,7 +2299,7 @@ namespace lemon { snapshot.addNode(node); } virtual void add(const std::vector& nodes) { - for (int i = nodes.size() - 1; i >= 0; ++i) { + for (int i = nodes.size() - 1; i >= 0; --i) { snapshot.addNode(nodes[i]); } } @@ -2349,7 +2349,7 @@ namespace lemon { snapshot.addEdge(edge); } virtual void add(const std::vector& edges) { - for (int i = edges.size() - 1; i >= 0; ++i) { + for (int i = edges.size() - 1; i >= 0; --i) { snapshot.addEdge(edges[i]); } } From 87f00bbaff2ff85130c2b509ca42e856c84a9c73 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Thu, 21 May 2015 15:23:35 +0200 Subject: [PATCH 19/52] use openMVG::cameras to use the openMVG/cameras module. #300 --- .../main_computeMatchesCasHas.cpp | 1 + src/openMVG/cameras/Camera_Common.hpp | 6 ++++++ src/openMVG/cameras/Camera_IO.hpp | 4 +++- src/openMVG/cameras/Camera_IO_test.cpp | 3 ++- src/openMVG/cameras/Camera_Intrinsics.hpp | 5 +++-- src/openMVG/cameras/Camera_Pinhole.hpp | 7 ++++--- src/openMVG/cameras/Camera_Pinhole_Radial.hpp | 8 +++++--- .../cameras/Camera_Pinhole_Radial_test.cpp | 1 + .../cameras/Camera_undistort_image.hpp | 4 +++- src/openMVG/cameras/PinholeCamera.hpp | 4 +++- .../GlobalSfM_translation_averaging.cpp | 3 +++ .../sfm/pipelines/global/global_SfM_test.cpp | 2 ++ .../sfm_global_engine_relative_motions.cpp | 3 +++ src/openMVG/sfm/pipelines/pipelines_test.hpp | 20 +++++++++---------- .../pipelines/sequential/sequential_SfM.cpp | 3 +++ .../pipelines/sequential/sequential_SfM.hpp | 4 ++-- .../sequential/sequential_SfM_test.cpp | 2 ++ .../structure_estimator.cpp | 3 +++ src/openMVG/sfm/sfm_data.hpp | 8 +++----- src/openMVG/sfm/sfm_data_BA_ceres.cpp | 3 +++ src/openMVG/sfm/sfm_data_BA_ceres.hpp | 4 +++- src/openMVG/sfm/sfm_data_BA_test.cpp | 2 ++ src/openMVG/sfm/sfm_data_filters.hpp | 12 +++++------ src/openMVG/sfm/sfm_data_filters_frustum.cpp | 7 ++++--- src/openMVG/sfm/sfm_data_io_test.cpp | 2 ++ src/openMVG/sfm/sfm_data_triangulation.cpp | 3 +++ src/openMVG/sfm/sfm_report.hpp | 4 ++-- .../robust_essential/robust_essential.cpp | 8 +++++--- .../robust_essential_ba.cpp | 2 ++ .../undisto_Brown/undistoBrown.cpp | 6 +++--- src/software/SfM/io_readGT.hpp | 2 ++ src/software/SfM/main_ComputeMatches.cpp | 1 + src/software/SfM/main_ConvertList.cpp | 1 + src/software/SfM/main_IncrementalSfM.cpp | 1 + .../SfM/main_SfMInit_ImageListing.cpp | 4 +++- src/software/SfM/main_openMVG2CMPMVS.cpp | 2 ++ src/software/SfM/main_openMVG2MESHLAB.cpp | 2 ++ src/software/SfM/main_openMVG2PMVS.cpp | 2 ++ src/software/SfMViewer/main.cpp | 4 +++- 39 files changed, 114 insertions(+), 49 deletions(-) diff --git a/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp b/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp index c01330d89a..cfaabb94bd 100644 --- a/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp +++ b/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp @@ -35,6 +35,7 @@ #include using namespace openMVG; +using namespace openMVG::cameras; using namespace openMVG::image; using namespace openMVG::matching; using namespace openMVG::robust; diff --git a/src/openMVG/cameras/Camera_Common.hpp b/src/openMVG/cameras/Camera_Common.hpp index 28fee77df2..b7853e6132 100644 --- a/src/openMVG/cameras/Camera_Common.hpp +++ b/src/openMVG/cameras/Camera_Common.hpp @@ -7,6 +7,9 @@ #ifndef OPENMVG_CAMERAS_COMMON_HPP #define OPENMVG_CAMERAS_COMMON_HPP +namespace openMVG { +namespace cameras { + enum EINTRINSIC { PINHOLE_CAMERA_START = 0, @@ -28,4 +31,7 @@ static bool isPinhole(EINTRINSIC eintrinsic) return eintrinsic > PINHOLE_CAMERA_START && eintrinsic < PINHOLE_CAMERA_END; } +} // namespace cameras +} // namespace openMVG + #endif // OPENMVG_CAMERAS_COMMON_HPP diff --git a/src/openMVG/cameras/Camera_IO.hpp b/src/openMVG/cameras/Camera_IO.hpp index 5d5fef0c46..2108d7c66c 100644 --- a/src/openMVG/cameras/Camera_IO.hpp +++ b/src/openMVG/cameras/Camera_IO.hpp @@ -15,7 +15,8 @@ #include #include -namespace openMVG{ +namespace openMVG { +namespace cameras { /// Save a Pinhole camera to a file as a P matrix (12 doubles as binary values) static bool save( @@ -74,6 +75,7 @@ static bool load( return false; } +} // namespace cameras } // namespace openMVG #endif // OPENMVG_CAMERA_IO_H diff --git a/src/openMVG/cameras/Camera_IO_test.cpp b/src/openMVG/cameras/Camera_IO_test.cpp index ac6132b093..e44b5268e0 100644 --- a/src/openMVG/cameras/Camera_IO_test.cpp +++ b/src/openMVG/cameras/Camera_IO_test.cpp @@ -6,6 +6,7 @@ #include "openMVG/cameras/Camera_IO.hpp" using namespace openMVG; +using namespace openMVG::cameras; #include "testing/testing.h" @@ -13,7 +14,7 @@ using std::string; TEST(Camera_IO, PinholeSaveRead) { - Mat3 R = Mat3 + const Mat3 R = Mat3 (Eigen::AngleAxisd(rand(), Vec3::UnitX()) * Eigen::AngleAxisd(rand(), Vec3::UnitY()) * Eigen::AngleAxisd(rand(), Vec3::UnitZ())); diff --git a/src/openMVG/cameras/Camera_Intrinsics.hpp b/src/openMVG/cameras/Camera_Intrinsics.hpp index f75a25b4b2..6ae7aa80e6 100644 --- a/src/openMVG/cameras/Camera_Intrinsics.hpp +++ b/src/openMVG/cameras/Camera_Intrinsics.hpp @@ -15,7 +15,8 @@ #include #include // Serialization -namespace openMVG{ +namespace openMVG { +namespace cameras { /// Basis class for all intrinsic parameters of a camera /// Store the image size & define all basis optical modelization of a camera @@ -142,8 +143,8 @@ static double AngleBetweenRay( return R2D(acos(clamp(dotAngle/mag, -1.0 + 1.e-8, 1.0 - 1.e-8))); } +} // namespace cameras } // namespace openMVG - #endif // #ifndef OPENMVG_CAMERA_INTRINSICS_H diff --git a/src/openMVG/cameras/Camera_Pinhole.hpp b/src/openMVG/cameras/Camera_Pinhole.hpp index e47ec9fdef..20cd5c06ae 100644 --- a/src/openMVG/cameras/Camera_Pinhole.hpp +++ b/src/openMVG/cameras/Camera_Pinhole.hpp @@ -14,7 +14,8 @@ #include -namespace openMVG{ +namespace openMVG { +namespace cameras { /// Define a classic Pinhole camera (store a K 3x3 matrix) /// with intrinsic parameters defining the K calibration matrix @@ -128,13 +129,13 @@ class Pinhole_Intrinsic : public IntrinsicBase } }; +} // namespace cameras } // namespace openMVG - #include #include -CEREAL_REGISTER_TYPE_WITH_NAME(openMVG::Pinhole_Intrinsic, "pinhole"); +CEREAL_REGISTER_TYPE_WITH_NAME(openMVG::cameras::Pinhole_Intrinsic, "pinhole"); #endif // #ifndef OPENMVG_CAMERA_PINHOLE_HPP diff --git a/src/openMVG/cameras/Camera_Pinhole_Radial.hpp b/src/openMVG/cameras/Camera_Pinhole_Radial.hpp index 38b485fa2c..79b7fec2ab 100644 --- a/src/openMVG/cameras/Camera_Pinhole_Radial.hpp +++ b/src/openMVG/cameras/Camera_Pinhole_Radial.hpp @@ -13,7 +13,8 @@ #include -namespace openMVG{ +namespace openMVG { +namespace cameras { namespace radial_distortion{ @@ -267,13 +268,14 @@ class Pinhole_Intrinsic_Radial_K3 : public Pinhole_Intrinsic } }; +} // namespace cameras } // namespace openMVG #include #include -CEREAL_REGISTER_TYPE_WITH_NAME(openMVG::Pinhole_Intrinsic_Radial_K1, "pinhole_radial_k1"); -CEREAL_REGISTER_TYPE_WITH_NAME(openMVG::Pinhole_Intrinsic_Radial_K3, "pinhole_radial_k3"); +CEREAL_REGISTER_TYPE_WITH_NAME(openMVG::cameras::Pinhole_Intrinsic_Radial_K1, "pinhole_radial_k1"); +CEREAL_REGISTER_TYPE_WITH_NAME(openMVG::cameras::Pinhole_Intrinsic_Radial_K3, "pinhole_radial_k3"); #endif // #ifndef OPENMVG_CAMERA_PINHOLE_RADIAL_K_HPP diff --git a/src/openMVG/cameras/Camera_Pinhole_Radial_test.cpp b/src/openMVG/cameras/Camera_Pinhole_Radial_test.cpp index ce9e51b75e..429d23b815 100644 --- a/src/openMVG/cameras/Camera_Pinhole_Radial_test.cpp +++ b/src/openMVG/cameras/Camera_Pinhole_Radial_test.cpp @@ -7,6 +7,7 @@ #include "openMVG/cameras/cameras.hpp" using namespace openMVG; +using namespace openMVG::cameras; #include "testing/testing.h" diff --git a/src/openMVG/cameras/Camera_undistort_image.hpp b/src/openMVG/cameras/Camera_undistort_image.hpp index 7ec1317a8b..f797587593 100644 --- a/src/openMVG/cameras/Camera_undistort_image.hpp +++ b/src/openMVG/cameras/Camera_undistort_image.hpp @@ -10,7 +10,8 @@ #include "openMVG/image/image.hpp" -namespace openMVG{ +namespace openMVG { +namespace cameras { /// Undistort an image according a given camera & it's distortion model template @@ -43,6 +44,7 @@ void UndistortImage( } } +} // namespace cameras } // namespace openMVG #endif // #ifndef OPENMVG_CAMERA_UNDISTORT_IMAGE_HPP diff --git a/src/openMVG/cameras/PinholeCamera.hpp b/src/openMVG/cameras/PinholeCamera.hpp index 39c4de6d2e..ba899b7f13 100644 --- a/src/openMVG/cameras/PinholeCamera.hpp +++ b/src/openMVG/cameras/PinholeCamera.hpp @@ -11,7 +11,8 @@ #include "openMVG/numeric/numeric.h" #include "openMVG/multiview/projection.hpp" -namespace openMVG{ +namespace openMVG { +namespace cameras { /// Pinhole camera P = K[R|t], t = -RC struct PinholeCamera @@ -103,6 +104,7 @@ struct PinholeCamera }; +} // namespace cameras } // namespace openMVG #endif // #ifndef OPENMVG_CAMERA_PINHOLECAMERA_H diff --git a/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp b/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp index 7a71a2135f..de396016ac 100644 --- a/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp +++ b/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp @@ -30,6 +30,9 @@ namespace openMVG{ namespace globalSfM{ +using namespace openMVG::cameras; +using namespace openMVG::geometry; + /// Use features in normalized camera frames bool GlobalSfM_Translation_AveragingSolver::Run( ETranslationAveragingMethod eTranslationAveragingMethod, diff --git a/src/openMVG/sfm/pipelines/global/global_SfM_test.cpp b/src/openMVG/sfm/pipelines/global/global_SfM_test.cpp index af703c6286..9510c5e143 100644 --- a/src/openMVG/sfm/pipelines/global/global_SfM_test.cpp +++ b/src/openMVG/sfm/pipelines/global/global_SfM_test.cpp @@ -20,6 +20,8 @@ #include "openMVG/sfm/pipelines/pipelines_test.hpp" #include "openMVG/sfm/sfm.hpp" using namespace openMVG; +using namespace openMVG::cameras; +using namespace openMVG::geometry; #include "testing/testing.h" diff --git a/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp b/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp index e9a8772e4b..9a8abbfe84 100644 --- a/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp +++ b/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp @@ -22,6 +22,9 @@ namespace openMVG{ +using namespace openMVG::geometry; +using namespace openMVG::cameras; + GlobalSfMReconstructionEngine_RelativeMotions::GlobalSfMReconstructionEngine_RelativeMotions( const SfM_Data & sfm_data, const std::string & soutDirectory, diff --git a/src/openMVG/sfm/pipelines/pipelines_test.hpp b/src/openMVG/sfm/pipelines/pipelines_test.hpp index 90486c3d2f..40e47802b7 100644 --- a/src/openMVG/sfm/pipelines/pipelines_test.hpp +++ b/src/openMVG/sfm/pipelines/pipelines_test.hpp @@ -73,8 +73,8 @@ static double RMSE(const SfM_Data & sfm_data) itObs != obs.end(); ++itObs) { const View * view = sfm_data.GetViews().find(itObs->first)->second.get(); - const Pose3 pose = sfm_data.GetPoseOrDie(view); - const std::shared_ptr intrinsic = sfm_data.GetIntrinsics().find(view->id_intrinsic)->second; + const geometry::Pose3 pose = sfm_data.GetPoseOrDie(view); + const std::shared_ptr intrinsic = sfm_data.GetIntrinsics().at(view->id_intrinsic); const Vec2 residual = intrinsic->residual(pose, iterTracks->second.X, itObs->second.x); //std::cout << residual << " "; vec.push_back( residual(0) ); @@ -92,7 +92,7 @@ SfM_Data getInputScene ( const NViewDataSet & d, const nViewDatasetConfigurator & config, - EINTRINSIC eintrinsic) + cameras::EINTRINSIC eintrinsic) { // Translate the input dataset to a SfM_Data scene SfM_Data sfm_data; @@ -116,7 +116,7 @@ SfM_Data getInputScene // 2. Poses for (int i = 0; i < nviews; ++i) { - sfm_data.poses[i] = Pose3(d._R[i], d._C[i]);; + sfm_data.poses[i] = geometry::Pose3(d._R[i], d._C[i]);; } // 3. Intrinsic data (shared, so only one camera intrinsic is defined) @@ -125,16 +125,16 @@ SfM_Data getInputScene const unsigned int h = config._cy *2; switch (eintrinsic) { - case PINHOLE_CAMERA: - sfm_data.intrinsics[0] = std::make_shared + case cameras::PINHOLE_CAMERA: + sfm_data.intrinsics[0] = std::make_shared (w, h, config._fx, config._cx, config._cy); break; - case PINHOLE_CAMERA_RADIAL1: - sfm_data.intrinsics[0] = std::make_shared + case cameras::PINHOLE_CAMERA_RADIAL1: + sfm_data.intrinsics[0] = std::make_shared (w, h, config._fx, config._cx, config._cy, 0.0); break; - case PINHOLE_CAMERA_RADIAL3: - sfm_data.intrinsics[0] = std::make_shared + case cameras::PINHOLE_CAMERA_RADIAL3: + sfm_data.intrinsics[0] = std::make_shared (w, h, config._fx, config._cx, config._cy, 0., 0., 0.); break; default: diff --git a/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp b/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp index 535cb81089..dd445efb8e 100644 --- a/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp +++ b/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp @@ -29,6 +29,9 @@ namespace openMVG{ +using namespace openMVG::geometry; +using namespace openMVG::cameras; + SequentialSfMReconstructionEngine::SequentialSfMReconstructionEngine( const SfM_Data & sfm_data, const std::string & soutDirectory, diff --git a/src/openMVG/sfm/pipelines/sequential/sequential_SfM.hpp b/src/openMVG/sfm/pipelines/sequential/sequential_SfM.hpp index 259c366614..8393a54994 100644 --- a/src/openMVG/sfm/pipelines/sequential/sequential_SfM.hpp +++ b/src/openMVG/sfm/pipelines/sequential/sequential_SfM.hpp @@ -48,7 +48,7 @@ class SequentialSfMReconstructionEngine : public ReconstructionEngine /// Compute the initial 3D seed (First camera t=0; R=Id, second estimated by 5 point algorithm) bool MakeInitialPair3D(const Pair & initialPair); - void SetUnknownCameraType(const EINTRINSIC camType) + void SetUnknownCameraType(const cameras::EINTRINSIC camType) { _camType = camType; } @@ -86,7 +86,7 @@ class SequentialSfMReconstructionEngine : public ReconstructionEngine // Parameter Pair _initialpair; - EINTRINSIC _camType; // The camera type for the unknown cameras + cameras::EINTRINSIC _camType; // The camera type for the unknown cameras //-- Data provider Features_Provider * _features_provider; diff --git a/src/openMVG/sfm/pipelines/sequential/sequential_SfM_test.cpp b/src/openMVG/sfm/pipelines/sequential/sequential_SfM_test.cpp index 5525b1cf24..d94f05380b 100644 --- a/src/openMVG/sfm/pipelines/sequential/sequential_SfM_test.cpp +++ b/src/openMVG/sfm/pipelines/sequential/sequential_SfM_test.cpp @@ -20,6 +20,8 @@ #include "openMVG/sfm/pipelines/pipelines_test.hpp" #include "openMVG/sfm/sfm.hpp" using namespace openMVG; +using namespace openMVG::cameras; +using namespace openMVG::geometry; #include "testing/testing.h" diff --git a/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.cpp b/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.cpp index c2e376dec4..8792d994d6 100644 --- a/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.cpp +++ b/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.cpp @@ -18,6 +18,9 @@ namespace openMVG { +using namespace openMVG::cameras; +using namespace openMVG::geometry; + /// Camera pair epipole (Projection of camera center 2 in the image plane 1) static Vec3 epipole_from_P(const Mat34& P1, const Pose3& P2) { diff --git a/src/openMVG/sfm/sfm_data.hpp b/src/openMVG/sfm/sfm_data.hpp index 223ddfccb0..5769edd506 100644 --- a/src/openMVG/sfm/sfm_data.hpp +++ b/src/openMVG/sfm/sfm_data.hpp @@ -15,16 +15,14 @@ namespace openMVG { -using namespace openMVG::geometry; - /// Define a collection of View typedef Hash_Map > Views; /// Define a collection of Pose (indexed by View::id_pose) -typedef Hash_Map Poses; +typedef Hash_Map Poses; /// Define a collection of IntrinsicParameter (indexed by View::id_intrinsic) -typedef Hash_Map > Intrinsics; +typedef Hash_Map > Intrinsics; /// Define a collection of landmarks are indexed by their TrackId typedef Hash_Map Landmarks; @@ -65,7 +63,7 @@ struct SfM_Data } /// Get the pose associated to a view - const Pose3 GetPoseOrDie(const View * view) const + const geometry::Pose3 GetPoseOrDie(const View * view) const { return poses.at(view->id_pose); } diff --git a/src/openMVG/sfm/sfm_data_BA_ceres.cpp b/src/openMVG/sfm/sfm_data_BA_ceres.cpp index e7076e6995..eed22b8fda 100644 --- a/src/openMVG/sfm/sfm_data_BA_ceres.cpp +++ b/src/openMVG/sfm/sfm_data_BA_ceres.cpp @@ -10,6 +10,9 @@ namespace openMVG { +using namespace openMVG::cameras; +using namespace openMVG::geometry; + /// Create the appropriate cost functor according the provided input camera intrinsic model ceres::CostFunction * IntrinsicsToCostFunction(IntrinsicBase * intrinsic, const Vec2 & observation) { diff --git a/src/openMVG/sfm/sfm_data_BA_ceres.hpp b/src/openMVG/sfm/sfm_data_BA_ceres.hpp index b9a3855225..413e970326 100644 --- a/src/openMVG/sfm/sfm_data_BA_ceres.hpp +++ b/src/openMVG/sfm/sfm_data_BA_ceres.hpp @@ -15,7 +15,9 @@ namespace openMVG { /// Create the appropriate cost functor according the provided input camera intrinsic model -ceres::CostFunction * IntrinsicsToCostFunction(IntrinsicBase * intrinsic, const Vec2 & observation); +ceres::CostFunction * IntrinsicsToCostFunction( + cameras::IntrinsicBase * intrinsic, + const Vec2 & observation); class Bundle_Adjustment_Ceres : public Bundle_Adjustment { diff --git a/src/openMVG/sfm/sfm_data_BA_test.cpp b/src/openMVG/sfm/sfm_data_BA_test.cpp index f1eea4d894..f48f16a3ba 100644 --- a/src/openMVG/sfm/sfm_data_BA_test.cpp +++ b/src/openMVG/sfm/sfm_data_BA_test.cpp @@ -18,6 +18,8 @@ #include "openMVG/multiview/test_data_sets.hpp" #include "openMVG/sfm/sfm.hpp" using namespace openMVG; +using namespace openMVG::cameras; +using namespace openMVG::geometry; #include "testing/testing.h" diff --git a/src/openMVG/sfm/sfm_data_filters.hpp b/src/openMVG/sfm/sfm_data_filters.hpp index 8183866e4b..0df8855b26 100644 --- a/src/openMVG/sfm/sfm_data_filters.hpp +++ b/src/openMVG/sfm/sfm_data_filters.hpp @@ -68,8 +68,8 @@ static IndexT RemoveOutliers_PixelResidualError while (itObs != obs.end()) { const View * view = sfm_data.views[itObs->first].get(); - const Pose3 pose = sfm_data.GetPoseOrDie(view); - const IntrinsicBase * intrinsic = sfm_data.intrinsics[view->id_intrinsic].get(); + const geometry::Pose3 pose = sfm_data.GetPoseOrDie(view); + const cameras::IntrinsicBase * intrinsic = sfm_data.intrinsics[view->id_intrinsic].get(); const Vec2 residual = intrinsic->residual(pose, iterTracks->second.X, itObs->second.x); if (residual.norm() > dThresholdPixel) { @@ -105,16 +105,16 @@ static IndexT RemoveOutliers_AngleError itObs1 != obs.end(); ++itObs1) { const View * view1 = sfm_data.views[itObs1->first].get(); - const Pose3 pose1 = sfm_data.GetPoseOrDie(view1); - const IntrinsicBase * intrinsic1 = sfm_data.intrinsics[view1->id_intrinsic].get(); + const geometry::Pose3 pose1 = sfm_data.GetPoseOrDie(view1); + const cameras::IntrinsicBase * intrinsic1 = sfm_data.intrinsics[view1->id_intrinsic].get(); Observations::const_iterator itObs2 = itObs1; ++itObs2; for (; itObs2 != obs.end(); ++itObs2) { const View * view2 = sfm_data.views[itObs2->first].get(); - const Pose3 pose2 = sfm_data.GetPoseOrDie(view2); - const IntrinsicBase * intrinsic2 = sfm_data.intrinsics[view2->id_intrinsic].get(); + const geometry::Pose3 pose2 = sfm_data.GetPoseOrDie(view2); + const cameras::IntrinsicBase * intrinsic2 = sfm_data.intrinsics[view2->id_intrinsic].get(); const double angle = AngleBetweenRay( pose1, intrinsic1, pose2, intrinsic2, diff --git a/src/openMVG/sfm/sfm_data_filters_frustum.cpp b/src/openMVG/sfm/sfm_data_filters_frustum.cpp index 64dc3767a5..f210785bb4 100644 --- a/src/openMVG/sfm/sfm_data_filters_frustum.cpp +++ b/src/openMVG/sfm/sfm_data_filters_frustum.cpp @@ -9,14 +9,15 @@ #include "openMVG/sfm/sfm.hpp" #include "openMVG/types.hpp" #include "openMVG/geometry/half_space_intersection.hpp" -using namespace openMVG; -using namespace openMVG::geometry; -using namespace openMVG::geometry::halfPlane; #include namespace openMVG { +using namespace openMVG::cameras; +using namespace openMVG::geometry; +using namespace openMVG::geometry::halfPlane; + // Constructor Frustum_Filter::Frustum_Filter(const SfM_Data & sfm_data, const double zNear, const double zFar) diff --git a/src/openMVG/sfm/sfm_data_io_test.cpp b/src/openMVG/sfm/sfm_data_io_test.cpp index ae8510b5d8..28478ef4f6 100644 --- a/src/openMVG/sfm/sfm_data_io_test.cpp +++ b/src/openMVG/sfm/sfm_data_io_test.cpp @@ -12,6 +12,8 @@ #include using namespace openMVG; +using namespace openMVG::cameras; +using namespace openMVG::geometry; // Create a SfM scene with desired count of views & poses & intrinsic (shared or not) // Add a 3D point with observation in 2 view (just in order to have non empty data) diff --git a/src/openMVG/sfm/sfm_data_triangulation.cpp b/src/openMVG/sfm/sfm_data_triangulation.cpp index 0366c834eb..d2f7ed9e11 100644 --- a/src/openMVG/sfm/sfm_data_triangulation.cpp +++ b/src/openMVG/sfm/sfm_data_triangulation.cpp @@ -15,6 +15,9 @@ namespace openMVG { +using namespace openMVG::geometry; +using namespace openMVG::cameras; + SfM_Data_Structure_Computation_Basis::SfM_Data_Structure_Computation_Basis(bool bConsoleVerbose) :_bConsoleVerbose(bConsoleVerbose) { diff --git a/src/openMVG/sfm/sfm_report.hpp b/src/openMVG/sfm/sfm_report.hpp index f1db8f0007..e2fb8ea220 100644 --- a/src/openMVG/sfm/sfm_report.hpp +++ b/src/openMVG/sfm/sfm_report.hpp @@ -33,8 +33,8 @@ static bool Generate_SfM_Report itObs != obs.end(); ++itObs) { const View * view = sfm_data.GetViews().at(itObs->first).get(); - const Pose3 pose = sfm_data.GetPoseOrDie(view); - const IntrinsicBase * intrinsic = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); + const geometry::Pose3 pose = sfm_data.GetPoseOrDie(view); + const cameras::IntrinsicBase * intrinsic = sfm_data.GetIntrinsics().at(view->id_intrinsic).get(); // Use absolute values const Vec2 residual = intrinsic->residual(pose, iterTracks->second.X, itObs->second.x).array().abs(); residuals_per_view[itObs->first].push_back(residual(0)); diff --git a/src/openMVG_Samples/robust_essential/robust_essential.cpp b/src/openMVG_Samples/robust_essential/robust_essential.cpp index 424e605ac5..52c72b2f96 100644 --- a/src/openMVG_Samples/robust_essential/robust_essential.cpp +++ b/src/openMVG_Samples/robust_essential/robust_essential.cpp @@ -25,6 +25,8 @@ using namespace openMVG; using namespace openMVG::matching; using namespace openMVG::image; +using namespace openMVG::cameras; +using namespace openMVG::geometry; using namespace svg; using namespace std; @@ -168,7 +170,7 @@ int main() { << "\t#inliers: " << relativePose_info.vec_inliers.size() << "\n" << "\t#matches: " << vec_PutativeMatches.size() << std::endl; - + // Show Essential validated point svgDrawer svgStream( imageL.Width() + imageR.Width(), max(imageL.Height(), imageR.Height())); svgStream.drawImage(jpg_filenameL, imageL.Width(), imageL.Height()); @@ -186,10 +188,10 @@ int main() { std::ofstream svgFile( out_filename.c_str() ); svgFile << svgStream.closeSvgFile().str(); svgFile.close(); - + //C. Triangulate and export inliers as a PLY scene std::vector vec_3DPoints; - + // Setup camera intrinsic and poses Pinhole_Intrinsic intrinsic0(imageL.Width(), imageL.Height(), K(0, 0), K(0, 2), K(1, 2)); Pinhole_Intrinsic intrinsic1(imageR.Width(), imageR.Height(), K(0, 0), K(0, 2), K(1, 2)); diff --git a/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp b/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp index 68d7c66833..672ec10e83 100644 --- a/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp +++ b/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp @@ -28,6 +28,8 @@ using namespace openMVG; using namespace openMVG::image; using namespace openMVG::matching; +using namespace openMVG::cameras; +using namespace openMVG::geometry; using namespace svg; using namespace std; diff --git a/src/openMVG_Samples/undisto_Brown/undistoBrown.cpp b/src/openMVG_Samples/undisto_Brown/undistoBrown.cpp index 6441386430..5deb46080a 100644 --- a/src/openMVG_Samples/undisto_Brown/undistoBrown.cpp +++ b/src/openMVG_Samples/undisto_Brown/undistoBrown.cpp @@ -16,10 +16,10 @@ #include using namespace openMVG; +using namespace openMVG::cameras; using namespace openMVG::image; using namespace std; - int main(int argc, char **argv) { CmdLine cmd; @@ -80,13 +80,13 @@ int main(int argc, char **argv) Image imageGreyIn, imageGreyU; Image imageRGBIn, imageRGBU; Image imageRGBAIn, imageRGBAU; - + C_Progress_display my_progress_bar( vec_fileNames.size() ); for (size_t j = 0; j < vec_fileNames.size(); ++j, ++my_progress_bar) { //read the depth int w,h,depth; - vector tmp_vec; + vector tmp_vec; const string sOutFileName = stlplus::create_filespec(sOutPath, stlplus::basename_part(vec_fileNames[j]), "JPG"); const string sInFileName = stlplus::create_filespec(sPath, stlplus::basename_part(vec_fileNames[j])); diff --git a/src/software/SfM/io_readGT.hpp b/src/software/SfM/io_readGT.hpp index 99b3de5efd..168c97b67b 100644 --- a/src/software/SfM/io_readGT.hpp +++ b/src/software/SfM/io_readGT.hpp @@ -17,6 +17,8 @@ namespace openMVG { +using namespace openMVG::cameras; + static bool read_openMVG_Camera(const std::string & camName, PinholeCamera & cam) { std::vector val; diff --git a/src/software/SfM/main_ComputeMatches.cpp b/src/software/SfM/main_ComputeMatches.cpp index 96924e1fc8..1d901ba891 100644 --- a/src/software/SfM/main_ComputeMatches.cpp +++ b/src/software/SfM/main_ComputeMatches.cpp @@ -31,6 +31,7 @@ using namespace openMVG; using namespace openMVG::matching; using namespace openMVG::robust; +using namespace openMVG::cameras; using namespace std; enum EGeometricModel diff --git a/src/software/SfM/main_ConvertList.cpp b/src/software/SfM/main_ConvertList.cpp index f0fd7c3d5c..f7626e020c 100644 --- a/src/software/SfM/main_ConvertList.cpp +++ b/src/software/SfM/main_ConvertList.cpp @@ -17,6 +17,7 @@ #include using namespace openMVG; +using namespace openMVG::cameras; // Compatibility binary // Convert an openMVG v0.x=>7 lists.txt file to the new SfM_Data file format (v0.8) diff --git a/src/software/SfM/main_IncrementalSfM.cpp b/src/software/SfM/main_IncrementalSfM.cpp index 50e3865909..cafe3e5c18 100644 --- a/src/software/SfM/main_IncrementalSfM.cpp +++ b/src/software/SfM/main_IncrementalSfM.cpp @@ -12,6 +12,7 @@ #include "openMVG/system/timer.hpp" using namespace openMVG; +using namespace openMVG::cameras; #include "third_party/cmdLine/cmdLine.h" #include "third_party/stlplus3/filesystemSimplified/file_system.hpp" diff --git a/src/software/SfM/main_SfMInit_ImageListing.cpp b/src/software/SfM/main_SfMInit_ImageListing.cpp index 101e88e36a..1ab532231b 100644 --- a/src/software/SfM/main_SfMInit_ImageListing.cpp +++ b/src/software/SfM/main_SfMInit_ImageListing.cpp @@ -23,8 +23,10 @@ #include using namespace openMVG; -using namespace openMVG::image; +using namespace openMVG::cameras; using namespace openMVG::exif; +using namespace openMVG::image; + /// Check that Kmatrix is a string like "f;0;ppx;0;f;ppy;0;0;1" /// With f,ppx,ppy as valid numerical value diff --git a/src/software/SfM/main_openMVG2CMPMVS.cpp b/src/software/SfM/main_openMVG2CMPMVS.cpp index 8188e30e4a..8206050edf 100644 --- a/src/software/SfM/main_openMVG2CMPMVS.cpp +++ b/src/software/SfM/main_openMVG2CMPMVS.cpp @@ -9,6 +9,8 @@ #include "openMVG/image/image.hpp" using namespace openMVG; +using namespace openMVG::cameras; +using namespace openMVG::geometry; using namespace openMVG::image; #include "third_party/cmdLine/cmdLine.h" diff --git a/src/software/SfM/main_openMVG2MESHLAB.cpp b/src/software/SfM/main_openMVG2MESHLAB.cpp index 2d9c04620c..0a6f1c8f5c 100644 --- a/src/software/SfM/main_openMVG2MESHLAB.cpp +++ b/src/software/SfM/main_openMVG2MESHLAB.cpp @@ -10,6 +10,8 @@ #include "openMVG/image/image.hpp" using namespace openMVG; +using namespace openMVG::cameras; +using namespace openMVG::geometry; using namespace openMVG::image; #include "third_party/cmdLine/cmdLine.h" diff --git a/src/software/SfM/main_openMVG2PMVS.cpp b/src/software/SfM/main_openMVG2PMVS.cpp index 223be3c8d9..da4b40dff6 100644 --- a/src/software/SfM/main_openMVG2PMVS.cpp +++ b/src/software/SfM/main_openMVG2PMVS.cpp @@ -9,6 +9,8 @@ #include "openMVG/image/image.hpp" using namespace openMVG; +using namespace openMVG::cameras; +using namespace openMVG::geometry; using namespace openMVG::image; #include "third_party/cmdLine/cmdLine.h" diff --git a/src/software/SfMViewer/main.cpp b/src/software/SfMViewer/main.cpp index 28cd9c4f92..450a1fbf9b 100644 --- a/src/software/SfMViewer/main.cpp +++ b/src/software/SfMViewer/main.cpp @@ -18,7 +18,9 @@ #include "third_party/cmdLine/cmdLine.h" -using namespace openMVG; +using namespace openMVG; +using namespace openMVG::cameras; +using namespace openMVG::geometry; using namespace openMVG::image; static int running = 1; From 768ee1eba01ff6dac805b8b201141acecb2c4d77 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Thu, 21 May 2015 16:31:11 +0200 Subject: [PATCH 20/52] use openMVG::features to use the openMVG/features module. #300 --- .../matching_cascade_hashing/CasHash.hpp | 2 +- .../Matcher_CascadeHashing.hpp | 4 +- .../selection_VLDSegment.hpp | 6 +- .../selection_matchedPoints.hpp | 12 +- src/openMVG/features/akaze/AKAZE.cpp | 4 +- src/openMVG/features/akaze/AKAZE.hpp | 4 +- .../features/akaze/mldb_descriptor.hpp | 9 +- .../features/akaze/msurf_descriptor.hpp | 9 +- src/openMVG/features/descriptor.hpp | 5 +- src/openMVG/features/feature.hpp | 2 + src/openMVG/features/features_test.cpp | 1 + src/openMVG/features/keypointSet.hpp | 2 + src/openMVG/features/liop/liop_descriptor.cpp | 419 ++++++++++++++++++ src/openMVG/features/liop/liop_descriptor.hpp | 385 +--------------- src/openMVG/matching/indMatchDecoratorXY.hpp | 8 +- src/openMVG/matching/kvld/algorithm.cpp | 4 +- src/openMVG/matching/kvld/algorithm.h | 4 +- src/openMVG/matching/kvld/kvld.cpp | 4 +- src/openMVG/matching/kvld/kvld.h | 4 +- src/openMVG/matching/kvld/kvld_draw.h | 14 +- .../GeometricFilter.hpp | 8 +- .../Matcher_Regions_AllInMemory.cpp | 1 + .../robust_estimation/guided_matching.hpp | 4 +- .../GlobalSfM_translation_averaging.cpp | 2 +- .../sfm_global_engine_relative_motions.cpp | 3 +- src/openMVG/sfm/pipelines/pipelines_test.hpp | 3 +- .../sfm/pipelines/sfm_features_provider.hpp | 8 +- .../structure_estimator.cpp | 1 + .../colorHarmonizeEngineGlobal.cpp | 2 +- .../colorHarmonizeEngineGlobal.hpp | 2 +- 30 files changed, 500 insertions(+), 436 deletions(-) create mode 100644 src/openMVG/features/liop/liop_descriptor.cpp diff --git a/src/nonFree/matching_cascade_hashing/CasHash.hpp b/src/nonFree/matching_cascade_hashing/CasHash.hpp index 66f2426456..55fa6b6781 100644 --- a/src/nonFree/matching_cascade_hashing/CasHash.hpp +++ b/src/nonFree/matching_cascade_hashing/CasHash.hpp @@ -84,7 +84,7 @@ struct ImageFeatures { /*----------------------------------------------------------------*/ // Define SIFT descriptors -typedef Descriptor DescriptorT; +typedef features::Descriptor DescriptorT; typedef std::vector DescsT; // fetch and adjust each SIFT feature vector in to zero-mean diff --git a/src/nonFree/matching_cascade_hashing/Matcher_CascadeHashing.hpp b/src/nonFree/matching_cascade_hashing/Matcher_CascadeHashing.hpp index 290eb9fff5..531505bfcb 100644 --- a/src/nonFree/matching_cascade_hashing/Matcher_CascadeHashing.hpp +++ b/src/nonFree/matching_cascade_hashing/Matcher_CascadeHashing.hpp @@ -83,7 +83,7 @@ class Matcher_CascadeHashing_AllInMemory { const size_t I = iter->first; const features::Regions *regionsI = regions_perImage.at(I).get(); - const std::vector pointFeaturesI = regionsI->GetRegionsPositions(); + const std::vector pointFeaturesI = regionsI->GetRegionsPositions(); const std::vector & indexToCompare = iter->second; #ifdef OPENMVG_USE_OPENMP @@ -105,7 +105,7 @@ class Matcher_CascadeHashing_AllInMemory IndMatch::getDeduplicated(vec_FilteredMatches); // Remove matches that have the same (X,Y) coordinates - const std::vector pointFeaturesJ = regionsJ->GetRegionsPositions(); + const std::vector pointFeaturesJ = regionsJ->GetRegionsPositions(); IndMatchDecorator matchDeduplicator(vec_FilteredMatches, pointFeaturesI, pointFeaturesJ); matchDeduplicator.getDeduplicated(vec_FilteredMatches); diff --git a/src/openMVG/color_harmonization/selection_VLDSegment.hpp b/src/openMVG/color_harmonization/selection_VLDSegment.hpp index 6ffe6b3aa4..b1bedd2bab 100644 --- a/src/openMVG/color_harmonization/selection_VLDSegment.hpp +++ b/src/openMVG/color_harmonization/selection_VLDSegment.hpp @@ -21,8 +21,8 @@ class commonDataByPair_VLDSegment : public commonDataByPair commonDataByPair_VLDSegment( const std::string & sLeftImage, const std::string & sRightImage, const std::vector< matching::IndMatch >& vec_PutativeMatches, - const vector< SIOPointFeature >& vec_featsL, - const vector< SIOPointFeature >& vec_featsR): + const vector< features::SIOPointFeature >& vec_featsL, + const vector< features::SIOPointFeature >& vec_featsR): commonDataByPair( sLeftImage, sRightImage ), _vec_PutativeMatches( vec_PutativeMatches ), _vec_featsL( vec_featsL ), _vec_featsR( vec_featsR ) @@ -108,7 +108,7 @@ class commonDataByPair_VLDSegment : public commonDataByPair private: // Left and Right features - std::vector< SIOPointFeature > _vec_featsL, _vec_featsR; + std::vector< features::SIOPointFeature > _vec_featsL, _vec_featsR; // Left and Right corresponding index (putatives matches) std::vector< matching::IndMatch > _vec_PutativeMatches; }; diff --git a/src/openMVG/color_harmonization/selection_matchedPoints.hpp b/src/openMVG/color_harmonization/selection_matchedPoints.hpp index 28296f6bc5..7d30c13e46 100644 --- a/src/openMVG/color_harmonization/selection_matchedPoints.hpp +++ b/src/openMVG/color_harmonization/selection_matchedPoints.hpp @@ -23,8 +23,8 @@ class commonDataByPair_MatchedPoints : public commonDataByPair commonDataByPair_MatchedPoints(const std::string & sLeftImage, const std::string & sRightImage, const std::vector< matching::IndMatch >& vec_PutativeMatches, - const std::vector< SIOPointFeature >& vec_featsL, - const std::vector< SIOPointFeature >& vec_featsR, + const std::vector< features::SIOPointFeature >& vec_featsL, + const std::vector< features::SIOPointFeature >& vec_featsR, const size_t radius = 1 ): commonDataByPair( sLeftImage, sRightImage ), _vec_PutativeMatches( vec_PutativeMatches ), @@ -51,8 +51,8 @@ class commonDataByPair_MatchedPoints : public commonDataByPair iter_putativeMatches != _vec_PutativeMatches.end(); ++iter_putativeMatches ) { - const SIOPointFeature & L = _vec_featsL[ iter_putativeMatches->_i ]; - const SIOPointFeature & R = _vec_featsR[ iter_putativeMatches->_j ]; + const features::SIOPointFeature & L = _vec_featsL[ iter_putativeMatches->_i ]; + const features::SIOPointFeature & R = _vec_featsR[ iter_putativeMatches->_j ]; image::FilledCircle( L.x(), L.y(), ( int )_radius, ( unsigned char ) 255, &maskLeft ); image::FilledCircle( R.x(), R.y(), ( int )_radius, ( unsigned char ) 255, &maskRight ); @@ -63,8 +63,8 @@ class commonDataByPair_MatchedPoints : public commonDataByPair private: size_t _radius; std::vector< matching::IndMatch > _vec_PutativeMatches; - std::vector< SIOPointFeature > _vec_featsL; - std::vector< SIOPointFeature > _vec_featsR; + std::vector< features::SIOPointFeature > _vec_featsL; + std::vector< features::SIOPointFeature > _vec_featsR; }; } // namespace color_harmonization diff --git a/src/openMVG/features/akaze/AKAZE.cpp b/src/openMVG/features/akaze/AKAZE.cpp index a2a7bebca3..88aff95353 100644 --- a/src/openMVG/features/akaze/AKAZE.cpp +++ b/src/openMVG/features/akaze/AKAZE.cpp @@ -7,6 +7,7 @@ #include "openMVG/features/akaze/AKAZE.hpp" namespace openMVG { +namespace features { using namespace openMVG::image; @@ -597,5 +598,6 @@ void AKAZE::Compute_Main_Orientation( } } -}; // namespace openMVG +} // namespace features +} // namespace openMVG diff --git a/src/openMVG/features/akaze/AKAZE.hpp b/src/openMVG/features/akaze/AKAZE.hpp index 77f820ec64..9006989dff 100644 --- a/src/openMVG/features/akaze/AKAZE.hpp +++ b/src/openMVG/features/akaze/AKAZE.hpp @@ -42,6 +42,7 @@ #include namespace openMVG { +namespace features { struct AKAZEConfig { @@ -162,6 +163,7 @@ class AKAZE { }; /* ************************************************************************* */ -}; // namespace openMVG +} // namespace features +} // namespace openMVG #endif //OPENMVG_FEATURES_AKAZE_H diff --git a/src/openMVG/features/akaze/mldb_descriptor.hpp b/src/openMVG/features/akaze/mldb_descriptor.hpp index 9675115ff2..106dca9aef 100644 --- a/src/openMVG/features/akaze/mldb_descriptor.hpp +++ b/src/openMVG/features/akaze/mldb_descriptor.hpp @@ -12,8 +12,9 @@ #include "openMVG/image/image.hpp" #include "openMVG/numeric/math_trait.hpp" -namespace openMVG -{ +namespace openMVG { +namespace features { + /** ** @brief Compute mean values (Li,Lx,Ly) in each subdivisions ** @param samples_Li input values on Li @@ -216,6 +217,8 @@ namespace openMVG assert( outIndex == 486 ) ; // Just to be sure (and we are sure ! completly sure !) } -} + +} // namespace features +} // namespace openMVG #endif diff --git a/src/openMVG/features/akaze/msurf_descriptor.hpp b/src/openMVG/features/akaze/msurf_descriptor.hpp index 00e460cebf..ac967019e5 100644 --- a/src/openMVG/features/akaze/msurf_descriptor.hpp +++ b/src/openMVG/features/akaze/msurf_descriptor.hpp @@ -11,8 +11,9 @@ #include "openMVG/features/feature.hpp" #include "openMVG/numeric/math_trait.hpp" -namespace openMVG -{ +namespace openMVG { +namespace features { + /** * @brief This function computes the value of a 2D Gaussian function * @param x X Position @@ -156,6 +157,8 @@ namespace openMVG ipt , descFloat); } -} + +} // namespace features +} // namespace openMVG #endif diff --git a/src/openMVG/features/descriptor.hpp b/src/openMVG/features/descriptor.hpp index f3763084d5..d3128a1802 100644 --- a/src/openMVG/features/descriptor.hpp +++ b/src/openMVG/features/descriptor.hpp @@ -16,6 +16,7 @@ #include namespace openMVG { +namespace features { /** * Class that handle descriptor (a data container of N values of type T). @@ -209,7 +210,7 @@ static bool saveDescsToBinFile( return bOk; } - -} // namespace openMVG +} // namespace features +} // namespace openMVG #endif // OPENMVG_FEATURES_DESCRIPTOR_HPP diff --git a/src/openMVG/features/feature.hpp b/src/openMVG/features/feature.hpp index 7362439486..39347f2a3f 100644 --- a/src/openMVG/features/feature.hpp +++ b/src/openMVG/features/feature.hpp @@ -16,6 +16,7 @@ #include namespace openMVG { +namespace features { /** * Base class for Point features. @@ -170,6 +171,7 @@ void PointsToMat( } } +} // namespace features } // namespace openMVG #endif // OPENMVG_FEATURES_FEATURE_HPP diff --git a/src/openMVG/features/features_test.cpp b/src/openMVG/features/features_test.cpp index ab4daddd43..5e8269a7c3 100644 --- a/src/openMVG/features/features_test.cpp +++ b/src/openMVG/features/features_test.cpp @@ -6,6 +6,7 @@ #include "openMVG/features/features.hpp" using namespace openMVG; +using namespace openMVG::features; #include "testing/testing.h" diff --git a/src/openMVG/features/keypointSet.hpp b/src/openMVG/features/keypointSet.hpp index 05935b926f..8e19942b95 100644 --- a/src/openMVG/features/keypointSet.hpp +++ b/src/openMVG/features/keypointSet.hpp @@ -13,6 +13,7 @@ #include namespace openMVG { +namespace features { /// Association storage of associated feature and descriptor for a given image. /// Load, save, R/W accessor operation. @@ -78,6 +79,7 @@ class KeypointSet { DescriptorsT _descs; }; +} // namespace features } // namespace openMVG #endif // OPENMVG_FEATURES_KEYPOINTSET_HPP diff --git a/src/openMVG/features/liop/liop_descriptor.cpp b/src/openMVG/features/liop/liop_descriptor.cpp new file mode 100644 index 0000000000..6ceb76b320 --- /dev/null +++ b/src/openMVG/features/liop/liop_descriptor.cpp @@ -0,0 +1,419 @@ + +// Copyright (C) 2013 "Robot Vision Group, NLPR, CASIA", Zhenhua Wang, +// Bin Fan and Fuchao Wu. + +// Copyright (C) 2014: Adaptation to openMVG by Pierre MOULON. + +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +//------------------ +//-- Bibliography -- +//------------------ +//- [1] "Local Intensity Order Pattern for Feature Description" +//- Authors: Zhenhua Wang, Bin Fan and Fuchao Wu +//- Date: 2011, ICCV, IEEE International Conference on Computer Vision + +#include + +#include +#include + +namespace openMVG { +namespace features{ +namespace LIOP { + +const int MAX_REGION_NUM = 10; +const int MAX_PIXEL_NUM = 1681; +const int MAX_SAMPLE_NUM = 10; +const int LIOP_NUM = 4; +const int REGION_NUM = 6; + +Liop_Descriptor_Extractor::Liop_Descriptor_Extractor() +{ + GeneratePatternMap( m_LiopPatternMap, m_LiopPosWeight, LIOP_NUM); +} + +struct Pixel{ + float x, y; // position + float f_gray; // color value + float weight; + int l_pattern; +}; + +inline bool fGrayComp(const Pixel & p1, const Pixel & p2) +{ + return p1.f_gray < p2.f_gray; +} + +bool BilinearInterpolation_BorderCheck( + float& val, + float x, float y, + const image::Image & image, + const image::Image & flagImage) +{ + val = 0.0f; + if(!(x >= 0 && y >= 0 && x<=image.Width()-1 && y<=image.Height()-1)) + return false; + + const int x1 = (int)x; + const int y1 = (int)y; + + int x2, y2; + if( x1 == image.Width()-1) + x2 = x1; + else + x2 = x1+1; + + if(y1 == image.Height()-1 ) + y2 = y1; + else + y2 = y1+1; + + const int step = image.Width(); + const float* data = image.data(); + + const int flag_step = flagImage.Width(); + const unsigned char* flag_data = flagImage.data(); + + if(flag_data[y1*flag_step+x1] == 0 || + flag_data[y1*flag_step+x2] == 0 || + flag_data[y2*flag_step+x1] == 0 || + flag_data[y2*flag_step+x2] == 0) + return false; + + val = + (x2 - x) * (y2 - y) * data[y1*step+x1] + + (x - x1) * (y2 - y) * data[y1*step+x2] + + (x2 - x) * (y - y1) * data[y2*step+x1] + + (x - x1) * (y - y1) * data[y2*step+x2]; + return true; +} + +//non descend +void SortGray(float* dst, int* idx, float* src, int len) +{ + int i, j; + + for (i=0; i illuThresh) + { + des[i] = illuThresh; + } + } + + // Normalize again. + + norm = 0.f; + + for (i=0; i & outPatch, + const image::Image & flagPatch, + const int inRadius, + float desc[144]) const +{ + const float* out_data = outPatch.data(); + const int out_step = outPatch.Width(); + const unsigned char* flag_data = flagPatch.data(); + const int flag_step = flagPatch.Width(); + + const float inRadius2 = float(inRadius*inRadius); + const int outRadius = outPatch.Width() / 2; + + const int lsRadius = 6; + const float theta = 2.0f*M_PI/(float)LIOP_NUM; + + Pixel pixel[MAX_PIXEL_NUM]; + int pixelCount = 0; + int idx[MAX_SAMPLE_NUM]; + float dst[MAX_SAMPLE_NUM]; + float src[MAX_SAMPLE_NUM]; + + for (int y=-inRadius; y<=inRadius; ++y) + { + for (int x=-inRadius; x<=inRadius; ++x) + { + float dis2 = (float)(x*x + y*y); + if(dis2 > inRadius2) + continue; + + const float cur_gray = out_data [(y+outRadius)*out_step +x+outRadius]; + const unsigned char cur_flag = flag_data[(y+outRadius)*flag_step+x+outRadius]; + if (cur_flag == 0) + continue; + + const float nDirX = static_cast(x); + const float nDirY = static_cast(y); + float nOri = atan2(nDirY, nDirX); + if (fabs(nOri - M_PI) < FLT_EPSILON) //[-M_PI, M_PI) + { + nOri = static_cast(-M_PI); + } + + bool isInBound = true; + for (int k=0; k::const_iterator iter = m_LiopPatternMap.find(key); + if (iter != m_LiopPatternMap.end()) + { + Pixel pix; + pix.x = x; + pix.y = y; + pix.f_gray = cur_gray; + pix.weight = 1; + pix.l_pattern = iter->second; + pixel[pixelCount++] = pix; + } + } + } + + std::sort(pixel, pixel+pixelCount, fGrayComp); //sort by gray + + const int l_patternWidth = LIOP_NUM == 3 ? 6 : 24; + const int dim = l_patternWidth*REGION_NUM; + + if (pixelCount >= REGION_NUM) + { + int curId = 0; + int lastId = 0; + for (int i=0; ifenceGray) + break; + + const int id = regionId*l_patternWidth+pixel[curId].l_pattern; + desc[id] += pixel[curId].weight; + ++curId; + } + } + + ThreshNorm(desc,dim,1.f); + } +} + +void Liop_Descriptor_Extractor::extract( + const image::Image & I, + const SIOPointFeature & feat, + float desc[144]) +{ + memset(desc, 0, sizeof(float)*144); + + //a. extract the local patch + const int scalePatchWidth = 31; + + const int outPatchWidth = scalePatchWidth+6; + const int outRadius = outPatchWidth/2; + const int outRadius2 = outRadius*outRadius; + const float scale = feat.scale(); + + image::Image outPatch(outPatchWidth,outPatchWidth, true, 0); + image::Image flagPatch(outPatchWidth, outPatchWidth, true, 0); + + // pointer alias + const unsigned char * img_data = I.GetMat().data(); + unsigned char * flagPatch_data = flagPatch.data(); + float * outPatch_data = outPatch.data(); + + for(int y=-outRadius; y<=outRadius; ++y) + { + const float ys = y*scale+feat.y(); + if(ys<0 || ys>I.Height()-1) + continue; + + for(int x=-outRadius; x<=outRadius; ++x) + { + const float dis2 = (float)(x*x + y*y); + if(dis2 > outRadius2) + continue; + + const float xs = x*scale+feat.x(); + if(xs<0 || xs>I.Width()-1) + continue; + + outPatch_data[(y+outRadius)*outPatchWidth+x+outRadius] = SampleLinear(I, ys, xs); + flagPatch_data[(y+outRadius)*outPatchWidth+x+outRadius] = 1; + } + } + image::ImageGaussianFilter(image::Image(outPatch), 1.2, outPatch); + + //b. creation of the LIOP ordering + const int inRadius = scalePatchWidth/2; + CreateLIOP_GOrder(outPatch, flagPatch, inRadius, desc); +} + +template +bool NextPermutation(std::vector & p, int n) +{ + int last = n - 1; + int i, j, k; + + i = last; + while (i > 0 && p[i] < p[i - 1]) + i--; + + if (i == 0) + return false; + + k = i; + for (j = last; j >= i; j--) + if (p[j] > p[i - 1] && p[j] < p[k]) + k = j; + std::swap(p[k], p[i - 1]); + for (j = last, k = i; j > k; j--, k++) + std::swap(p[j], p[k]); + + return true; +} + +void Liop_Descriptor_Extractor::GeneratePatternMap( + std::map & pattern_map, + std::vector & pos_weight, + unsigned char n) +{ + pattern_map.clear(); + pos_weight.resize(n); + + //do the job + std::vector p(n); + pos_weight[0] = 1; + for (unsigned char i=1; i #include -#include -#include #include #include namespace openMVG { +namespace features{ namespace LIOP { -const int MAX_REGION_NUM = 10; -const int MAX_PIXEL_NUM = 1681; -const int MAX_SAMPLE_NUM = 10; -const int LIOP_NUM = 4; -const int REGION_NUM = 6; - class Liop_Descriptor_Extractor { private: @@ -41,391 +34,25 @@ class Liop_Descriptor_Extractor std::vector m_LiopPosWeight; public: - Liop_Descriptor_Extractor() - { - GeneratePatternMap( m_LiopPatternMap, m_LiopPosWeight, LIOP_NUM); - } + Liop_Descriptor_Extractor(); void extract( const image::Image & I, const SIOPointFeature & feat, - float desc[144]) - { - memset(desc, 0, sizeof(float)*144); - - //a. extract the local patch - const int scalePatchWidth = 31; - - const int outPatchWidth = scalePatchWidth+6; - const int outRadius = outPatchWidth/2; - const int outRadius2 = outRadius*outRadius; - const float scale = feat.scale(); - - image::Image outPatch(outPatchWidth,outPatchWidth, true, 0); - image::Image flagPatch(outPatchWidth, outPatchWidth, true, 0); - - // pointer alias - const unsigned char * img_data = I.GetMat().data(); - unsigned char * flagPatch_data = flagPatch.data(); - float * outPatch_data = outPatch.data(); - - for(int y=-outRadius; y<=outRadius; ++y) - { - const float ys = y*scale+feat.y(); - if(ys<0 || ys>I.Height()-1) - continue; - - for(int x=-outRadius; x<=outRadius; ++x) - { - const float dis2 = (float)(x*x + y*y); - if(dis2 > outRadius2) - continue; - - const float xs = x*scale+feat.x(); - if(xs<0 || xs>I.Width()-1) - continue; - - outPatch_data[(y+outRadius)*outPatchWidth+x+outRadius] = SampleLinear(I, ys, xs); - flagPatch_data[(y+outRadius)*outPatchWidth+x+outRadius] = 1; - } - } - image::ImageGaussianFilter(image::Image(outPatch), 1.2, outPatch); - - //b. creation of the LIOP ordering - const int inRadius = scalePatchWidth/2; - CreateLIOP_GOrder(outPatch, flagPatch, inRadius, desc); - } - - struct Pixel{ - float x, y; // position - float f_gray; // color value - float weight; - int l_pattern; - }; + float desc[144]); void CreateLIOP_GOrder( const image::Image & outPatch, const image::Image & flagPatch, const int inRadius, - float desc[144]) - { - const float* out_data = outPatch.data(); - const int out_step = outPatch.Width(); - const unsigned char* flag_data = flagPatch.data(); - const int flag_step = flagPatch.Width(); - - const float inRadius2 = float(inRadius*inRadius); - const int outRadius = outPatch.Width() / 2; - - const int lsRadius = 6; - const float theta = 2.0f*M_PI/(float)LIOP_NUM; - - Pixel pixel[MAX_PIXEL_NUM]; - int pixelCount = 0; - int idx[MAX_SAMPLE_NUM]; - float dst[MAX_SAMPLE_NUM]; - float src[MAX_SAMPLE_NUM]; - - for (int y=-inRadius; y<=inRadius; ++y) - { - for (int x=-inRadius; x<=inRadius; ++x) - { - float dis2 = (float)(x*x + y*y); - if(dis2 > inRadius2) - continue; - - const float cur_gray = out_data [(y+outRadius)*out_step +x+outRadius]; - const unsigned char cur_flag = flag_data[(y+outRadius)*flag_step+x+outRadius]; - if (cur_flag == 0) - continue; - - const float nDirX = static_cast(x); - const float nDirY = static_cast(y); - float nOri = atan2(nDirY, nDirX); - if (fabs(nOri - M_PI) < FLT_EPSILON) //[-M_PI, M_PI) - { - nOri = static_cast(-M_PI); - } - - bool isInBound = true; - for (int k=0; k::const_iterator iter = m_LiopPatternMap.find(key); - if (iter != m_LiopPatternMap.end()) - { - Pixel pix; - pix.x = x; - pix.y = y; - pix.f_gray = cur_gray; - pix.weight = 1; - pix.l_pattern = iter->second; - pixel[pixelCount++] = pix; - } - } - } - - std::sort(pixel, pixel+pixelCount, fGrayComp); //sort by gray - - const int l_patternWidth = LIOP_NUM == 3 ? 6 : 24; - const int dim = l_patternWidth*REGION_NUM; - - if (pixelCount >= REGION_NUM) - { - int curId = 0; - int lastId = 0; - for (int i=0; ifenceGray) - break; - - const int id = regionId*l_patternWidth+pixel[curId].l_pattern; - desc[id] += pixel[curId].weight; - ++curId; - } - } - - ThreshNorm(desc,dim,1.f); - } - } - private: - - bool BilinearInterpolation_BorderCheck( - float& val, - float x, float y, - const image::Image & image, - const image::Image & flagImage) const - { - val = 0.0f; - if(!(x >= 0 && y >= 0 && x<=image.Width()-1 && y<=image.Height()-1)) - return false; - - const int x1 = (int)x; - const int y1 = (int)y; - - int x2, y2; - if( x1 == image.Width()-1) - x2 = x1; - else - x2 = x1+1; - - if(y1 == image.Height()-1 ) - y2 = y1; - else - y2 = y1+1; - - const int step = image.Width(); - const float* data = image.data(); - - const int flag_step = flagImage.Width(); - const unsigned char* flag_data = flagImage.data(); - - if(flag_data[y1*flag_step+x1] == 0 || - flag_data[y1*flag_step+x2] == 0 || - flag_data[y2*flag_step+x1] == 0 || - flag_data[y2*flag_step+x2] == 0) - return false; - - val = - (x2 - x) * (y2 - y) * data[y1*step+x1] + - (x - x1) * (y2 - y) * data[y1*step+x2] + - (x2 - x) * (y - y1) * data[y2*step+x1] + - (x - x1) * (y - y1) * data[y2*step+x2]; - return true; - } - - inline static bool fGrayComp(const Pixel & p1, const Pixel & p2) - { - return p1.f_gray < p2.f_gray; - } - - //non descend - void SortGray(float* dst, int* idx, float* src, int len) - { - int i, j; - - for (i=0; i & pattern_map, std::vector & pos_weight, - unsigned char n) - { - pattern_map.clear(); - pos_weight.resize(n); - - //do the job - std::vector p(n); - pos_weight[0] = 1; - for (unsigned char i=1; i - bool NextPermutation(std::vector & p, int n) - { - int last = n - 1; - int i, j, k; - - i = last; - while (i > 0 && p[i] < p[i - 1]) - i--; - - if (i == 0) - return false; - - k = i; - for (j = last; j >= i; j--) - if (p[j] > p[i - 1] && p[j] < p[k]) - k = j; - std::swap(p[k], p[i - 1]); - for (j = last, k = i; j > k; j--, k++) - std::swap(p[j], p[k]); - - return true; - } - - /// To avoid linear illumination change, we normalize the descriptor. - /// To avoid non-linear illumination change, we threshold the value - /// of each descriptor element to 'illuThresh', then normalize again. - void ThreshNorm(float* des, int dim, float illuThresh) - { - // Normalize the descriptor, and threshold - // value of each element to 'illuThresh'. - - float norm = 0.f; - int i; - - for (i=0; i illuThresh) - { - des[i] = illuThresh; - } - } - - // Normalize again. - - norm = 0.f; - - for (i=0; i & vec_matches, - const std::vector & leftFeat, - const std::vector & rightFeat) + const std::vector & leftFeat, + const std::vector & rightFeat) :_vec_matches(vec_matches) { for (size_t i = 0; i < vec_matches.size(); ++i) { @@ -74,8 +74,8 @@ class IndMatchDecorator } IndMatchDecorator(const std::vector & vec_matches, - const std::vector & leftFeat, - const std::vector & rightFeat) + const std::vector & leftFeat, + const std::vector & rightFeat) :_vec_matches(vec_matches) { for (size_t i = 0; i < vec_matches.size(); ++i) { diff --git a/src/openMVG/matching/kvld/algorithm.cpp b/src/openMVG/matching/kvld/algorithm.cpp index 26422c535e..5c956078e4 100644 --- a/src/openMVG/matching/kvld/algorithm.cpp +++ b/src/openMVG/matching/kvld/algorithm.cpp @@ -37,7 +37,7 @@ float getRange( //=============================IO interface======================// -std::ofstream& writeDetector( std::ofstream& out, const openMVG::SIOPointFeature& feature ) +std::ofstream& writeDetector( std::ofstream& out, const openMVG::features::SIOPointFeature& feature ) { out << feature.x() << " " << feature.y() << " " @@ -46,7 +46,7 @@ std::ofstream& writeDetector( std::ofstream& out, const openMVG::SIOPointFeature return out; } -std::ifstream& readDetector( std::ifstream& in, openMVG::SIOPointFeature& point ) +std::ifstream& readDetector( std::ifstream& in, openMVG::features::SIOPointFeature& point ) { in >> point.x() >> point.y() diff --git a/src/openMVG/matching/kvld/algorithm.h b/src/openMVG/matching/kvld/algorithm.h index 3988d5cc0f..b576277404 100644 --- a/src/openMVG/matching/kvld/algorithm.h +++ b/src/openMVG/matching/kvld/algorithm.h @@ -85,8 +85,8 @@ private : //=============================IO interface ======================// -std::ofstream& writeDetector( std::ofstream& out, const openMVG::SIOPointFeature& vect ); -std::ifstream& readDetector( std::ifstream& in, openMVG::SIOPointFeature& point ); +std::ofstream& writeDetector( std::ofstream& out, const openMVG::features::SIOPointFeature& vect ); +std::ifstream& readDetector( std::ifstream& in, openMVG::features::SIOPointFeature& point ); //======================================elemetuary operations================================// template < typename T > inline T point_distance( const T x1, const T y1, const T x2, const T y2 ) diff --git a/src/openMVG/matching/kvld/kvld.cpp b/src/openMVG/matching/kvld/kvld.cpp index 564edc603a..3433638720 100644 --- a/src/openMVG/matching/kvld/kvld.cpp +++ b/src/openMVG/matching/kvld/kvld.cpp @@ -200,8 +200,8 @@ VLD::VLD( const ImageScale& series, T const& P1, T const& P2 ) : contrast( 0.0 ) float KVLD( const Image< float >& I1, const Image< float >& I2, - const std::vector & F1, - const std::vector & F2, + const std::vector & F1, + const std::vector & F2, const vector< Pair >& matches, vector< Pair >& matchesFiltered, vector< double >& score, diff --git a/src/openMVG/matching/kvld/kvld.h b/src/openMVG/matching/kvld/kvld.h index 8b1eb00b66..4ea72f5a47 100644 --- a/src/openMVG/matching/kvld/kvld.h +++ b/src/openMVG/matching/kvld/kvld.h @@ -174,8 +174,8 @@ class VLD float KVLD(const openMVG::image::Image< float >& I1, const openMVG::image::Image< float >& I2, - const std::vector & F1, - const std::vector & F2, + const std::vector & F1, + const std::vector & F2, const std::vector< openMVG::Pair >& matches, std::vector< openMVG::Pair >& matchesFiltered, std::vector< double >& score, diff --git a/src/openMVG/matching/kvld/kvld_draw.h b/src/openMVG/matching/kvld/kvld_draw.h index 8b016206e4..6fe1f7a084 100644 --- a/src/openMVG/matching/kvld/kvld_draw.h +++ b/src/openMVG/matching/kvld/kvld_draw.h @@ -16,8 +16,8 @@ namespace openMVG { void getKVLDMask( image::Image< unsigned char > *maskL, image::Image< unsigned char > *maskR, - const std::vector< openMVG::SIOPointFeature > &vec_F1, - const std::vector< openMVG::SIOPointFeature > &vec_F2, + const std::vector< features::SIOPointFeature > &vec_F1, + const std::vector< features::SIOPointFeature > &vec_F2, const std::vector< Pair >& vec_matches, const std::vector< bool >& vec_valide, const openMVG::Mat& mat_E) @@ -28,17 +28,17 @@ void getKVLDMask( { if( vec_valide[ it1 ] && vec_valide[ it2 ] && mat_E( it1, it2 ) >= 0 ) { - const openMVG::SIOPointFeature & l1 = vec_F1[ vec_matches[ it1 ].first ]; - const openMVG::SIOPointFeature & l2 = vec_F1[ vec_matches[ it2 ].first ]; + const features::SIOPointFeature & l1 = vec_F1[ vec_matches[ it1 ].first ]; + const features::SIOPointFeature & l2 = vec_F1[ vec_matches[ it2 ].first ]; float l = ( l1.coords() - l2.coords() ).norm(); int widthL = std::max( 1.f, l / ( dimension + 1.f ) ); image::DrawLineThickness(l1.x(), l1.y(), l2.x(), l2.y(), 255, widthL, maskL); - const openMVG::SIOPointFeature & r1 = vec_F2[ vec_matches[ it1 ].second ]; - const openMVG::SIOPointFeature & r2 = vec_F2[ vec_matches[ it2 ].second ]; + const features::SIOPointFeature & r1 = vec_F2[ vec_matches[ it1 ].second ]; + const features::SIOPointFeature & r2 = vec_F2[ vec_matches[ it2 ].second ]; float r = ( r1.coords() - r2.coords() ).norm(); - int widthR = std::max( 1.f, r / ( dimension + 1.f ) ); + int widthR = std::max( 1.f, r / ( dimension + 1.f ) ); image::DrawLineThickness(r1.x(), r1.y(), r2.x(), r2.y(), 255, widthR, maskR); } diff --git a/src/openMVG/matching_image_collection/GeometricFilter.hpp b/src/openMVG/matching_image_collection/GeometricFilter.hpp index abd68fc7d9..88a1f690e4 100644 --- a/src/openMVG/matching_image_collection/GeometricFilter.hpp +++ b/src/openMVG/matching_image_collection/GeometricFilter.hpp @@ -55,16 +55,16 @@ class ImageCollectionGeometricFilter const std::vector & vec_PutativeMatches = iter->second; // Load features of Inth and Jnth images - const PointFeatures & kpSetI = _feat_provider->getFeatures(iIndex); - const PointFeatures & kpSetJ = _feat_provider->getFeatures(jIndex); + const features::PointFeatures & kpSetI = _feat_provider->getFeatures(iIndex); + const features::PointFeatures & kpSetJ = _feat_provider->getFeatures(jIndex); //-- Copy point to array in order to estimate fundamental matrix : const size_t n = vec_PutativeMatches.size(); Mat xI(2,n), xJ(2,n); for (size_t i=0; i < vec_PutativeMatches.size(); ++i) { - const PointFeature & imaA = kpSetI[vec_PutativeMatches[i]._i]; - const PointFeature & imaB = kpSetJ[vec_PutativeMatches[i]._j]; + const features::PointFeature & imaA = kpSetI[vec_PutativeMatches[i]._i]; + const features::PointFeature & imaB = kpSetJ[vec_PutativeMatches[i]._j]; xI.col(i) = Vec2f(imaA.coords()).cast(); xJ.col(i) = Vec2f(imaB.coords()).cast(); } diff --git a/src/openMVG/matching_image_collection/Matcher_Regions_AllInMemory.cpp b/src/openMVG/matching_image_collection/Matcher_Regions_AllInMemory.cpp index 90f9ef1ebd..9dde7193ff 100644 --- a/src/openMVG/matching_image_collection/Matcher_Regions_AllInMemory.cpp +++ b/src/openMVG/matching_image_collection/Matcher_Regions_AllInMemory.cpp @@ -20,6 +20,7 @@ namespace openMVG { using namespace openMVG::matching; +using namespace openMVG::features; Matcher_Regions_AllInMemory::Matcher_Regions_AllInMemory( float distRatio, EMatcherType eMatcherType) diff --git a/src/openMVG/robust_estimation/guided_matching.hpp b/src/openMVG/robust_estimation/guided_matching.hpp index 7c8bcb7783..16a776125c 100644 --- a/src/openMVG/robust_estimation/guided_matching.hpp +++ b/src/openMVG/robust_estimation/guided_matching.hpp @@ -243,8 +243,8 @@ void GuidedMatching_Fundamental_Fast( // - For each right point, compute threshold limited bandwidth and compare only // points that belong to this range (limited buckets). - const PointFeatures r_pt = rRegions->GetRegionsPositions(); - const PointFeatures l_pt = lRegions->GetRegionsPositions(); + const features::PointFeatures r_pt = rRegions->GetRegionsPositions(); + const features::PointFeatures l_pt = lRegions->GetRegionsPositions(); MetricT metric; diff --git a/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp b/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp index de396016ac..e60e2a4f99 100644 --- a/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp +++ b/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp @@ -600,7 +600,7 @@ bool GlobalSfM_Translation_AveragingSolver::Estimate_T_triplet( for (tracks::submapTrack::const_iterator iter = subTrack.begin(); iter != subTrack.end(); ++iter, ++index) { const size_t imaIndex = iter->first; const size_t featIndex = iter->second; - const PointFeature pt = features_provider->getFeatures(imaIndex)[featIndex]; + const features::PointFeature pt = features_provider->getFeatures(imaIndex)[featIndex]; xxx[index]->col(cpt) = pt.coords().cast(); } } diff --git a/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp b/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp index 9a8abbfe84..25aafe277e 100644 --- a/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp +++ b/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp @@ -22,8 +22,9 @@ namespace openMVG{ -using namespace openMVG::geometry; using namespace openMVG::cameras; +using namespace openMVG::geometry; +using namespace openMVG::features; GlobalSfMReconstructionEngine_RelativeMotions::GlobalSfMReconstructionEngine_RelativeMotions( const SfM_Data & sfm_data, diff --git a/src/openMVG/sfm/pipelines/pipelines_test.hpp b/src/openMVG/sfm/pipelines/pipelines_test.hpp index 40e47802b7..09aa5a3652 100644 --- a/src/openMVG/sfm/pipelines/pipelines_test.hpp +++ b/src/openMVG/sfm/pipelines/pipelines_test.hpp @@ -29,7 +29,7 @@ struct Synthetic_Features_Provider : public Features_Provider { const Vec2 pt = synthetic_data._x[j].col(i); feats_per_view[j].push_back( - PointFeature(pt(0)+noise(generator), pt(1)+noise(generator))); + features::PointFeature(pt(0)+noise(generator), pt(1)+noise(generator))); } } return true; @@ -48,7 +48,6 @@ struct Synthetic_Matches_Provider : public Matches_Provider { for (int jj = j+1; jj < j+3 ; ++jj) { - std::cout << j << "\t" << (jj)%synthetic_data._n << std::endl; for (int idx = 0; idx < synthetic_data._x[j].cols(); ++idx) { _pairWise_matches[Pair(j,(jj)%synthetic_data._n)].push_back(IndMatch(idx,idx)); diff --git a/src/openMVG/sfm/pipelines/sfm_features_provider.hpp b/src/openMVG/sfm/pipelines/sfm_features_provider.hpp index f72434fc5e..57e89517e0 100644 --- a/src/openMVG/sfm/pipelines/sfm_features_provider.hpp +++ b/src/openMVG/sfm/pipelines/sfm_features_provider.hpp @@ -22,7 +22,7 @@ namespace openMVG{ struct Features_Provider { /// PointFeature array per ViewId of the considered SfM_Data container - Hash_Map feats_per_view; + Hash_Map feats_per_view; // Load features related to a provided SfM_Data View container virtual bool load( @@ -82,12 +82,12 @@ struct Features_Provider /// Return the PointFeatures belonging to the View, if the view does not exist /// it return an empty PointFeature array. - const PointFeatures & getFeatures(const IndexT & id_view) const + const features::PointFeatures & getFeatures(const IndexT & id_view) const { // Have an empty feature set in order to deal with non existing view_id - static const PointFeatures emptyFeats = PointFeatures(); + static const features::PointFeatures emptyFeats = features::PointFeatures(); - Hash_Map::const_iterator it = feats_per_view.find(id_view); + Hash_Map::const_iterator it = feats_per_view.find(id_view); if (it != feats_per_view.end()) return it->second; else diff --git a/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.cpp b/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.cpp index 8792d994d6..d754388763 100644 --- a/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.cpp +++ b/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.cpp @@ -19,6 +19,7 @@ namespace openMVG { using namespace openMVG::cameras; +using namespace openMVG::features; using namespace openMVG::geometry; /// Camera pair epipole (Projection of camera center 2 in the image plane 1) diff --git a/src/software/colorHarmonize/colorHarmonizeEngineGlobal.cpp b/src/software/colorHarmonize/colorHarmonizeEngineGlobal.cpp index 64a12bc958..ef7dd3e513 100644 --- a/src/software/colorHarmonize/colorHarmonizeEngineGlobal.cpp +++ b/src/software/colorHarmonize/colorHarmonizeEngineGlobal.cpp @@ -47,7 +47,7 @@ using namespace openMVG::image; using namespace openMVG::matching; using namespace openMVG::lInfinity; -typedef SIOPointFeature FeatureT; +typedef features::SIOPointFeature FeatureT; typedef vector< FeatureT > featsT; ColorHarmonizationEngineGlobal::ColorHarmonizationEngineGlobal( diff --git a/src/software/colorHarmonize/colorHarmonizeEngineGlobal.hpp b/src/software/colorHarmonize/colorHarmonizeEngineGlobal.hpp index a803f3b40e..b9e045ae55 100644 --- a/src/software/colorHarmonize/colorHarmonizeEngineGlobal.hpp +++ b/src/software/colorHarmonize/colorHarmonizeEngineGlobal.hpp @@ -55,7 +55,7 @@ class ColorHarmonizationEngineGlobal // ---- std::vector< std::string > _vec_fileNames; // considered images - std::map< size_t, std::vector< SIOPointFeature > > _map_feats; // feature per images + std::map< size_t, std::vector< features::SIOPointFeature > > _map_feats; // feature per images std::vector< std::pair< size_t, size_t > > _vec_imageSize; // Size of each image From cc82175851de81ccccb0cebceb05b66074c1fc10 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Thu, 21 May 2015 17:53:34 +0200 Subject: [PATCH 21/52] use openMVG::sfm to use the openMVG/sfm module. #300 --- .../main_computeMatchesCasHas.cpp | 1 + .../GeometricFilter.hpp | 4 ++-- .../global/GlobalSfM_rotation_averaging.cpp | 8 ++++---- .../global/GlobalSfM_rotation_averaging.hpp | 10 +++++----- .../global/GlobalSfM_translation_averaging.cpp | 8 ++++---- .../global/GlobalSfM_translation_averaging.hpp | 10 +++++----- .../sfm/pipelines/global/global_SfM_test.cpp | 13 +++++++------ src/openMVG/sfm/pipelines/global/mutexSet.hpp | 4 +++- .../sfm_global_engine_relative_motions.cpp | 18 ++++++++++-------- .../sfm_global_engine_relative_motions.hpp | 10 ++++++---- .../pipelines/global/sfm_global_reindex.hpp | 2 ++ .../triplet_t_ACRansac_kernelAdaptator.hpp | 2 ++ src/openMVG/sfm/pipelines/pipelines_test.hpp | 1 + .../pipelines/sequential/sequential_SfM.cpp | 4 +++- .../pipelines/sequential/sequential_SfM.hpp | 5 ++++- .../sequential/sequential_SfM_test.cpp | 1 + src/openMVG/sfm/pipelines/sfm_engine.hpp | 5 ++++- .../sfm/pipelines/sfm_features_provider.hpp | 4 +++- .../sfm/pipelines/sfm_matches_provider.hpp | 4 +++- .../sfm/pipelines/sfm_regions_provider.hpp | 4 +++- .../pipelines/sfm_robust_model_estimation.cpp | 5 +++-- .../pipelines/sfm_robust_model_estimation.hpp | 5 +++-- .../structure_estimator.cpp | 4 ++++ .../structure_estimator.hpp | 3 +++ src/openMVG/sfm/sfm_data.hpp | 2 ++ src/openMVG/sfm/sfm_data_BA.hpp | 2 ++ src/openMVG/sfm/sfm_data_BA_ceres.cpp | 2 ++ src/openMVG/sfm/sfm_data_BA_ceres.hpp | 3 +++ .../sfm/sfm_data_BA_ceres_camera_functor.hpp | 3 ++- src/openMVG/sfm/sfm_data_BA_test.cpp | 1 + src/openMVG/sfm/sfm_data_filters.hpp | 4 +++- src/openMVG/sfm/sfm_data_filters_frustum.cpp | 4 +++- src/openMVG/sfm/sfm_data_filters_frustum.hpp | 5 +++-- src/openMVG/sfm/sfm_data_io.cpp | 2 ++ src/openMVG/sfm/sfm_data_io.hpp | 5 +++-- src/openMVG/sfm/sfm_data_io_baf.hpp | 5 +++-- src/openMVG/sfm/sfm_data_io_cereal.hpp | 5 +++-- src/openMVG/sfm/sfm_data_io_ply.hpp | 5 +++-- src/openMVG/sfm/sfm_data_io_test.cpp | 1 + src/openMVG/sfm/sfm_data_triangulation.cpp | 2 ++ src/openMVG/sfm/sfm_data_triangulation.hpp | 2 ++ src/openMVG/sfm/sfm_filters.hpp | 2 ++ src/openMVG/sfm/sfm_landmark.hpp | 2 ++ src/openMVG/sfm/sfm_report.hpp | 2 ++ src/openMVG/sfm/sfm_view.hpp | 2 ++ .../robust_essential/robust_essential.cpp | 4 ++-- .../robust_essential_ba.cpp | 1 + src/software/SfM/main_ComputeFeatures.cpp | 2 ++ .../SfM/main_ComputeFeatures_OpenCV.cpp | 3 ++- src/software/SfM/main_ComputeMatches.cpp | 3 ++- src/software/SfM/main_ComputeSfM_DataColor.cpp | 1 + .../main_ComputeStructureFromKnownPoses.cpp | 1 + src/software/SfM/main_ConvertList.cpp | 1 + .../SfM/main_ConvertSfM_DataFormat.cpp | 1 + src/software/SfM/main_ExportCameraFrustums.cpp | 1 + src/software/SfM/main_FrustumFiltering.cpp | 1 + src/software/SfM/main_GlobalSfM.cpp | 16 ++++++++-------- src/software/SfM/main_IncrementalSfM.cpp | 4 ++-- src/software/SfM/main_SfMInit_ImageListing.cpp | 2 +- src/software/SfM/main_evalQuality.cpp | 1 + src/software/SfM/main_exportKeypoints.cpp | 1 + src/software/SfM/main_exportMatches.cpp | 3 ++- src/software/SfM/main_exportTracks.cpp | 3 ++- src/software/SfM/main_openMVG2CMPMVS.cpp | 1 + src/software/SfM/main_openMVG2MESHLAB.cpp | 1 + src/software/SfM/main_openMVG2PMVS.cpp | 1 + src/software/SfMViewer/main.cpp | 3 ++- .../colorHarmonizeEngineGlobal.cpp | 3 ++- 68 files changed, 173 insertions(+), 81 deletions(-) diff --git a/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp b/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp index cfaabb94bd..3cd28c7953 100644 --- a/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp +++ b/src/nonFree/matching_cascade_hashing/main_computeMatchesCasHas.cpp @@ -39,6 +39,7 @@ using namespace openMVG::cameras; using namespace openMVG::image; using namespace openMVG::matching; using namespace openMVG::robust; +using namespace openMVG::sfm; using namespace std; enum eGeometricModel diff --git a/src/openMVG/matching_image_collection/GeometricFilter.hpp b/src/openMVG/matching_image_collection/GeometricFilter.hpp index 88a1f690e4..a8d10fcd9b 100644 --- a/src/openMVG/matching_image_collection/GeometricFilter.hpp +++ b/src/openMVG/matching_image_collection/GeometricFilter.hpp @@ -28,7 +28,7 @@ class ImageCollectionGeometricFilter { } - ImageCollectionGeometricFilter(Features_Provider * feat_provider) + ImageCollectionGeometricFilter(sfm::Features_Provider * feat_provider) : _feat_provider(feat_provider) { } @@ -104,6 +104,6 @@ class ImageCollectionGeometricFilter private: // Features per image - Features_Provider * _feat_provider; + sfm::Features_Provider * _feat_provider; }; diff --git a/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.cpp b/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.cpp index 20393af244..e3b61b64ed 100644 --- a/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.cpp +++ b/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.cpp @@ -15,7 +15,7 @@ #include "third_party/histogram/histogram.hpp" namespace openMVG{ -namespace globalSfM{ +namespace sfm{ using namespace openMVG::rotation_averaging; @@ -56,7 +56,7 @@ bool GlobalSfM_Rotation_AveragingSolver::Run( const Pair_Set pairs = getPairs(relativeRotations); Hash_Map _reindexForward, _reindexBackward; - openMVG::reindex(pairs, _reindexForward, _reindexBackward); + reindex(pairs, _reindexForward, _reindexBackward); for(RelativeRotations::iterator iter = relativeRotations.begin(); iter != relativeRotations.end(); ++iter) { @@ -229,6 +229,6 @@ void GlobalSfM_Rotation_AveragingSolver::TripletRotationRejection( std::cout << "\n #Edges removed by triplet inference: " << edges_start_count - edges_end_count << std::endl; } - -} // namespace globalSfM +} // namespace sfm } // namespace openMVG + diff --git a/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.hpp b/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.hpp index 13bb4efcb0..f24f30e968 100644 --- a/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.hpp +++ b/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.hpp @@ -9,7 +9,7 @@ #define OPENMVG_SFM_GLOBAL_ENGINE_PIPELINES_GLOBAL_ROTATION_AVERAGING_HPP namespace openMVG{ -namespace globalSfM{ +namespace sfm{ enum ERotationAveragingMethod { @@ -23,15 +23,15 @@ enum ERelativeRotationInferenceMethod TRIPLET_ROTATION_INFERENCE_COMPOSITION_ERROR = 1 }; -} -} +} // namespace sfm +} // namespace openMVG #include "openMVG/sfm/sfm.hpp" #include "openMVG/graph/graph.hpp" #include "openMVG/multiview/rotation_averaging_common.hpp" namespace openMVG{ -namespace globalSfM{ +namespace sfm{ class GlobalSfM_Rotation_AveragingSolver { @@ -55,7 +55,7 @@ class GlobalSfM_Rotation_AveragingSolver }; -} // namespace globalSfM +} // namespace sfm } // namespace openMVG #endif // OPENMVG_SFM_GLOBAL_ENGINE_PIPELINES_GLOBAL_ROTATION_AVERAGING_HPP diff --git a/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp b/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp index e60e2a4f99..dcdd4c67ed 100644 --- a/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp +++ b/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.cpp @@ -28,7 +28,7 @@ #include "third_party/stlplus3/filesystemSimplified/file_system.hpp" namespace openMVG{ -namespace globalSfM{ +namespace sfm{ using namespace openMVG::cameras; using namespace openMVG::geometry; @@ -102,7 +102,7 @@ bool GlobalSfM_Translation_AveragingSolver::Translation_averaging( RelativeInfo_Vec vec_initialRijTijEstimates_cpy = vec_initialRijTijEstimates; const Pair_Set pairs = getPairs(vec_initialRijTijEstimates_cpy); Hash_Map _reindexForward, _reindexBackward; - openMVG::reindex(pairs, _reindexForward, _reindexBackward); + reindex(pairs, _reindexForward, _reindexBackward); for(size_t i = 0; i < vec_initialRijTijEstimates_cpy.size(); ++i) { openMVG::relativeInfo & rel = vec_initialRijTijEstimates_cpy[i]; @@ -639,6 +639,6 @@ bool GlobalSfM_Translation_AveragingSolver::Estimate_T_triplet( return bTest; } - -} // namespace globalSfM +} // namespace sfm } // namespace openMVG + diff --git a/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.hpp b/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.hpp index 93f0bb2f6e..a9c440c1e9 100644 --- a/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.hpp +++ b/src/openMVG/sfm/pipelines/global/GlobalSfM_translation_averaging.hpp @@ -9,7 +9,7 @@ #define OPENMVG_SFM_GLOBAL_ENGINE_PIPELINES_GLOBAL_TRANSLATION_AVERAGING_HPP namespace openMVG{ -namespace globalSfM{ +namespace sfm{ enum ETranslationAveragingMethod { @@ -17,8 +17,8 @@ enum ETranslationAveragingMethod TRANSLATION_AVERAGING_L2 = 2 }; -} -} +} // namespace sfm +} // namespace openMVG #include "openMVG/sfm/sfm_data.hpp" #include "openMVG/multiview/translation_averaging_common.hpp" @@ -28,7 +28,7 @@ enum ETranslationAveragingMethod #include "openMVG/graph/graph.hpp" namespace openMVG{ -namespace globalSfM{ +namespace sfm{ class GlobalSfM_Translation_AveragingSolver { @@ -87,7 +87,7 @@ class GlobalSfM_Translation_AveragingSolver const std::string & sOutDirectory) const; }; -} // namespace globalSfM +} // namespace sfm } // namespace openMVG #endif // OPENMVG_SFM_GLOBAL_ENGINE_PIPELINES_GLOBAL_TRANSLATION_AVERAGING_HPP diff --git a/src/openMVG/sfm/pipelines/global/global_SfM_test.cpp b/src/openMVG/sfm/pipelines/global/global_SfM_test.cpp index 9510c5e143..d4dd137336 100644 --- a/src/openMVG/sfm/pipelines/global/global_SfM_test.cpp +++ b/src/openMVG/sfm/pipelines/global/global_SfM_test.cpp @@ -22,6 +22,7 @@ using namespace openMVG; using namespace openMVG::cameras; using namespace openMVG::geometry; +using namespace openMVG::sfm; #include "testing/testing.h" @@ -68,8 +69,8 @@ TEST(GLOBAL_SFM, RotationAveragingL2_TranslationAveragingL1) { sfmEngine.Set_bFixedIntrinsics(true); // Configure motion averaging method - sfmEngine.SetRotationAveragingMethod(globalSfM::ROTATION_AVERAGING_L2); - sfmEngine.SetTranslationAveragingMethod(globalSfM::TRANSLATION_AVERAGING_L1); + sfmEngine.SetRotationAveragingMethod(ROTATION_AVERAGING_L2); + sfmEngine.SetTranslationAveragingMethod(TRANSLATION_AVERAGING_L1); EXPECT_TRUE (sfmEngine.Process()); @@ -119,8 +120,8 @@ TEST(GLOBAL_SFM, RotationAveragingL1_TranslationAveragingL1) { sfmEngine.Set_bFixedIntrinsics(true); // Configure motion averaging method - sfmEngine.SetRotationAveragingMethod(globalSfM::ROTATION_AVERAGING_L1); - sfmEngine.SetTranslationAveragingMethod(globalSfM::TRANSLATION_AVERAGING_L1); + sfmEngine.SetRotationAveragingMethod(ROTATION_AVERAGING_L1); + sfmEngine.SetTranslationAveragingMethod(TRANSLATION_AVERAGING_L1); EXPECT_TRUE (sfmEngine.Process()); @@ -170,8 +171,8 @@ TEST(GLOBAL_SFM, RotationAveragingL2_TranslationAveragingL2) { sfmEngine.Set_bFixedIntrinsics(true); // Configure motion averaging method - sfmEngine.SetRotationAveragingMethod(globalSfM::ROTATION_AVERAGING_L2); - sfmEngine.SetTranslationAveragingMethod(globalSfM::TRANSLATION_AVERAGING_L2); + sfmEngine.SetRotationAveragingMethod(ROTATION_AVERAGING_L2); + sfmEngine.SetTranslationAveragingMethod(TRANSLATION_AVERAGING_L2); EXPECT_TRUE (sfmEngine.Process()); diff --git a/src/openMVG/sfm/pipelines/global/mutexSet.hpp b/src/openMVG/sfm/pipelines/global/mutexSet.hpp index 95a7793c0c..735da57be2 100644 --- a/src/openMVG/sfm/pipelines/global/mutexSet.hpp +++ b/src/openMVG/sfm/pipelines/global/mutexSet.hpp @@ -21,6 +21,7 @@ typedef tthread::lock_guard lock_guardT; #endif namespace openMVG { +namespace sfm{ /// ThreadSafe Set thanks to a mutex template @@ -47,4 +48,5 @@ class MutexSet { mutable mutexT m_Mutex; }; -}; // namespace openMVG +} // namespace sfm +} // namespace openMVG diff --git a/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp b/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp index 25aafe277e..7d74854975 100644 --- a/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp +++ b/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp @@ -21,6 +21,7 @@ #endif namespace openMVG{ +namespace sfm{ using namespace openMVG::cameras; using namespace openMVG::geometry; @@ -46,8 +47,8 @@ GlobalSfMReconstructionEngine_RelativeMotions::GlobalSfMReconstructionEngine_Rel } // Set default motion Averaging methods - _eRotationAveragingMethod = globalSfM::ROTATION_AVERAGING_L2; - _eTranslationAveragingMethod = globalSfM::TRANSLATION_AVERAGING_L1; + _eRotationAveragingMethod = ROTATION_AVERAGING_L2; + _eTranslationAveragingMethod = TRANSLATION_AVERAGING_L1; } GlobalSfMReconstructionEngine_RelativeMotions::~GlobalSfMReconstructionEngine_RelativeMotions() @@ -89,7 +90,7 @@ void GlobalSfMReconstructionEngine_RelativeMotions::SetMatchesProvider(Matches_P void GlobalSfMReconstructionEngine_RelativeMotions::SetRotationAveragingMethod ( - globalSfM::ERotationAveragingMethod eRotationAveragingMethod + ERotationAveragingMethod eRotationAveragingMethod ) { _eRotationAveragingMethod = eRotationAveragingMethod; @@ -97,7 +98,7 @@ void GlobalSfMReconstructionEngine_RelativeMotions::SetRotationAveragingMethod void GlobalSfMReconstructionEngine_RelativeMotions::SetTranslationAveragingMethod ( - globalSfM::ETranslationAveragingMethod eTranslationAveragingMethod + ETranslationAveragingMethod eTranslationAveragingMethod ) { _eTranslationAveragingMethod = eTranslationAveragingMethod; @@ -237,10 +238,9 @@ bool GlobalSfMReconstructionEngine_RelativeMotions::Compute_Global_Rotations() } // Global Rotation solver: - using namespace openMVG::globalSfM; - globalSfM::ERelativeRotationInferenceMethod eRelativeRotationInferenceMethod = globalSfM::TRIPLET_ROTATION_INFERENCE_COMPOSITION_ERROR; + ERelativeRotationInferenceMethod eRelativeRotationInferenceMethod = TRIPLET_ROTATION_INFERENCE_COMPOSITION_ERROR; - globalSfM::GlobalSfM_Rotation_AveragingSolver rotation_averaging_solver; + GlobalSfM_Rotation_AveragingSolver rotation_averaging_solver; const bool bRotationAveraging = rotation_averaging_solver.Run( _eRotationAveragingMethod, eRelativeRotationInferenceMethod, vec_relativeRotEstimate, _map_globalR); @@ -252,7 +252,7 @@ bool GlobalSfMReconstructionEngine_RelativeMotions::Compute_Global_Rotations() bool GlobalSfMReconstructionEngine_RelativeMotions::Compute_Global_Translations() { // Translation averaging (compute translations & update them to a global common coordinates system) - globalSfM::GlobalSfM_Translation_AveragingSolver translation_averaging_solver; + GlobalSfM_Translation_AveragingSolver translation_averaging_solver; const bool bTranslationAveraging = translation_averaging_solver.Run( _eTranslationAveragingMethod, _sfm_data, @@ -565,4 +565,6 @@ void GlobalSfMReconstructionEngine_RelativeMotions::Compute_Relative_Rotations(R } } +} // namespace sfm } // namespace openMVG + diff --git a/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.hpp b/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.hpp index cfebf308ce..bd10267d29 100644 --- a/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.hpp +++ b/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.hpp @@ -15,6 +15,7 @@ #include "third_party/htmlDoc/htmlDoc.hpp" namespace openMVG{ +namespace sfm{ /// Global SfM Pipeline Reconstruction Engine. /// - Method: Global Fusion of Relative Motions. @@ -32,8 +33,8 @@ class GlobalSfMReconstructionEngine_RelativeMotions : public ReconstructionEngin void SetFeaturesProvider(Features_Provider * provider); void SetMatchesProvider(Matches_Provider * provider); - void SetRotationAveragingMethod(globalSfM::ERotationAveragingMethod eRotationAveragingMethod); - void SetTranslationAveragingMethod(globalSfM::ETranslationAveragingMethod _eTranslationAveragingMethod); + void SetRotationAveragingMethod(ERotationAveragingMethod eRotationAveragingMethod); + void SetTranslationAveragingMethod(ETranslationAveragingMethod _eTranslationAveragingMethod); virtual bool Process(); @@ -63,8 +64,8 @@ class GlobalSfMReconstructionEngine_RelativeMotions : public ReconstructionEngin std::string _sLoggingFile; // Parameter - globalSfM::ERotationAveragingMethod _eRotationAveragingMethod; - globalSfM::ETranslationAveragingMethod _eTranslationAveragingMethod; + ERotationAveragingMethod _eRotationAveragingMethod; + ETranslationAveragingMethod _eTranslationAveragingMethod; //-- Data provider Features_Provider * _features_provider; @@ -79,6 +80,7 @@ class GlobalSfMReconstructionEngine_RelativeMotions : public ReconstructionEngin }; +} // namespace sfm } // namespace openMVG #endif // OPENMVG_SFM_GLOBAL_ENGINE_RELATIVE_MOTIONS_HPP diff --git a/src/openMVG/sfm/pipelines/global/sfm_global_reindex.hpp b/src/openMVG/sfm/pipelines/global/sfm_global_reindex.hpp index 59256617d1..071a1d4e9f 100644 --- a/src/openMVG/sfm/pipelines/global/sfm_global_reindex.hpp +++ b/src/openMVG/sfm/pipelines/global/sfm_global_reindex.hpp @@ -8,6 +8,7 @@ #define OPENMVG_SFM_GLOBAL_REINDEX_HPP namespace openMVG { +namespace sfm{ /// Association of Ids to a contiguous set of Ids template @@ -45,6 +46,7 @@ void reindex( } } +} // namespace sfm } // namespace openMVG #endif // OPENMVG_SFM_GLOBAL_REINDEX_HPP diff --git a/src/openMVG/sfm/pipelines/global/triplet_t_ACRansac_kernelAdaptator.hpp b/src/openMVG/sfm/pipelines/global/triplet_t_ACRansac_kernelAdaptator.hpp index 9c940fcfc6..07674b4a8e 100644 --- a/src/openMVG/sfm/pipelines/global/triplet_t_ACRansac_kernelAdaptator.hpp +++ b/src/openMVG/sfm/pipelines/global/triplet_t_ACRansac_kernelAdaptator.hpp @@ -15,6 +15,7 @@ #include "openMVG/robust_estimation/robust_estimator_ACRansac.hpp" namespace openMVG{ +namespace sfm{ using namespace openMVG::trifocal::kernel; @@ -98,6 +99,7 @@ class TranslationTripletKernel_ACRansac }; +} // namespace sfm } // namespace openMVG #endif // OPENMVG_GLOBAL_SFM_ENGINE_TRIPLET_T_ESTIMATOR_H diff --git a/src/openMVG/sfm/pipelines/pipelines_test.hpp b/src/openMVG/sfm/pipelines/pipelines_test.hpp index 09aa5a3652..9dc2c3b48e 100644 --- a/src/openMVG/sfm/pipelines/pipelines_test.hpp +++ b/src/openMVG/sfm/pipelines/pipelines_test.hpp @@ -8,6 +8,7 @@ #include "openMVG/multiview/test_data_sets.hpp" #include "openMVG/sfm/sfm.hpp" using namespace openMVG; +using namespace openMVG::sfm; #include #include diff --git a/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp b/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp index dd445efb8e..fec2e7b3fe 100644 --- a/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp +++ b/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp @@ -27,7 +27,8 @@ #pragma warning( once : 4267 ) //warning C4267: 'argument' : conversion from 'size_t' to 'const int', possible loss of data #endif -namespace openMVG{ +namespace openMVG { +namespace sfm { using namespace openMVG::geometry; using namespace openMVG::cameras; @@ -1078,5 +1079,6 @@ size_t SequentialSfMReconstructionEngine::badTrackRejector(double dPrecision) RemoveOutliers_AngleError(_sfm_data, 2.0); } +} // namespace sfm } // namespace openMVG diff --git a/src/openMVG/sfm/pipelines/sequential/sequential_SfM.hpp b/src/openMVG/sfm/pipelines/sequential/sequential_SfM.hpp index 8393a54994..869ae5db53 100644 --- a/src/openMVG/sfm/pipelines/sequential/sequential_SfM.hpp +++ b/src/openMVG/sfm/pipelines/sequential/sequential_SfM.hpp @@ -15,7 +15,8 @@ #include "third_party/htmlDoc/htmlDoc.hpp" #include "third_party/histogram/histogram.hpp" -namespace openMVG{ +namespace openMVG { +namespace sfm { /// Sequential SfM Pipeline Reconstruction Engine. class SequentialSfMReconstructionEngine : public ReconstructionEngine @@ -99,4 +100,6 @@ class SequentialSfMReconstructionEngine : public ReconstructionEngine std::set _set_remainingViewId; // Remaining camera index that can be used for resection }; +} // namespace sfm } // namespace openMVG + diff --git a/src/openMVG/sfm/pipelines/sequential/sequential_SfM_test.cpp b/src/openMVG/sfm/pipelines/sequential/sequential_SfM_test.cpp index d94f05380b..c8d1ec7e6e 100644 --- a/src/openMVG/sfm/pipelines/sequential/sequential_SfM_test.cpp +++ b/src/openMVG/sfm/pipelines/sequential/sequential_SfM_test.cpp @@ -22,6 +22,7 @@ using namespace openMVG; using namespace openMVG::cameras; using namespace openMVG::geometry; +using namespace openMVG::sfm; #include "testing/testing.h" diff --git a/src/openMVG/sfm/pipelines/sfm_engine.hpp b/src/openMVG/sfm/pipelines/sfm_engine.hpp index 83f2150ff7..bf39e67ee5 100644 --- a/src/openMVG/sfm/pipelines/sfm_engine.hpp +++ b/src/openMVG/sfm/pipelines/sfm_engine.hpp @@ -10,7 +10,8 @@ #include "openMVG/sfm/sfm_data.hpp" #include -namespace openMVG{ +namespace openMVG { +namespace sfm { /// Basic Reconstruction Engine. /// Process Function handle the reconstruction. @@ -47,4 +48,6 @@ class ReconstructionEngine //----- bool _bFixedIntrinsics; }; + +} // namespace sfm } // namespace openMVG diff --git a/src/openMVG/sfm/pipelines/sfm_features_provider.hpp b/src/openMVG/sfm/pipelines/sfm_features_provider.hpp index 57e89517e0..a48977a4b8 100644 --- a/src/openMVG/sfm/pipelines/sfm_features_provider.hpp +++ b/src/openMVG/sfm/pipelines/sfm_features_provider.hpp @@ -15,7 +15,8 @@ #include -namespace openMVG{ +namespace openMVG { +namespace sfm { /// Abstract PointFeature provider (read some feature and store them as PointFeature). /// Allow to load and return the features related to a view @@ -95,6 +96,7 @@ struct Features_Provider } }; // Features_Provider +} // namespace sfm } // namespace openMVG #endif // OPENMVG_SFM_FEATURES_PROVIDER_HPP diff --git a/src/openMVG/sfm/pipelines/sfm_matches_provider.hpp b/src/openMVG/sfm/pipelines/sfm_matches_provider.hpp index 482e59bfd2..8cb3de58a7 100644 --- a/src/openMVG/sfm/pipelines/sfm_matches_provider.hpp +++ b/src/openMVG/sfm/pipelines/sfm_matches_provider.hpp @@ -12,7 +12,8 @@ #include "openMVG/matching/indMatch.hpp" #include -namespace openMVG{ +namespace openMVG { +namespace sfm { /// Return the matches loaded from a provided matches file struct Matches_Provider @@ -58,6 +59,7 @@ struct Matches_Provider } }; // Features_Provider +} // namespace sfm } // namespace openMVG #endif // OPENMVG_SFM_MATCHES_PROVIDER_HPP diff --git a/src/openMVG/sfm/pipelines/sfm_regions_provider.hpp b/src/openMVG/sfm/pipelines/sfm_regions_provider.hpp index 84eca40812..9ccbb74735 100644 --- a/src/openMVG/sfm/pipelines/sfm_regions_provider.hpp +++ b/src/openMVG/sfm/pipelines/sfm_regions_provider.hpp @@ -16,7 +16,8 @@ #include -namespace openMVG{ +namespace openMVG { +namespace sfm { /// Abstract Regions provider /// Allow to load and return the regions related to a view @@ -84,6 +85,7 @@ struct Regions_Provider }; // Regions_Provider +} // namespace sfm } // namespace openMVG #endif // OPENMVG_SFM_REGIONS_PROVIDER_HPP diff --git a/src/openMVG/sfm/pipelines/sfm_robust_model_estimation.cpp b/src/openMVG/sfm/pipelines/sfm_robust_model_estimation.cpp index 1a8cab2ad1..d7c6bdd367 100644 --- a/src/openMVG/sfm/pipelines/sfm_robust_model_estimation.cpp +++ b/src/openMVG/sfm/pipelines/sfm_robust_model_estimation.cpp @@ -19,8 +19,8 @@ #include "openMVG/robust_estimation/robust_estimator_ACRansac.hpp" #include "openMVG/robust_estimation/robust_estimator_ACRansacKernelAdaptator.hpp" -namespace openMVG -{ +namespace openMVG { +namespace sfm { bool estimate_Rt_fromE(const Mat3 & K1, const Mat3 & K2, const Mat & x1, const Mat & x2, @@ -187,5 +187,6 @@ bool robustResection( return false; } +} // namespace sfm } // namespace openMVG diff --git a/src/openMVG/sfm/pipelines/sfm_robust_model_estimation.hpp b/src/openMVG/sfm/pipelines/sfm_robust_model_estimation.hpp index c06bdfd356..f870fe451f 100644 --- a/src/openMVG/sfm/pipelines/sfm_robust_model_estimation.hpp +++ b/src/openMVG/sfm/pipelines/sfm_robust_model_estimation.hpp @@ -12,8 +12,8 @@ #include "openMVG/geometry/pose3.hpp" #include -namespace openMVG -{ +namespace openMVG { +namespace sfm { /** * @brief Estimate the best possible Rotation/Translation from E. @@ -92,6 +92,7 @@ bool robustResection( const size_t max_iteration = 4096); +} // namespace sfm } // namespace openMVG #endif // OPENMVG_SFM_ROBUST_MODEL_ESTIMATION_HPP diff --git a/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.cpp b/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.cpp index d754388763..6922b58f8d 100644 --- a/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.cpp +++ b/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.cpp @@ -17,11 +17,13 @@ #include "third_party/progress/progress.hpp" namespace openMVG { +namespace sfm { using namespace openMVG::cameras; using namespace openMVG::features; using namespace openMVG::geometry; + /// Camera pair epipole (Projection of camera center 2 in the image plane 1) static Vec3 epipole_from_P(const Mat34& P1, const Pose3& P2) { @@ -323,4 +325,6 @@ void SfM_Data_Structure_Estimation_From_Known_Poses::triangulate( structure_estimator.triangulate(sfm_data); } +} // namespace sfm } // namespace openMVG + diff --git a/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.hpp b/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.hpp index b8a723a943..a2ca5a7230 100644 --- a/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.hpp +++ b/src/openMVG/sfm/pipelines/structure_from_known_poses/structure_estimator.hpp @@ -10,6 +10,7 @@ #include "openMVG/matching/indMatch.hpp" namespace openMVG { +namespace sfm { class SfM_Data_Structure_Estimation_From_Known_Poses { @@ -48,4 +49,6 @@ class SfM_Data_Structure_Estimation_From_Known_Poses matching::PairWiseMatches triplets_matches; }; +} // namespace sfm } // namespace openMVG + diff --git a/src/openMVG/sfm/sfm_data.hpp b/src/openMVG/sfm/sfm_data.hpp index 5769edd506..96d890634f 100644 --- a/src/openMVG/sfm/sfm_data.hpp +++ b/src/openMVG/sfm/sfm_data.hpp @@ -14,6 +14,7 @@ #include "openMVG/cameras/cameras.hpp" namespace openMVG { +namespace sfm { /// Define a collection of View typedef Hash_Map > Views; @@ -69,6 +70,7 @@ struct SfM_Data } }; +} // namespace sfm } // namespace openMVG #endif // OPENMVG_SFM_DATA_HPP diff --git a/src/openMVG/sfm/sfm_data_BA.hpp b/src/openMVG/sfm/sfm_data_BA.hpp index 8e7ab4b544..750dea510e 100644 --- a/src/openMVG/sfm/sfm_data_BA.hpp +++ b/src/openMVG/sfm/sfm_data_BA.hpp @@ -8,6 +8,7 @@ #define OPENMVG_SFM_DATA_BA_HPP namespace openMVG { +namespace sfm { class Bundle_Adjustment { @@ -24,6 +25,7 @@ class Bundle_Adjustment // TODO: Use filter to say wich parameter is const or not (allow to refine only a subpart of the intrinsics or the poses) }; +} // namespace sfm } // namespace openMVG #endif // OPENMVG_SFM_DATA_BA_HPP diff --git a/src/openMVG/sfm/sfm_data_BA_ceres.cpp b/src/openMVG/sfm/sfm_data_BA_ceres.cpp index eed22b8fda..37b9adfe22 100644 --- a/src/openMVG/sfm/sfm_data_BA_ceres.cpp +++ b/src/openMVG/sfm/sfm_data_BA_ceres.cpp @@ -9,6 +9,7 @@ #include "ceres/rotation.h" namespace openMVG { +namespace sfm { using namespace openMVG::cameras; using namespace openMVG::geometry; @@ -261,5 +262,6 @@ bool Bundle_Adjustment_Ceres::Adjust( } } +} // namespace sfm } // namespace openMVG diff --git a/src/openMVG/sfm/sfm_data_BA_ceres.hpp b/src/openMVG/sfm/sfm_data_BA_ceres.hpp index 413e970326..3bfe6c8af1 100644 --- a/src/openMVG/sfm/sfm_data_BA_ceres.hpp +++ b/src/openMVG/sfm/sfm_data_BA_ceres.hpp @@ -13,6 +13,7 @@ #include "ceres/ceres.h" namespace openMVG { +namespace sfm { /// Create the appropriate cost functor according the provided input camera intrinsic model ceres::CostFunction * IntrinsicsToCostFunction( @@ -46,6 +47,8 @@ class Bundle_Adjustment_Ceres : public Bundle_Adjustment bool bRefineIntrinsics = true, // tell if the camera intrinsic will be refined bool bRefineStructure = true); // tell if the structure will be refined }; + +} // namespace sfm } // namespace openMVG #endif // OPENMVG_SFM_DATA_BA_CERES_HPP diff --git a/src/openMVG/sfm/sfm_data_BA_ceres_camera_functor.hpp b/src/openMVG/sfm/sfm_data_BA_ceres_camera_functor.hpp index 2b43411941..41c7fb9318 100644 --- a/src/openMVG/sfm/sfm_data_BA_ceres_camera_functor.hpp +++ b/src/openMVG/sfm/sfm_data_BA_ceres_camera_functor.hpp @@ -15,6 +15,7 @@ //-- namespace openMVG { +namespace sfm { /** * @brief Ceres functor to use a Pinhole_Intrinsic (pinhole camera model K[R[t]) and a 3D points. @@ -287,7 +288,7 @@ struct ResidualErrorFunctor_Pinhole_Intrinsic_Radial_K3 double m_pos_2dpoint[2]; // The 2D observation }; - +} // namespace sfm } // namespace openMVG #endif // OPENMVG_SFM_DATA_BA_CERES_CAMERA_FUNCTOR_HPP diff --git a/src/openMVG/sfm/sfm_data_BA_test.cpp b/src/openMVG/sfm/sfm_data_BA_test.cpp index f48f16a3ba..c611a6076f 100644 --- a/src/openMVG/sfm/sfm_data_BA_test.cpp +++ b/src/openMVG/sfm/sfm_data_BA_test.cpp @@ -20,6 +20,7 @@ using namespace openMVG; using namespace openMVG::cameras; using namespace openMVG::geometry; +using namespace openMVG::sfm; #include "testing/testing.h" diff --git a/src/openMVG/sfm/sfm_data_filters.hpp b/src/openMVG/sfm/sfm_data_filters.hpp index 0df8855b26..9ca7b56b3b 100644 --- a/src/openMVG/sfm/sfm_data_filters.hpp +++ b/src/openMVG/sfm/sfm_data_filters.hpp @@ -12,6 +12,7 @@ #include namespace openMVG { +namespace sfm { /// List the view indexes that have valid camera intrinsic and pose. static std::set Get_Valid_Views @@ -235,6 +236,7 @@ static bool eraseUnstablePosesAndObservations( return remove_iteration > 0; } -}; // namespace openMVG +} // namespace sfm +} // namespace openMVG #endif // OPENMVG_SFM_DATA_FILTERS_HPP diff --git a/src/openMVG/sfm/sfm_data_filters_frustum.cpp b/src/openMVG/sfm/sfm_data_filters_frustum.cpp index f210785bb4..4b5f900103 100644 --- a/src/openMVG/sfm/sfm_data_filters_frustum.cpp +++ b/src/openMVG/sfm/sfm_data_filters_frustum.cpp @@ -13,6 +13,7 @@ #include namespace openMVG { +namespace sfm { using namespace openMVG::cameras; using namespace openMVG::geometry; @@ -234,5 +235,6 @@ void Frustum_Filter::init_z_near_z_far_depth(const SfM_Data & sfm_data, } } -}; // namespace openMVG +} // namespace sfm +} // namespace openMVG diff --git a/src/openMVG/sfm/sfm_data_filters_frustum.hpp b/src/openMVG/sfm/sfm_data_filters_frustum.hpp index be21823e7c..71d1a1b8c2 100644 --- a/src/openMVG/sfm/sfm_data_filters_frustum.hpp +++ b/src/openMVG/sfm/sfm_data_filters_frustum.hpp @@ -12,6 +12,7 @@ #include "openMVG/geometry/frustum.hpp" namespace openMVG { +namespace sfm { struct SfM_Data; @@ -50,7 +51,7 @@ class Frustum_Filter NearFarPlanesT z_near_z_far_perView; // Near & Far plane distance per view }; - -}; // namespace openMVG +} // namespace sfm +} // namespace openMVG #endif // OPENMVG_SFM_DATA_FILTERS_FRUSTUM_HPP diff --git a/src/openMVG/sfm/sfm_data_io.cpp b/src/openMVG/sfm/sfm_data_io.cpp index d1935ae599..32efa74620 100644 --- a/src/openMVG/sfm/sfm_data_io.cpp +++ b/src/openMVG/sfm/sfm_data_io.cpp @@ -16,6 +16,7 @@ #include "openMVG/sfm/sfm_data_io_baf.hpp" namespace openMVG { +namespace sfm { ///Check that each pose have a valid intrinsic and pose id in the existing View ids bool ValidIds(const SfM_Data & sfm_data, ESfM_Data flags_part) @@ -102,6 +103,7 @@ bool Save(const SfM_Data & sfm_data, const std::string & filename, ESfM_Data fla return false; } +} // namespace sfm } // namespace openMVG diff --git a/src/openMVG/sfm/sfm_data_io.hpp b/src/openMVG/sfm/sfm_data_io.hpp index 5b8683f33c..fee8c179ac 100644 --- a/src/openMVG/sfm/sfm_data_io.hpp +++ b/src/openMVG/sfm/sfm_data_io.hpp @@ -11,8 +11,8 @@ #include "openMVG/sfm/sfm_data.hpp" -namespace openMVG -{ +namespace openMVG { +namespace sfm { enum ESfM_Data { @@ -32,6 +32,7 @@ bool Load(SfM_Data & sfm_data, const std::string & filename, ESfM_Data flags_par /// Save SfM_Data SfM scene to a file bool Save(const SfM_Data & sfm_data, const std::string & filename, ESfM_Data flags_part); +} // namespace sfm } // namespace openMVG #endif // OPENMVG_SFM_DATA_IO_HPP diff --git a/src/openMVG/sfm/sfm_data_io_baf.hpp b/src/openMVG/sfm/sfm_data_io_baf.hpp index 9422300a08..a436cac6c2 100644 --- a/src/openMVG/sfm/sfm_data_io_baf.hpp +++ b/src/openMVG/sfm/sfm_data_io_baf.hpp @@ -11,8 +11,8 @@ #include "openMVG/sfm/sfm_data_io.hpp" #include -namespace openMVG -{ +namespace openMVG { +namespace sfm { /// Save SfM_Data in an ASCII BAF (Bundle Adjustment File). // --Header @@ -92,6 +92,7 @@ static bool Save_BAF( return bOk; } +} // namespace sfm } // namespace openMVG #endif // OPENMVG_SFM_DATA_IO_PLY_HPP diff --git a/src/openMVG/sfm/sfm_data_io_cereal.hpp b/src/openMVG/sfm/sfm_data_io_cereal.hpp index 2a7fc3db50..10084012ac 100644 --- a/src/openMVG/sfm/sfm_data_io_cereal.hpp +++ b/src/openMVG/sfm/sfm_data_io_cereal.hpp @@ -23,8 +23,8 @@ #include #include -namespace openMVG -{ +namespace openMVG { +namespace sfm { template < // JSONInputArchive/ ... @@ -149,6 +149,7 @@ bool Save_Cereal( return true; } +} // namespace sfm } // namespace openMVG #endif // OPENMVG_SFM_DATA_IO_CEREAL_HPP diff --git a/src/openMVG/sfm/sfm_data_io_ply.hpp b/src/openMVG/sfm/sfm_data_io_ply.hpp index 1e7f66012b..b810be8665 100644 --- a/src/openMVG/sfm/sfm_data_io_ply.hpp +++ b/src/openMVG/sfm/sfm_data_io_ply.hpp @@ -11,8 +11,8 @@ #include "openMVG/sfm/sfm_data_io.hpp" #include -namespace openMVG -{ +namespace openMVG { +namespace sfm { /// Save the structure and camera positions of a SfM_Data container as 3D points in a PLY ASCII file. static bool Save_PLY( @@ -72,6 +72,7 @@ static bool Save_PLY( return bOk; } +} // namespace sfm } // namespace openMVG #endif // OPENMVG_SFM_DATA_IO_PLY_HPP diff --git a/src/openMVG/sfm/sfm_data_io_test.cpp b/src/openMVG/sfm/sfm_data_io_test.cpp index 28478ef4f6..e498ea8444 100644 --- a/src/openMVG/sfm/sfm_data_io_test.cpp +++ b/src/openMVG/sfm/sfm_data_io_test.cpp @@ -14,6 +14,7 @@ using namespace openMVG; using namespace openMVG::cameras; using namespace openMVG::geometry; +using namespace openMVG::sfm; // Create a SfM scene with desired count of views & poses & intrinsic (shared or not) // Add a 3D point with observation in 2 view (just in order to have non empty data) diff --git a/src/openMVG/sfm/sfm_data_triangulation.cpp b/src/openMVG/sfm/sfm_data_triangulation.cpp index d2f7ed9e11..2736566db4 100644 --- a/src/openMVG/sfm/sfm_data_triangulation.cpp +++ b/src/openMVG/sfm/sfm_data_triangulation.cpp @@ -14,6 +14,7 @@ #include namespace openMVG { +namespace sfm { using namespace openMVG::geometry; using namespace openMVG::cameras; @@ -256,4 +257,5 @@ Vec3 SfM_Data_Structure_Computation_Robust::track_sample_triangulation( return trianObj.compute(); } +} // namespace sfm } // namespace openMVG diff --git a/src/openMVG/sfm/sfm_data_triangulation.hpp b/src/openMVG/sfm/sfm_data_triangulation.hpp index 2f9417cf89..702f5ca035 100644 --- a/src/openMVG/sfm/sfm_data_triangulation.hpp +++ b/src/openMVG/sfm/sfm_data_triangulation.hpp @@ -10,6 +10,7 @@ #include "openMVG/sfm/sfm_data.hpp" namespace openMVG { +namespace sfm { /// Generic basis struct for triangulation of track data contained /// in the SfM_Data scene structure. @@ -66,6 +67,7 @@ struct SfM_Data_Structure_Computation_Robust: public SfM_Data_Structure_Computat const std::set & samples) const; }; +} // namespace sfm } // namespace openMVG #endif // OPENMVG_SFM_DATA_TRIANGULATION_HPP diff --git a/src/openMVG/sfm/sfm_filters.hpp b/src/openMVG/sfm/sfm_filters.hpp index ad5e2ff297..3a68ef36cb 100644 --- a/src/openMVG/sfm/sfm_filters.hpp +++ b/src/openMVG/sfm/sfm_filters.hpp @@ -12,6 +12,7 @@ #include "openMVG/matching/indMatch.hpp" namespace openMVG { +namespace sfm { template static std::set getIndexes(const IterableIndexTSequence & seq) @@ -143,6 +144,7 @@ void KeepOnlyReferencedElement( relativeInfo_vec.swap(map_infered); } +} // namespace sfm } // namespace openMVG #endif // OPENMVG_SFM_FILTERS_HPP diff --git a/src/openMVG/sfm/sfm_landmark.hpp b/src/openMVG/sfm/sfm_landmark.hpp index a60689f11b..8560c382b8 100644 --- a/src/openMVG/sfm/sfm_landmark.hpp +++ b/src/openMVG/sfm/sfm_landmark.hpp @@ -11,6 +11,7 @@ #include // Serialization namespace openMVG { +namespace sfm { /// Define 3D-2D tracking data: 3D landmark with it's 2D observations struct Observation @@ -68,6 +69,7 @@ struct Landmark } }; +} // namespace sfm } // namespace openMVG #endif // OPENMVG_SFM_LANDMARK_HPP diff --git a/src/openMVG/sfm/sfm_report.hpp b/src/openMVG/sfm/sfm_report.hpp index e2fb8ea220..2e1b5b9782 100644 --- a/src/openMVG/sfm/sfm_report.hpp +++ b/src/openMVG/sfm/sfm_report.hpp @@ -13,6 +13,7 @@ #include "third_party/vectorGraphics/svgDrawer.hpp" namespace openMVG { +namespace sfm { static bool Generate_SfM_Report ( @@ -172,6 +173,7 @@ static bool Generate_SfM_Report return bOk; } +} // namespace sfm } // namespace openMVG #endif // OPENMVG_SFM_REPORT_HPP diff --git a/src/openMVG/sfm/sfm_view.hpp b/src/openMVG/sfm/sfm_view.hpp index 2353337ffb..d45991d0b4 100644 --- a/src/openMVG/sfm/sfm_view.hpp +++ b/src/openMVG/sfm/sfm_view.hpp @@ -11,6 +11,7 @@ #include // Serialization namespace openMVG { +namespace sfm { /// A view define an image by a string and unique indexes for the view, the camera intrinsic & the pose struct View @@ -59,6 +60,7 @@ struct View } }; +} // namespace sfm } // namespace openMVG #endif // OPENMVG_SFM_VIEW_HPP diff --git a/src/openMVG_Samples/robust_essential/robust_essential.cpp b/src/openMVG_Samples/robust_essential/robust_essential.cpp index 52c72b2f96..2a5a4035ed 100644 --- a/src/openMVG_Samples/robust_essential/robust_essential.cpp +++ b/src/openMVG_Samples/robust_essential/robust_essential.cpp @@ -157,8 +157,8 @@ int main() { //B. Compute the relative pose thanks to a essential matrix estimation std::pair size_imaL(imageL.Width(), imageL.Height()); std::pair size_imaR(imageR.Width(), imageR.Height()); - RelativePose_Info relativePose_info; - if (!robustRelativePose(K, K, xL, xR, relativePose_info, size_imaL, size_imaR, 256)) + sfm::RelativePose_Info relativePose_info; + if (!sfm::robustRelativePose(K, K, xL, xR, relativePose_info, size_imaL, size_imaR, 256)) { std::cerr << " /!\\ Robust relative pose estimation failure." << std::endl; diff --git a/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp b/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp index 672ec10e83..d06a42e3c8 100644 --- a/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp +++ b/src/openMVG_Samples/robust_essential_ba/robust_essential_ba.cpp @@ -30,6 +30,7 @@ using namespace openMVG::image; using namespace openMVG::matching; using namespace openMVG::cameras; using namespace openMVG::geometry; +using namespace openMVG::sfm; using namespace svg; using namespace std; diff --git a/src/software/SfM/main_ComputeFeatures.cpp b/src/software/SfM/main_ComputeFeatures.cpp index f08bb359af..99995a2eb3 100644 --- a/src/software/SfM/main_ComputeFeatures.cpp +++ b/src/software/SfM/main_ComputeFeatures.cpp @@ -24,6 +24,8 @@ using namespace openMVG; using namespace openMVG::image; +using namespace openMVG::features; +using namespace openMVG::sfm; using namespace std; features::EDESCRIBER_PRESET stringToEnum(const std::string & sPreset) diff --git a/src/software/SfM/main_ComputeFeatures_OpenCV.cpp b/src/software/SfM/main_ComputeFeatures_OpenCV.cpp index 80c91e5ced..9476929b9f 100644 --- a/src/software/SfM/main_ComputeFeatures_OpenCV.cpp +++ b/src/software/SfM/main_ComputeFeatures_OpenCV.cpp @@ -28,6 +28,8 @@ using namespace openMVG; using namespace openMVG::image; +using namespace openMVG::features; +using namespace openMVG::sfm; using namespace std; enum eGeometricModel @@ -50,7 +52,6 @@ enum ePairMode //--/!\ If you use a new Regions type you define and register it in // "openMVG/features/regions_factory.hpp" file. /// -using namespace openMVG::features; // Reuse the existing AKAZE floating point Keypoint. typedef features::AKAZE_Float_Regions AKAZE_OpenCV_Regions; // Define the Interface diff --git a/src/software/SfM/main_ComputeMatches.cpp b/src/software/SfM/main_ComputeMatches.cpp index 1d901ba891..046b071823 100644 --- a/src/software/SfM/main_ComputeMatches.cpp +++ b/src/software/SfM/main_ComputeMatches.cpp @@ -29,9 +29,10 @@ #include using namespace openMVG; +using namespace openMVG::cameras; using namespace openMVG::matching; using namespace openMVG::robust; -using namespace openMVG::cameras; +using namespace openMVG::sfm; using namespace std; enum EGeometricModel diff --git a/src/software/SfM/main_ComputeSfM_DataColor.cpp b/src/software/SfM/main_ComputeSfM_DataColor.cpp index 3d5ad26d6c..e20727b009 100644 --- a/src/software/SfM/main_ComputeSfM_DataColor.cpp +++ b/src/software/SfM/main_ComputeSfM_DataColor.cpp @@ -15,6 +15,7 @@ using namespace openMVG; using namespace openMVG::image; +using namespace openMVG::sfm; /// Find the color of the SfM_Data Landmarks/structure void ColorizeTracks( diff --git a/src/software/SfM/main_ComputeStructureFromKnownPoses.cpp b/src/software/SfM/main_ComputeStructureFromKnownPoses.cpp index 9542b7fbfc..34e350e3ee 100644 --- a/src/software/SfM/main_ComputeStructureFromKnownPoses.cpp +++ b/src/software/SfM/main_ComputeStructureFromKnownPoses.cpp @@ -13,6 +13,7 @@ #include "third_party/stlplus3/filesystemSimplified/file_system.hpp" using namespace openMVG; +using namespace openMVG::sfm; /// Build a list of pair from the camera frusta intersections Pair_Set BuildPairsFromFrustumsIntersections( diff --git a/src/software/SfM/main_ConvertList.cpp b/src/software/SfM/main_ConvertList.cpp index f7626e020c..3448e4b487 100644 --- a/src/software/SfM/main_ConvertList.cpp +++ b/src/software/SfM/main_ConvertList.cpp @@ -18,6 +18,7 @@ using namespace openMVG; using namespace openMVG::cameras; +using namespace openMVG::sfm; // Compatibility binary // Convert an openMVG v0.x=>7 lists.txt file to the new SfM_Data file format (v0.8) diff --git a/src/software/SfM/main_ConvertSfM_DataFormat.cpp b/src/software/SfM/main_ConvertSfM_DataFormat.cpp index b00da7a9c4..8d9ac6c5e4 100644 --- a/src/software/SfM/main_ConvertSfM_DataFormat.cpp +++ b/src/software/SfM/main_ConvertSfM_DataFormat.cpp @@ -13,6 +13,7 @@ #include using namespace openMVG; +using namespace openMVG::sfm; // Convert from a SfM_Data format to another int main(int argc, char **argv) diff --git a/src/software/SfM/main_ExportCameraFrustums.cpp b/src/software/SfM/main_ExportCameraFrustums.cpp index c9bf3a4514..72ca2bb839 100644 --- a/src/software/SfM/main_ExportCameraFrustums.cpp +++ b/src/software/SfM/main_ExportCameraFrustums.cpp @@ -12,6 +12,7 @@ #include "third_party/stlplus3/filesystemSimplified/file_system.hpp" using namespace openMVG; +using namespace openMVG::sfm; /// Export camera frustrums as a triangle PLY file int main(int argc, char **argv) diff --git a/src/software/SfM/main_FrustumFiltering.cpp b/src/software/SfM/main_FrustumFiltering.cpp index 54c029bf98..612bb65d3f 100644 --- a/src/software/SfM/main_FrustumFiltering.cpp +++ b/src/software/SfM/main_FrustumFiltering.cpp @@ -15,6 +15,7 @@ #include "third_party/stlplus3/filesystemSimplified/file_system.hpp" using namespace openMVG; +using namespace openMVG::sfm; /// Build a list of pair that share visibility content from the SfM_Data structure Pair_Set BuildPairsFromStructureObservations(const SfM_Data & sfm_data) diff --git a/src/software/SfM/main_GlobalSfM.cpp b/src/software/SfM/main_GlobalSfM.cpp index c048de524d..fa4735db37 100644 --- a/src/software/SfM/main_GlobalSfM.cpp +++ b/src/software/SfM/main_GlobalSfM.cpp @@ -8,10 +8,10 @@ #include #include "openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.hpp" -#include "software/SfM/io_regions_type.hpp" - #include "openMVG/system/timer.hpp" +#include "software/SfM/io_regions_type.hpp" using namespace openMVG; +using namespace openMVG::sfm; #include "third_party/cmdLine/cmdLine.h" #include "third_party/stlplus3/filesystemSimplified/file_system.hpp" @@ -70,14 +70,14 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - if (iRotationAveragingMethod < globalSfM::ROTATION_AVERAGING_L1 || - iRotationAveragingMethod > globalSfM::ROTATION_AVERAGING_L2 ) { + if (iRotationAveragingMethod < ROTATION_AVERAGING_L1 || + iRotationAveragingMethod > ROTATION_AVERAGING_L2 ) { std::cerr << "\n Rotation averaging method is invalid" << std::endl; return EXIT_FAILURE; } - if (iTranslationAveragingMethod < globalSfM::TRANSLATION_AVERAGING_L1 || - iTranslationAveragingMethod > globalSfM::TRANSLATION_AVERAGING_L2 ) { + if (iTranslationAveragingMethod < TRANSLATION_AVERAGING_L1 || + iTranslationAveragingMethod > TRANSLATION_AVERAGING_L2 ) { std::cerr << "\n Translation averaging method is invalid" << std::endl; return EXIT_FAILURE; } @@ -143,9 +143,9 @@ int main(int argc, char **argv) // Configure motion averaging method sfmEngine.SetRotationAveragingMethod( - globalSfM::ERotationAveragingMethod(iRotationAveragingMethod)); + ERotationAveragingMethod(iRotationAveragingMethod)); sfmEngine.SetTranslationAveragingMethod( - globalSfM::ETranslationAveragingMethod(iTranslationAveragingMethod)); + ETranslationAveragingMethod(iTranslationAveragingMethod)); if (sfmEngine.Process()) { diff --git a/src/software/SfM/main_IncrementalSfM.cpp b/src/software/SfM/main_IncrementalSfM.cpp index cafe3e5c18..1c7c40f794 100644 --- a/src/software/SfM/main_IncrementalSfM.cpp +++ b/src/software/SfM/main_IncrementalSfM.cpp @@ -8,11 +8,11 @@ #include #include "openMVG/sfm/sfm.hpp" -#include "software/SfM/io_regions_type.hpp" - #include "openMVG/system/timer.hpp" +#include "software/SfM/io_regions_type.hpp" using namespace openMVG; using namespace openMVG::cameras; +using namespace openMVG::sfm; #include "third_party/cmdLine/cmdLine.h" #include "third_party/stlplus3/filesystemSimplified/file_system.hpp" diff --git a/src/software/SfM/main_SfMInit_ImageListing.cpp b/src/software/SfM/main_SfMInit_ImageListing.cpp index 1ab532231b..d8b38e1717 100644 --- a/src/software/SfM/main_SfMInit_ImageListing.cpp +++ b/src/software/SfM/main_SfMInit_ImageListing.cpp @@ -26,7 +26,7 @@ using namespace openMVG; using namespace openMVG::cameras; using namespace openMVG::exif; using namespace openMVG::image; - +using namespace openMVG::sfm; /// Check that Kmatrix is a string like "f;0;ppx;0;f;ppy;0;0;1" /// With f,ppx,ppy as valid numerical value diff --git a/src/software/SfM/main_evalQuality.cpp b/src/software/SfM/main_evalQuality.cpp index 257ac843f6..387c527b54 100644 --- a/src/software/SfM/main_evalQuality.cpp +++ b/src/software/SfM/main_evalQuality.cpp @@ -19,6 +19,7 @@ #include using namespace openMVG; +using namespace openMVG::sfm; int main(int argc, char **argv) { diff --git a/src/software/SfM/main_exportKeypoints.cpp b/src/software/SfM/main_exportKeypoints.cpp index 7bb6e4dfbf..bf10ca99e7 100644 --- a/src/software/SfM/main_exportKeypoints.cpp +++ b/src/software/SfM/main_exportKeypoints.cpp @@ -24,6 +24,7 @@ using namespace openMVG; using namespace openMVG::matching; +using namespace openMVG::sfm; using namespace svg; diff --git a/src/software/SfM/main_exportMatches.cpp b/src/software/SfM/main_exportMatches.cpp index ae6720a8f4..07cc277a98 100644 --- a/src/software/SfM/main_exportMatches.cpp +++ b/src/software/SfM/main_exportMatches.cpp @@ -22,7 +22,9 @@ #include using namespace openMVG; +using namespace openMVG::features; using namespace openMVG::matching; +using namespace openMVG::sfm; using namespace svg; // Convert HUE color to RGB @@ -104,7 +106,6 @@ int main(int argc, char ** argv) // Load SfM Scene regions //--------------------------------------- // Init the regions_type from the image describer file (used for image regions extraction) - using namespace openMVG::features; const std::string sImage_describer = stlplus::create_filespec(sMatchesDir, "image_describer", "json"); std::unique_ptr regions_type = Init_region_type_from_file(sImage_describer); if (!regions_type) diff --git a/src/software/SfM/main_exportTracks.cpp b/src/software/SfM/main_exportTracks.cpp index 880e26ff40..433b5eef5d 100644 --- a/src/software/SfM/main_exportTracks.cpp +++ b/src/software/SfM/main_exportTracks.cpp @@ -21,6 +21,7 @@ using namespace openMVG; using namespace openMVG::matching; +using namespace openMVG::sfm; using namespace openMVG::tracks; using namespace svg; @@ -109,7 +110,7 @@ int main(int argc, char ** argv) tracksBuilder.Build(map_Matches); tracksBuilder.Filter(); tracksBuilder.ExportToSTL(map_tracks); -} + } // ------------ // For each pair, export the matches diff --git a/src/software/SfM/main_openMVG2CMPMVS.cpp b/src/software/SfM/main_openMVG2CMPMVS.cpp index 8206050edf..1a7501de8d 100644 --- a/src/software/SfM/main_openMVG2CMPMVS.cpp +++ b/src/software/SfM/main_openMVG2CMPMVS.cpp @@ -12,6 +12,7 @@ using namespace openMVG; using namespace openMVG::cameras; using namespace openMVG::geometry; using namespace openMVG::image; +using namespace openMVG::sfm; #include "third_party/cmdLine/cmdLine.h" #include "third_party/progress/progress.hpp" diff --git a/src/software/SfM/main_openMVG2MESHLAB.cpp b/src/software/SfM/main_openMVG2MESHLAB.cpp index 0a6f1c8f5c..d9ccdbbd49 100644 --- a/src/software/SfM/main_openMVG2MESHLAB.cpp +++ b/src/software/SfM/main_openMVG2MESHLAB.cpp @@ -13,6 +13,7 @@ using namespace openMVG; using namespace openMVG::cameras; using namespace openMVG::geometry; using namespace openMVG::image; +using namespace openMVG::sfm; #include "third_party/cmdLine/cmdLine.h" #include "third_party/stlplus3/filesystemSimplified/file_system.hpp" diff --git a/src/software/SfM/main_openMVG2PMVS.cpp b/src/software/SfM/main_openMVG2PMVS.cpp index da4b40dff6..1cdbd965b6 100644 --- a/src/software/SfM/main_openMVG2PMVS.cpp +++ b/src/software/SfM/main_openMVG2PMVS.cpp @@ -12,6 +12,7 @@ using namespace openMVG; using namespace openMVG::cameras; using namespace openMVG::geometry; using namespace openMVG::image; +using namespace openMVG::sfm; #include "third_party/cmdLine/cmdLine.h" #include "third_party/progress/progress.hpp" diff --git a/src/software/SfMViewer/main.cpp b/src/software/SfMViewer/main.cpp index 450a1fbf9b..191e1568c4 100644 --- a/src/software/SfMViewer/main.cpp +++ b/src/software/SfMViewer/main.cpp @@ -21,7 +21,8 @@ using namespace openMVG; using namespace openMVG::cameras; using namespace openMVG::geometry; -using namespace openMVG::image; +using namespace openMVG::image; +using namespace openMVG::sfm; static int running = 1; static SfM_Data sfm_data; diff --git a/src/software/colorHarmonize/colorHarmonizeEngineGlobal.cpp b/src/software/colorHarmonize/colorHarmonizeEngineGlobal.cpp index ef7dd3e513..ccedb37b30 100644 --- a/src/software/colorHarmonize/colorHarmonizeEngineGlobal.cpp +++ b/src/software/colorHarmonize/colorHarmonizeEngineGlobal.cpp @@ -45,7 +45,8 @@ namespace openMVG{ using namespace lemon; using namespace openMVG::image; using namespace openMVG::matching; -using namespace openMVG::lInfinity; +using namespace openMVG::lInfinity; +using namespace openMVG::sfm; typedef features::SIOPointFeature FeatureT; typedef vector< FeatureT > featsT; From f860ced341730f08214a11d1a63280809b8143b2 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Fri, 22 May 2015 09:08:24 +0200 Subject: [PATCH 22/52] Try back to compile with two thread on travis. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a30d2a70f4..0b99c0619d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ language: cpp compiler: - gcc - #- clang: #Consider clang later, since cereal does not build fine with clang + #- clang: #Consider clang later, since cereal does not build fine on the clang CI version # - "3.3" before_install: @@ -33,7 +33,7 @@ before_script: script: # limit GCC builds to a reduced number of thread for the virtual machine - - if [ "$CC" = "gcc" ]; then make; else make -j 2; fi + - make -j 2 # Perform unit tests only on GCC builds - if [ "$CC" = "gcc" ]; then make test; fi From f49419f092cd488b942acb9f4cc8c9781d6c8a7b Mon Sep 17 00:00:00 2001 From: pmoulon Date: Fri, 22 May 2015 10:08:23 +0200 Subject: [PATCH 23/52] [exif] do not reject bad terminated JPEG file. #303 --- .../SfM/main_SfMInit_ImageListing.cpp | 2 +- src/third_party/easyexif/exif.cpp | 110 +++++++++--------- src/third_party/easyexif/exif.h | 47 ++++---- 3 files changed, 84 insertions(+), 75 deletions(-) diff --git a/src/software/SfM/main_SfMInit_ImageListing.cpp b/src/software/SfM/main_SfMInit_ImageListing.cpp index d8b38e1717..eea05c5fa4 100644 --- a/src/software/SfM/main_SfMInit_ImageListing.cpp +++ b/src/software/SfM/main_SfMInit_ImageListing.cpp @@ -195,7 +195,7 @@ int main(int argc, char **argv) else continue; // image cannot be read - std::shared_ptr exifReader = std::make_shared(); + std::unique_ptr exifReader(new Exif_IO_EasyExif()); exifReader->open( sImageFilename ); // Consider the case where focal is provided manually diff --git a/src/third_party/easyexif/exif.cpp b/src/third_party/easyexif/exif.cpp index 0f3fda1482..62242374d2 100644 --- a/src/third_party/easyexif/exif.cpp +++ b/src/third_party/easyexif/exif.cpp @@ -1,6 +1,6 @@ #include /************************************************************************** - exif.cpp -- A simple ISO C++ library to parse basic EXIF + exif.cpp -- A simple ISO C++ library to parse basic EXIF information from a JPEG file. Copyright (c) 2010-2013 Mayank Lahiri @@ -9,24 +9,24 @@ See exif.h for version history. - Redistribution and use in source and binary forms, with or without + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -- Redistributions of source code must retain the above copyright notice, + -- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + -- Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include @@ -35,14 +35,14 @@ using std::string; namespace { - // IF Entry + // IF Entry struct IFEntry { // Raw fields unsigned short tag; unsigned short format; unsigned data; unsigned length; - + // Parsed fields string val_string; unsigned short val_16; @@ -53,28 +53,28 @@ namespace { // Helper functions unsigned int parse32(const unsigned char *buf, bool intel) { - if (intel) - return ((unsigned)buf[3]<<24) | - ((unsigned)buf[2]<<16) | - ((unsigned)buf[1]<<8) | + if (intel) + return ((unsigned)buf[3]<<24) | + ((unsigned)buf[2]<<16) | + ((unsigned)buf[1]<<8) | buf[0]; - return ((unsigned)buf[0]<<24) | - ((unsigned)buf[1]<<16) | - ((unsigned)buf[2]<<8) | + return ((unsigned)buf[0]<<24) | + ((unsigned)buf[1]<<16) | + ((unsigned)buf[2]<<8) | buf[3]; } unsigned short parse16(const unsigned char *buf, bool intel) { if (intel) return ((unsigned) buf[1]<<8) | buf[0]; - return ((unsigned) buf[0]<<8) | buf[1]; + return ((unsigned) buf[0]<<8) | buf[1]; } - string parseEXIFString(const unsigned char *buf, - const unsigned num_components, - const unsigned data, - const unsigned base, + string parseEXIFString(const unsigned char *buf, + const unsigned num_components, + const unsigned data, + const unsigned base, const unsigned len) { string value; if (num_components <= 4) @@ -97,10 +97,10 @@ namespace { return numerator/denominator; } - IFEntry parseIFEntry(const unsigned char *buf, - const unsigned offs, - const bool alignIntel, - const unsigned base, + IFEntry parseIFEntry(const unsigned char *buf, + const unsigned offs, + const bool alignIntel, + const unsigned base, const unsigned len) { IFEntry result; @@ -144,20 +144,22 @@ namespace { } // -// Locates the EXIF segment and parses it using parseFromEXIFSegment +// Locates the EXIF segment and parses it using parseFromEXIFSegment // int EXIFInfo::parseFrom(const unsigned char *buf, unsigned len) { // Sanity check: all JPEG files start with 0xFFD8 and end with 0xFFD9 // This check also ensures that the user has supplied a correct value for len. if (!buf || len < 4) return PARSE_EXIF_ERROR_NO_EXIF; + // JPEG file start check if (buf[0] != 0xFF || buf[1] != 0xD8) return PARSE_EXIF_ERROR_NO_JPEG; - if (buf[len-2] != 0xFF || buf[len-1] != 0xD9) - return PARSE_EXIF_ERROR_NO_JPEG; + // JPEG file end check +// if (buf[len-2] != 0xFF || buf[len-1] != 0xD9) +// return PARSE_EXIF_ERROR_NO_JPEG; clear(); - // Scan for EXIF header (bytes 0xFF 0xE1) and do a sanity check by + // Scan for EXIF header (bytes 0xFF 0xE1) and do a sanity check by // looking for bytes "Exif\0\0". The marker length data is in Motorola // byte order, which results in the 'false' parameter to parse16(). // The marker has to contain at least the TIFF header, otherwise the @@ -170,13 +172,13 @@ int EXIFInfo::parseFrom(const unsigned char *buf, unsigned len) { // ========= // 16 bytes unsigned offs = 0; // current offset into buffer - for (offs = 0; offs < len-1; offs++) - if (buf[offs] == 0xFF && buf[offs+1] == 0xE1) + for (offs = 0; offs < len-1; offs++) + if (buf[offs] == 0xFF && buf[offs+1] == 0xE1) break; if (offs + 4 > len) return PARSE_EXIF_ERROR_NO_EXIF; offs += 2; - unsigned short section_length = parse16(buf + offs, false); + unsigned short section_length = parse16(buf + offs, false); if (offs + section_length > len || section_length < 16) return PARSE_EXIF_ERROR_CORRUPT; offs += 2; @@ -203,11 +205,11 @@ int EXIFInfo::parseFromEXIFSegment(const unsigned char *buf, unsigned len) { if (!std::equal(buf, buf+6, "Exif\0\0")) return PARSE_EXIF_ERROR_NO_EXIF; offs += 6; - + // Now parsing the TIFF header. The first two bytes are either "II" or // "MM" for Intel or Motorola byte alignment. Sanity check by parsing // the unsigned short that follows, making sure it equals 0x2a. The - // last 4 bytes are an offset into the first IFD, which are added to + // last 4 bytes are an offset into the first IFD, which are added to // the global offset counter. For this block, we expect the following // minimum size: // 2 bytes: 'II' or 'MM' @@ -223,7 +225,7 @@ int EXIFInfo::parseFromEXIFSegment(const unsigned char *buf, unsigned len) { else { if(buf[offs] == 'M' && buf[offs+1] == 'M') alignIntel = false; - else + else return PARSE_EXIF_ERROR_UNKNOWN_BYTEALIGN; } this->ByteAlign = alignIntel; @@ -364,7 +366,7 @@ int EXIFInfo::parseFromEXIFSegment(const unsigned char *buf, unsigned len) { break; case 0x9204: - // Exposure bias value + // Exposure bias value if (result.format == 5) this->ExposureBiasValue = result.val_rational; break; @@ -455,13 +457,13 @@ int EXIFInfo::parseFromEXIFSegment(const unsigned char *buf, unsigned len) { case 2: // GPS latitude if (format == 5 && length == 3) { - this->GeoLocation.LatComponents.degrees = + this->GeoLocation.LatComponents.degrees = parseEXIFRational(buf + data + tiff_header_start, alignIntel); - this->GeoLocation.LatComponents.minutes = + this->GeoLocation.LatComponents.minutes = parseEXIFRational(buf + data + tiff_header_start + 8, alignIntel); - this->GeoLocation.LatComponents.seconds = + this->GeoLocation.LatComponents.seconds = parseEXIFRational(buf + data + tiff_header_start + 16, alignIntel); - this->GeoLocation.Latitude = + this->GeoLocation.Latitude = this->GeoLocation.LatComponents.degrees + this->GeoLocation.LatComponents.minutes / 60 + this->GeoLocation.LatComponents.seconds / 3600; @@ -480,13 +482,13 @@ int EXIFInfo::parseFromEXIFSegment(const unsigned char *buf, unsigned len) { case 4: // GPS longitude if (format == 5 && length == 3) { - this->GeoLocation.LonComponents.degrees = + this->GeoLocation.LonComponents.degrees = parseEXIFRational(buf + data + tiff_header_start, alignIntel); - this->GeoLocation.LonComponents.minutes = + this->GeoLocation.LonComponents.minutes = parseEXIFRational(buf + data + tiff_header_start + 8, alignIntel); - this->GeoLocation.LonComponents.seconds = + this->GeoLocation.LonComponents.seconds = parseEXIFRational(buf + data + tiff_header_start + 16, alignIntel); - this->GeoLocation.Longitude = + this->GeoLocation.Longitude = this->GeoLocation.LonComponents.degrees + this->GeoLocation.LonComponents.minutes / 60 + this->GeoLocation.LonComponents.seconds / 3600; @@ -505,7 +507,7 @@ int EXIFInfo::parseFromEXIFSegment(const unsigned char *buf, unsigned len) { case 6: // GPS altitude reference if (format == 5) { - this->GeoLocation.Altitude = + this->GeoLocation.Altitude = parseEXIFRational(buf + data + tiff_header_start, alignIntel); if (1 == this->GeoLocation.AltitudeRef) this->GeoLocation.Altitude = -this->GeoLocation.Altitude; @@ -527,13 +529,13 @@ void EXIFInfo::clear() { Software = ""; DateTime = ""; DateTimeOriginal = ""; - DateTimeDigitized = ""; + DateTimeDigitized = ""; SubSecTimeOriginal= ""; Copyright = ""; // Shorts / unsigned / double ByteAlign = 0; - Orientation = 0; + Orientation = 0; BitsPerSample = 0; ExposureTime = 0; diff --git a/src/third_party/easyexif/exif.h b/src/third_party/easyexif/exif.h index c0b736ade8..6de34b6216 100644 --- a/src/third_party/easyexif/exif.h +++ b/src/third_party/easyexif/exif.h @@ -1,5 +1,5 @@ /************************************************************************** - exif.h -- A simple ISO C++ library to parse basic EXIF + exif.h -- A simple ISO C++ library to parse basic EXIF information from a JPEG file. Based on the description of the EXIF file format at: @@ -28,25 +28,25 @@ -- added GPS support 1.0: Released 2010 - - Redistribution and use in source and binary forms, with or without + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -- Redistributions of source code must retain the above copyright notice, + -- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation + -- Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __EXIF_H @@ -54,7 +54,7 @@ #include -// +// // Class responsible for storing and parsing EXIF information from a JPEG blob // class EXIFInfo { @@ -69,7 +69,7 @@ class EXIFInfo { int parseFrom(const std::string &data); // Parsing function for an EXIF segment. This is used internally by parseFrom() - // but can be called for special cases where only the EXIF section is + // but can be called for special cases where only the EXIF section is // available (i.e., a blob starting with the bytes "Exif\0\0"). int parseFromEXIFSegment(const unsigned char *buf, unsigned len); @@ -77,7 +77,7 @@ class EXIFInfo { void clear(); // Data fields filled out by parseFrom() - char ByteAlign; // 0 = Motorola byte alignment, 1 = Intel + char ByteAlign; // 0 = Motorola byte alignment, 1 = Intel std::string ImageDescription; // Image description std::string Make; // Camera manufacturer's name std::string Model; // Camera model @@ -103,6 +103,13 @@ class EXIFInfo { double SubjectDistance; // Distance to focus point in meters double FocalLength; // Focal length of lens in millimeters unsigned short FocalLengthIn35mm; // Focal length in 35mm film + double FocalPlaneXResolution; // Indicates the number of pixels in the image width (X) direction per FocalPlaneResolutionUnit on the camera focal plane (may not exist) + double FocalPlaneYResolution; // Indicates the number of pixels in the image width (Y) direction per FocalPlaneResolutionUnit on the camera focal plane (may not exist) + unsigned short FocalPlaneResolutionUnit;// Indicates the unit for measuring FocalPlaneXResolution and FocalPlaneYResolution (may not exist) + // 0: unspecified in EXIF data + // 1: no absolute unit of measurement + // 2: inch + // 3: centimeter char Flash; // 0 = no flash, 1 = flash used unsigned short MeteringMode; // Metering mode // 1: average @@ -118,11 +125,11 @@ class EXIFInfo { double Altitude; // Altitude in meters, relative to sea level char AltitudeRef; // 0 = above sea level, -1 = below sea level struct Coord_t { - double degrees; + double degrees; double minutes; double seconds; char direction; - } LatComponents, LonComponents; // Latitude, Longitude expressed in deg/min/sec + } LatComponents, LonComponents; // Latitude, Longitude expressed in deg/min/sec } GeoLocation; EXIFInfo() { clear(); From bf5efb9cbb1f055b26522da269d55ff900c07362 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Fri, 22 May 2015 10:09:27 +0200 Subject: [PATCH 24/52] Add Motorola XT1033 camera model. --- src/software/SfM/cameraSensorWidth/cameraGenerated.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/software/SfM/cameraSensorWidth/cameraGenerated.txt b/src/software/SfM/cameraSensorWidth/cameraGenerated.txt index 591764489f..d9456eabc7 100644 --- a/src/software/SfM/cameraSensorWidth/cameraGenerated.txt +++ b/src/software/SfM/cameraSensorWidth/cameraGenerated.txt @@ -1551,6 +1551,7 @@ Minox;Minox DD1 Diamond;6.4 Minox;Minox DC 3311;7.11 Minox;Minox DC 2111;5.33 Minox;Minox DC 1311;5.33 +Motorola;XT1033;3.8 Nikon;Nikon Coolpix A;23.6 Nikon;Nikon Coolpix P330;7.53 Nikon;Nikon Coolpix L320;6.16 From f9d9c0ff13312c732295ca8fc8942ccd3805d0a8 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Fri, 22 May 2015 10:53:07 +0200 Subject: [PATCH 25/52] [sfm] Extend BAF file format. #304 --- src/openMVG/sfm/sfm_data_io_baf.hpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/openMVG/sfm/sfm_data_io_baf.hpp b/src/openMVG/sfm/sfm_data_io_baf.hpp index a436cac6c2..3fc12238c7 100644 --- a/src/openMVG/sfm/sfm_data_io_baf.hpp +++ b/src/openMVG/sfm/sfm_data_io_baf.hpp @@ -89,6 +89,26 @@ static bool Save_BAF( bOk = stream.good(); stream.close(); } + // Export View filenames as an imgList.txt file + { + const std::string sFile = stlplus::create_filespec( + stlplus::folder_part(filename), "imgList", "txt"); + + stream.open(sFile.c_str()); + if (!stream.is_open()) + return false; + for (Views::const_iterator iterV = sfm_data.GetViews().begin(); + iterV != sfm_data.GetViews().end(); + ++ iterV) + { + const std::string sView_filename = stlplus::create_filespec(sfm_data.s_root_path, + iterV->second->s_Img_path); + stream << sView_filename << "\n"; + } + stream.flush(); + bOk = stream.good(); + stream.close(); + } return bOk; } From d76a2808d85d622509e500493624406cd7f68666 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Fri, 22 May 2015 11:29:53 +0200 Subject: [PATCH 26/52] [software] Add a software to export undistorted images. #305 --- src/software/SfM/CMakeLists.txt | 8 ++ .../SfM/main_ExportUndistortedImages.cpp | 98 +++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 src/software/SfM/main_ExportUndistortedImages.cpp diff --git a/src/software/SfM/CMakeLists.txt b/src/software/SfM/CMakeLists.txt index f746f8bc66..4c1336da9f 100644 --- a/src/software/SfM/CMakeLists.txt +++ b/src/software/SfM/CMakeLists.txt @@ -110,6 +110,12 @@ ADD_EXECUTABLE(openMVG_main_exportTracks main_exportTracks.cpp) TARGET_LINK_LIBRARIES(openMVG_main_exportTracks ${OpenMVG_LIBS}) +# - Export undistorted images related to a sfm_data file +# +ADD_EXECUTABLE(openMVG_main_ExportUndistortedImages main_ExportUndistortedImages.cpp) +TARGET_LINK_LIBRARIES(openMVG_main_ExportUndistortedImages + ${OpenMVG_LIBS}) + # installation rules SET_PROPERTY(TARGET openMVG_main_exportKeypoints PROPERTY FOLDER OpenMVG/software) INSTALL(TARGETS openMVG_main_exportKeypoints DESTINATION bin/) @@ -117,6 +123,8 @@ SET_PROPERTY(TARGET openMVG_main_exportMatches PROPERTY FOLDER OpenMVG/software) INSTALL(TARGETS openMVG_main_exportMatches DESTINATION bin/) SET_PROPERTY(TARGET openMVG_main_exportTracks PROPERTY FOLDER OpenMVG/software) INSTALL(TARGETS openMVG_main_exportTracks DESTINATION bin/) +SET_PROPERTY(TARGET openMVG_main_ExportUndistortedImages PROPERTY FOLDER OpenMVG/software) +INSTALL(TARGETS openMVG_main_ExportUndistortedImages DESTINATION bin/) ### # SfM export to X diff --git a/src/software/SfM/main_ExportUndistortedImages.cpp b/src/software/SfM/main_ExportUndistortedImages.cpp new file mode 100644 index 0000000000..5865add90e --- /dev/null +++ b/src/software/SfM/main_ExportUndistortedImages.cpp @@ -0,0 +1,98 @@ + +// Copyright (c) 2015 Pierre MOULON. + +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "openMVG/sfm/sfm.hpp" +#include "openMVG/image/image.hpp" + +using namespace openMVG; +using namespace openMVG::cameras; +using namespace openMVG::geometry; +using namespace openMVG::image; +using namespace openMVG::sfm; + +#include "third_party/cmdLine/cmdLine.h" +#include "third_party/progress/progress.hpp" + +#include + +int main(int argc, char *argv[]) { + + CmdLine cmd; + std::string sSfM_Data_Filename; + std::string sOutDir = ""; + + cmd.add( make_option('i', sSfM_Data_Filename, "sfmdata") ); + cmd.add( make_option('o', sOutDir, "outdir") ); + + try { + if (argc == 1) throw std::string("Invalid command line parameter."); + cmd.process(argc, argv); + } catch(const std::string& s) { + std::cerr + << "Export undistorted images related to a sfm_data file.\n" + << "Usage: " << argv[0] << '\n' + << "[-i|--sfmdata filename, the SfM_Data file to convert]\n" + << "[-o|--outdir path]\n" + << std::endl; + + std::cerr << s << std::endl; + return EXIT_FAILURE; + } + + // Create output dir + if (!stlplus::folder_exists(sOutDir)) + stlplus::folder_create( sOutDir ); + + SfM_Data sfm_data; + if (!Load(sfm_data, sSfM_Data_Filename, ESfM_Data(VIEWS|INTRINSICS))) { + std::cerr << std::endl + << "The input SfM_Data file \""<< sSfM_Data_Filename << "\" cannot be read." << std::endl; + return EXIT_FAILURE; + } + + bool bOk = true; + { + // Export views as undistorted images (those with valid Intrinsics) + Image image, image_ud; + C_Progress_display my_progress_bar( sfm_data.GetViews().size() ); + for(Views::const_iterator iter = sfm_data.GetViews().begin(); + iter != sfm_data.GetViews().end(); ++iter, ++my_progress_bar) + { + const View * view = iter->second.get(); + bool bIntrinsicDefined = view->id_intrinsic != UndefinedIndexT && + sfm_data.GetIntrinsics().find(view->id_intrinsic) != sfm_data.GetIntrinsics().end(); + + Intrinsics::const_iterator iterIntrinsic = sfm_data.GetIntrinsics().find(view->id_intrinsic); + + const std::string srcImage = stlplus::create_filespec(sfm_data.s_root_path, view->s_Img_path); + const std::string dstImage = stlplus::create_filespec( + sOutDir, stlplus::filename_part(srcImage)); + + const IntrinsicBase * cam = iterIntrinsic->second.get(); + if (cam->have_disto()) + { + // undistort the image and save it + if (ReadImage( srcImage.c_str(), &image)) + { + UndistortImage(image, cam, image_ud, BLACK); + bOk &= WriteImage(dstImage.c_str(), image_ud); + } + } + else // (no distortion) + { + // copy the image since there is no distortion + stlplus::file_copy(srcImage, dstImage); + } + } + } + + // Exit program + if (bOk) + return( EXIT_SUCCESS ); + else + return( EXIT_FAILURE ); +} From ef30349d54190d6f3cbe4768357fdf21728f1bb7 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Fri, 22 May 2015 12:38:40 +0200 Subject: [PATCH 27/52] [software] export some view graphs. #306 --- BUILD | 27 +++++++---- src/openMVG/graph/graph_builder.hpp | 27 +++++++++++ .../global/GlobalSfM_rotation_averaging.cpp | 8 +++- .../global/GlobalSfM_rotation_averaging.hpp | 2 + .../sfm_global_engine_relative_motions.cpp | 48 +++++++++++++++++++ src/software/SfM/main_ComputeMatches.cpp | 23 +++++++++ 6 files changed, 125 insertions(+), 10 deletions(-) diff --git a/BUILD b/BUILD index c765ef92ec..abd11ec6db 100644 --- a/BUILD +++ b/BUILD @@ -2,9 +2,9 @@ OpenMVG (open Multiple View Geometry) ===================================== ------------------ -Build instruction ------------------ +------------------ +Build instructions +------------------ Required tools: * Cmake @@ -31,12 +31,21 @@ OpenMVG_BUILD_TESTS (ON/OFF(default))=> Build openMVG unit tests OpenMVG_BUILD_EXAMPLES (ON/OFF(default))=> Build OpenMVG example applications. Does not affect binaries under 'software' +-------------------------- +General informations +for openMVG SfM pipelines +-------------------------- +OpenMVG can export graphs as graphviz .dot files and render them as SVG files. +If you want consider this graph visualization feature, please consider to install Graphviz. + ----------------- Linux compilation ----------------- Setup the required external library. * sudo apt-get install libpng-dev libjpeg-dev libtiff-dev libxxf86vm1 libxxf86vm-dev libxi-dev libxrandr-dev +If you want see the view graph svg logs +* sudo apt-get install graphviz $ git clone --recursive https://github.com/openMVG/openMVG.git $ cd openMVG @@ -92,6 +101,7 @@ Compile the libraries and binaries samples. ------------------- Mac compilation ------------------- + $ git clone --recursive https://github.com/openMVG/openMVG.git $ cd openMVG $ ls @@ -105,15 +115,17 @@ If you want enable unit tests and examples to the build: $ xcodebuild -configuration Release - -------------------- - Using openCV sample - -------------------- +-------------------- +Using openCV sample +-------------------- + Add -DOpenMVG_USE_OPENCV=ON to your cmake command line and set OpenCV_DIR variable to your openCV build directory => i.e.: -DOpenCV_DIR="/home/user/Dev/github/itseez/opencv_Build" -DOpenMVG_USE_OPENCV=ON ------------------------------------ Using as library dependency in cmake ------------------------------------ + Adding following lines to your CMakeLists.txt should provide OpenMVG usable as static library: @@ -121,6 +133,3 @@ static library: include_directories(${OpenMVG_INCLUDES}) target_link_libraries(target ${OpenMVG_LIBS}) -Information about required dependencies, standalone build and platform -specificity can be found below. - diff --git a/src/openMVG/graph/graph_builder.hpp b/src/openMVG/graph/graph_builder.hpp index e8cc7d5b5a..86164faa11 100644 --- a/src/openMVG/graph/graph_builder.hpp +++ b/src/openMVG/graph/graph_builder.hpp @@ -60,6 +60,33 @@ struct indexedGraph g.addEdge(map_size_t_to_node[i], map_size_t_to_node[j]); } } + + /// Create a graph from node index and pairs (edges) + // /!\ pairs must contains valid nodes indexes + template + indexedGraph(const IterableNodes & nodes, const IterablePairs & pairs) + { + map_nodeMapIndex.reset( new map_NodeMapIndex(g) ); + + //A-- Create a node graph for each element of the set + for (typename IterableNodes::const_iterator iter = nodes.begin(); + iter != nodes.end(); + ++iter) + { + map_size_t_to_node[*iter] = g.addNode(); + (*map_nodeMapIndex) [map_size_t_to_node[*iter]] = *iter; + } + + //B-- Add weighted edges from the pairs object + for (typename IterablePairs::const_iterator iter = pairs.begin(); + iter != pairs.end(); + ++iter) + { + const IndexT i = iter->first; + const IndexT j = iter->second; + g.addEdge(map_size_t_to_node[i], map_size_t_to_node[j]); + } + } }; } // namespace graph diff --git a/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.cpp b/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.cpp index e3b61b64ed..38fa0799d1 100644 --- a/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.cpp +++ b/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.cpp @@ -19,6 +19,11 @@ namespace sfm{ using namespace openMVG::rotation_averaging; +Pair_Set GlobalSfM_Rotation_AveragingSolver::GetUsedPairs() const +{ + return used_pairs; +} + bool GlobalSfM_Rotation_AveragingSolver::Run( ERotationAveragingMethod eRotationAveragingMethod, ERelativeRotationInferenceMethod eRelativeRotationInferenceMethod, @@ -27,7 +32,7 @@ bool GlobalSfM_Rotation_AveragingSolver::Run( ) const { RelativeRotations relativeRotations = relativeRot_In; - // We will work on a copy, since inference can remove some relative motions + // We work on a copy, since inference can remove some relative motions //-> Test there is only one graph and at least 3 camera ? switch(eRelativeRotationInferenceMethod) @@ -82,6 +87,7 @@ bool GlobalSfM_Rotation_AveragingSolver::Run( bSuccess = rotation_averaging::l2::L2RotationAveraging_Refine( relativeRotations, vec_globalR); + used_pairs = getPairs(relativeRotations); } break; case ROTATION_AVERAGING_L1: diff --git a/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.hpp b/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.hpp index f24f30e968..51ea8a7b49 100644 --- a/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.hpp +++ b/src/openMVG/sfm/pipelines/global/GlobalSfM_rotation_averaging.hpp @@ -53,6 +53,8 @@ class GlobalSfM_Rotation_AveragingSolver std::vector< graph::Triplet > & vec_triplets, rotation_averaging::RelativeRotations & relativeRotations) const; + /// Return the pairs validated by the GlobalRotation routine (inference can remove some) + Pair_Set GetUsedPairs() const; }; } // namespace sfm diff --git a/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp b/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp index 7d74854975..586ebe6cf9 100644 --- a/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp +++ b/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp @@ -12,6 +12,7 @@ #include "openMVG/multiview/triangulation_nview.hpp" #include "openMVG/graph/connectedComponent.hpp" #include "openMVG/system/timer.hpp" +#include "openMVG/stl/stl.hpp" #include "openMVG/multiview/essential.hpp" #include "third_party/progress/progress.hpp" @@ -245,6 +246,32 @@ bool GlobalSfMReconstructionEngine_RelativeMotions::Compute_Global_Rotations() _eRotationAveragingMethod, eRelativeRotationInferenceMethod, vec_relativeRotEstimate, _map_globalR); + if (bRotationAveraging) + { + // Log input graph to the HTML report + if (!_sLoggingFile.empty() && !_sOutDirectory.empty()) + { + // List the plausible remaining edges + std::set set_ViewIds; + std::transform(_sfm_data.GetViews().begin(), _sfm_data.GetViews().end(), + std::inserter(set_ViewIds, set_ViewIds.begin()), stl::RetrieveKey()); + const std::string sGraph_name = "global_rotation_graph"; + graph::indexedGraph putativeGraph(set_ViewIds, rotation_averaging_solver.GetUsedPairs()); + graph::exportToGraphvizData( + stlplus::create_filespec(_sOutDirectory, sGraph_name), + putativeGraph.g); + + using namespace htmlDocument; + std::ostringstream os; + + os << "
" << sGraph_name << "
" + << "\n"; + + _htmlDocStream->pushInfo(os.str()); + } + } return bRotationAveraging; } @@ -563,6 +590,27 @@ void GlobalSfMReconstructionEngine_RelativeMotions::Compute_Relative_Rotations(R // relativePose_info.relativePose.translation()); } } + // Log input graph to the HTML report + if (!_sLoggingFile.empty() && !_sOutDirectory.empty()) + { + std::set set_ViewIds; + std::transform(_sfm_data.GetViews().begin(), _sfm_data.GetViews().end(), + std::inserter(set_ViewIds, set_ViewIds.begin()), stl::RetrieveKey()); + graph::indexedGraph putativeGraph(set_ViewIds, getPairs(_matches_provider->_pairWise_matches)); + graph::exportToGraphvizData( + stlplus::create_filespec(_sOutDirectory, "input_largest_cc_relative_motions_graph"), + putativeGraph.g); + + using namespace htmlDocument; + std::ostringstream os; + + os << "
" << "input_largest_cc_relative_motions_graph" << "
" + << "\n"; + + _htmlDocStream->pushInfo(os.str()); + } } } // namespace sfm diff --git a/src/software/SfM/main_ComputeMatches.cpp b/src/software/SfM/main_ComputeMatches.cpp index 046b071823..dee78499ef 100644 --- a/src/software/SfM/main_ComputeMatches.cpp +++ b/src/software/SfM/main_ComputeMatches.cpp @@ -22,6 +22,8 @@ #include "openMVG/matching/indMatch_utils.hpp" #include "openMVG/system/timer.hpp" +#include "openMVG/graph/graph.hpp" +#include "openMVG/stl/stl.hpp" #include "third_party/cmdLine/cmdLine.h" #include "third_party/stlplus3/filesystemSimplified/file_system.hpp" @@ -298,6 +300,16 @@ int main(int argc, char **argv) PairWiseMatchingToAdjacencyMatrixSVG(vec_fileNames.size(), map_PutativesMatches, stlplus::create_filespec(sMatchesDirectory, "PutativeAdjacencyMatrix", "svg")); + //-- export view pair graph once putative graph matches have been computed + { + std::set set_ViewIds; + std::transform(sfm_data.GetViews().begin(), sfm_data.GetViews().end(), + std::inserter(set_ViewIds, set_ViewIds.begin()), stl::RetrieveKey()); + graph::indexedGraph putativeGraph(set_ViewIds, getPairs(map_PutativesMatches)); + graph::exportToGraphvizData( + stlplus::create_filespec(sMatchesDirectory, "putative_matches"), + putativeGraph.g); + } //--------------------------------------- // b. Geometric filtering of putative matches @@ -405,6 +417,17 @@ int main(int argc, char **argv) PairWiseMatchingToAdjacencyMatrixSVG(vec_fileNames.size(), map_GeometricMatches, stlplus::create_filespec(sMatchesDirectory, "GeometricAdjacencyMatrix", "svg")); + + //-- export view pair graph once geometric filter have been done + { + std::set set_ViewIds; + std::transform(sfm_data.GetViews().begin(), sfm_data.GetViews().end(), + std::inserter(set_ViewIds, set_ViewIds.begin()), stl::RetrieveKey()); + graph::indexedGraph putativeGraph(set_ViewIds, getPairs(map_GeometricMatches)); + graph::exportToGraphvizData( + stlplus::create_filespec(sMatchesDirectory, "geometric_matches"), + putativeGraph.g); + } } return EXIT_SUCCESS; } From 5653b3b18354b9952454f4876402924b9dd4923f Mon Sep 17 00:00:00 2001 From: pmoulon Date: Fri, 22 May 2015 15:47:47 +0200 Subject: [PATCH 28/52] Update citation part --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c64f765d93..27e4a28b38 100644 --- a/README.md +++ b/README.md @@ -78,5 +78,16 @@ publications are relevant: [5] Moisan Lionel, Moulon Pierre and Monasse Pascal. IPOL 2012. [Automatic Homographic Registration of a Pair of Images, with A Contrario Elimination of Outliers.](http://dx.doi.org/10.5201/ipol.2012.mmm-oh) -Please cite [3] if you use openMVG library in your work. +[6] Moulon Pierre, Monasse Pascal and Marlet Renaud. ICCV 2013. +[Global Fusion of Relative Motions for Robust, Accurate and Scalable Structure from Motion.](http://imagine.enpc.fr/~moulonp/publis/iccv2013/index.html) + +or cite it as: + +``` + @misc{openMVG, + author = "Pierre Moulon and Pascal Monasse and Renaud Marlet and Others", + title = "OpenMVG", + howpublished = "\url{https://github.com/openMVG/openMVG}", + } +``` From 7722de0eb25d63ae33c8346bef5744f81d35dc79 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Sat, 23 May 2015 16:54:46 +0200 Subject: [PATCH 29/52] Update the doc. #305 --- .../software/SfM/ExportUndistortedImages.rst | 42 +++++++++++++++++++ docs/sphinx/rst/software/SfM/SfM.rst | 2 + 2 files changed, 44 insertions(+) create mode 100644 docs/sphinx/rst/software/SfM/ExportUndistortedImages.rst diff --git a/docs/sphinx/rst/software/SfM/ExportUndistortedImages.rst b/docs/sphinx/rst/software/SfM/ExportUndistortedImages.rst new file mode 100644 index 0000000000..15bc9a2d73 --- /dev/null +++ b/docs/sphinx/rst/software/SfM/ExportUndistortedImages.rst @@ -0,0 +1,42 @@ + +******************************************** +openMVG_main_ExportUndistortedImages +******************************************** + +This application export undistorted images from known camera parameter intrinsic. + +Algorithm of the application + +.. code-block:: c++ + + Require: internal + camera calibration + Require: images + Ensure: undistorted images + for each view + if view has valid intrinsic + undistort and save the undistorted view + +Information and usage +======================== + +The chain is designed to run on a sfm_data.json file. +The sfm_data file should contains: +- valid view with some defined intrinsics, + + .. code-block:: c++ + + $ openMVG_main_ExportUndistortedImages -i Dataset/out_Reconstruction/sfm_data.json -o Dataset/out_Reconstruction/undistortedImages + +Arguments description: + +**Required parameters:** + + - **[-i|--input_file]** + + - a SfM_Data file with valid intrinsics and poses and optional structure + + - **[-o|--outdir]** + + - path where the undistorted images will be stored + + diff --git a/docs/sphinx/rst/software/SfM/SfM.rst b/docs/sphinx/rst/software/SfM/SfM.rst index 957561a185..e6f16373f2 100644 --- a/docs/sphinx/rst/software/SfM/SfM.rst +++ b/docs/sphinx/rst/software/SfM/SfM.rst @@ -82,6 +82,7 @@ OpenMVG SfM pipelines run as a 4 step process: ./ComputeSfM_DataColor.rst ./ComputeStructureFromKnownPoses.rst + ./ExportUndistortedImages.rst 5. Optional further processing (3rd party) @@ -131,6 +132,7 @@ To know more about each tool visit the following link and read the doc below: ./GlobalSfM.rst ./ComputeSfM_DataColor.rst ./ComputeStructureFromKnownPoses.rst + ./ExportUndistortedImages.rst .. toctree:: :maxdepth: 1 From 368ab5c29afbb0eb666b7ae0e9d7d92293dcd82c Mon Sep 17 00:00:00 2001 From: pmoulon Date: Sat, 23 May 2015 16:55:27 +0200 Subject: [PATCH 30/52] Add datum size information logging in verbose mode. --- src/openMVG/robust_estimation/robust_estimator_ACRansac.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openMVG/robust_estimation/robust_estimator_ACRansac.hpp b/src/openMVG/robust_estimation/robust_estimator_ACRansac.hpp index 21540ac23c..41b4a3eaa8 100644 --- a/src/openMVG/robust_estimation/robust_estimator_ACRansac.hpp +++ b/src/openMVG/robust_estimation/robust_estimator_ACRansac.hpp @@ -216,7 +216,7 @@ std::pair ACRANSAC(const Kernel &kernel, if(bVerbose) { std::cout << " nfa=" << minNFA - << " inliers=" << best.second + << " inliers=" << best.second << "/" << nData << " precisionNormalized=" << errorMax << " precision=" << kernel.unormalizeError(errorMax) << " (iter=" << iter; From ad8faf1628945e5ec4800acd718a80a7417a3268 Mon Sep 17 00:00:00 2001 From: Romain Janvier Date: Fri, 22 May 2015 12:06:07 +0200 Subject: [PATCH 31/52] openMVG2MVSTEXTURING (WIP) --- src/software/SfM/CMakeLists.txt | 6 ++ .../SfM/main_openMVG2MVSTEXTURING.cpp | 98 +++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 src/software/SfM/main_openMVG2MVSTEXTURING.cpp diff --git a/src/software/SfM/CMakeLists.txt b/src/software/SfM/CMakeLists.txt index 4c1336da9f..796e34d0d2 100644 --- a/src/software/SfM/CMakeLists.txt +++ b/src/software/SfM/CMakeLists.txt @@ -151,6 +151,12 @@ ADD_EXECUTABLE(openMVG_main_openMVG2MESHLAB main_openMVG2MESHLAB.cpp) TARGET_LINK_LIBRARIES(openMVG_main_openMVG2MESHLAB ${OpenMVG_LIBS}) +# - Export a SfM openMVG scene to mvs-texturing scene folder +# - +ADD_EXECUTABLE(openMVG_main_openMVG2MVSTEXTURING main_openMVG2MVSTEXTURING.cpp) +TARGET_LINK_LIBRARIES(openMVG_main_openMVG2MVSTEXTURING + ${OpenMVG_LIBS}) + # - Export SfM openMVG camera scene as triangle meshes # - ADD_EXECUTABLE(openMVG_main_ExportCameraFrustums main_ExportCameraFrustums.cpp) diff --git a/src/software/SfM/main_openMVG2MVSTEXTURING.cpp b/src/software/SfM/main_openMVG2MVSTEXTURING.cpp new file mode 100644 index 0000000000..a6fe69a5ec --- /dev/null +++ b/src/software/SfM/main_openMVG2MVSTEXTURING.cpp @@ -0,0 +1,98 @@ + + +// Copyright (c) 2012, 2013, 2015 Pierre MOULON. + +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "openMVG/sfm/sfm.hpp" +#include "openMVG/image/image.hpp" + +using namespace openMVG; + +#include "third_party/cmdLine/cmdLine.h" +#include "third_party/stlplus3/filesystemSimplified/file_system.hpp" +#include "openMVG/numeric/numeric.h" + +#include + +int main(int argc, char **argv) +{ + CmdLine cmd; + + std::string sSfM_Data_Filename; + std::string sOutDir = ""; + + cmd.add( make_option('i', sSfM_Data_Filename, "sfmdata") ); + cmd.add( make_option('o', sOutDir, "outdir") ); + + try { + if (argc == 1) throw std::string("Invalid command line parameter."); + cmd.process(argc, argv); + } catch(const std::string& s) { + std::cerr << "Usage: " << argv[0] << '\n' + << "[-i|--sfmdata filename, the SfM_Data file to convert]\n" + << "[-o|--outdir path]\n" + << std::endl; + + std::cerr << s << std::endl; + return EXIT_FAILURE; + } + + std::cout << " You called : " <second.get(); + std::cout << view->s_Img_path << "\n"; + std::cout << stlplus::basename_part(view->s_Img_path) << std::endl; + std::ofstream outfile( stlplus::create_filespec( + sOutDir, stlplus::basename_part(view->s_Img_path), "cam" ).c_str() ); + Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); + Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); + + if (iterPose == sfm_data.getPoses().end() || + iterIntrinsic == sfm_data.getIntrinsics().end()) + continue; + + const std::string srcImage = stlplus::create_filespec(sfm_data.s_root_path, view->s_Img_path); + const IntrinsicBase * cam = iterIntrinsic->second.get(); + Mat34 P = cam->get_projective_equivalent(iterPose->second); + + Mat3 R, K; + Vec3 t; + KRt_From_P(P, &K, &R, &t); + + int largerDim = cam->w() > cam->h() ? cam->w() : cam->h(); + + // see https://github.com/nmoehrle/mvs-texturing/blob/master/Arguments.cpp + // for full specs + outfile << t(0) << " " << t(1) << " " << t(2) << " " + << R(0,0) << " " << R(0,1) << " " << R(0,2) << " " + << R(1,0) << " " << R(1,1) << " " << R(1,2) << " " + << R(2,0) << " " << R(2,1) << " " << R(2,2) << "\n" + << K(0,0) / largerDim << " 0 0 1 " << K(0,2) / cam->w() << " " << K(1,2) / cam->h(); + //TODO : undist + outfile.close(); + + } + return EXIT_SUCCESS; +} From dc0dd2c59058c57e1229322f5dea29d874aeccca Mon Sep 17 00:00:00 2001 From: Romain Janvier Date: Sun, 24 May 2015 10:01:38 +0200 Subject: [PATCH 32/52] Adds some needed corrections (Thx @pmoulon) --- src/software/SfM/CMakeLists.txt | 2 + .../SfM/main_openMVG2MVSTEXTURING.cpp | 53 ++++++++++--------- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/src/software/SfM/CMakeLists.txt b/src/software/SfM/CMakeLists.txt index 796e34d0d2..ff37bb3a16 100644 --- a/src/software/SfM/CMakeLists.txt +++ b/src/software/SfM/CMakeLists.txt @@ -170,6 +170,8 @@ SET_PROPERTY(TARGET openMVG_main_openMVG2CMPMVS PROPERTY FOLDER OpenMVG/software INSTALL(TARGETS openMVG_main_openMVG2CMPMVS DESTINATION bin/) SET_PROPERTY(TARGET openMVG_main_openMVG2MESHLAB PROPERTY FOLDER OpenMVG/software) INSTALL(TARGETS openMVG_main_openMVG2MESHLAB DESTINATION bin/) +SET_PROPERTY(TARGET openMVG_main_openMVG2MVSTEXTURING PROPERTY FOLDER OpenMVG/software) +INSTALL(TARGETS openMVG_main_openMVG2MVSTEXTURING DESTINATION bin/) SET_PROPERTY(TARGET openMVG_main_ExportCameraFrustums PROPERTY FOLDER OpenMVG/software) INSTALL(TARGETS openMVG_main_ExportCameraFrustums DESTINATION bin/) diff --git a/src/software/SfM/main_openMVG2MVSTEXTURING.cpp b/src/software/SfM/main_openMVG2MVSTEXTURING.cpp index a6fe69a5ec..48cc35f223 100644 --- a/src/software/SfM/main_openMVG2MVSTEXTURING.cpp +++ b/src/software/SfM/main_openMVG2MVSTEXTURING.cpp @@ -10,10 +10,12 @@ #include "openMVG/image/image.hpp" using namespace openMVG; +using namespace openMVG::cameras; +using namespace openMVG::geometry; +using namespace openMVG::sfm; #include "third_party/cmdLine/cmdLine.h" #include "third_party/stlplus3/filesystemSimplified/file_system.hpp" -#include "openMVG/numeric/numeric.h" #include @@ -45,6 +47,8 @@ int main(int argc, char **argv) << "--sfmdata " << sSfM_Data_Filename << std::endl << "--outdir " << sOutDir << std::endl; + bool bOneHaveDisto = false; + // Create output dir if (!stlplus::folder_exists(sOutDir)) stlplus::folder_create( sOutDir ); @@ -57,42 +61,43 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - - for(Views::const_iterator iter = sfm_data.getViews().begin(); - iter != sfm_data.getViews().end(); ++iter) + for(Views::const_iterator iter = sfm_data.GetViews().begin(); + iter != sfm_data.GetViews().end(); ++iter) { const View * view = iter->second.get(); - std::cout << view->s_Img_path << "\n"; - std::cout << stlplus::basename_part(view->s_Img_path) << std::endl; - std::ofstream outfile( stlplus::create_filespec( - sOutDir, stlplus::basename_part(view->s_Img_path), "cam" ).c_str() ); - Poses::const_iterator iterPose = sfm_data.getPoses().find(view->id_pose); - Intrinsics::const_iterator iterIntrinsic = sfm_data.getIntrinsics().find(view->id_intrinsic); - - if (iterPose == sfm_data.getPoses().end() || - iterIntrinsic == sfm_data.getIntrinsics().end()) + if (!sfm_data.IsPoseAndIntrinsicDefined(view)) continue; - - const std::string srcImage = stlplus::create_filespec(sfm_data.s_root_path, view->s_Img_path); + + // Valid view, we can ask a pose & intrinsic data + const Pose3 pose = sfm_data.GetPoseOrDie(view); + Intrinsics::const_iterator iterIntrinsic = sfm_data.GetIntrinsics().find(view->id_intrinsic); const IntrinsicBase * cam = iterIntrinsic->second.get(); - Mat34 P = cam->get_projective_equivalent(iterPose->second); - + const Mat34 P = cam->get_projective_equivalent(pose); + Mat3 R, K; Vec3 t; KRt_From_P(P, &K, &R, &t); - - int largerDim = cam->w() > cam->h() ? cam->w() : cam->h(); - - // see https://github.com/nmoehrle/mvs-texturing/blob/master/Arguments.cpp + + // We can now create the .cam file for the View in the output dir + std::ofstream outfile( stlplus::create_filespec( + sOutDir, stlplus::basename_part(view->s_Img_path), "cam" ).c_str() ); + // See https://github.com/nmoehrle/mvs-texturing/blob/master/Arguments.cpp // for full specs + const int largerDim = cam->w() > cam->h() ? cam->w() : cam->h(); outfile << t(0) << " " << t(1) << " " << t(2) << " " << R(0,0) << " " << R(0,1) << " " << R(0,2) << " " << R(1,0) << " " << R(1,1) << " " << R(1,2) << " " << R(2,0) << " " << R(2,1) << " " << R(2,2) << "\n" << K(0,0) / largerDim << " 0 0 1 " << K(0,2) / cam->w() << " " << K(1,2) / cam->h(); - //TODO : undist outfile.close(); - + + if(cam->have_disto()) + bOneHaveDisto = true; } - return EXIT_SUCCESS; + + const string sUndistMsg = bOneHaveDisto ? "undistorded" : ""; + const string sQuitMsg = "Your SfM_Data file was succesfully converted!\n" + + "Now you can copy your " + sUndistMsg + " images in the \"" + sOutDir + "\" directory and run MVS Texturing"; + std::cout << sQuitMsg << std::endl; + return EXIT_SUCCESS; } From a067c306206fc4dc42cc4fd9a7782c9ecb238866 Mon Sep 17 00:00:00 2001 From: Romain Janvier Date: Sun, 24 May 2015 10:45:14 +0200 Subject: [PATCH 33/52] C++ is not Python --- src/software/SfM/main_openMVG2MVSTEXTURING.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/software/SfM/main_openMVG2MVSTEXTURING.cpp b/src/software/SfM/main_openMVG2MVSTEXTURING.cpp index 48cc35f223..bccf56b964 100644 --- a/src/software/SfM/main_openMVG2MVSTEXTURING.cpp +++ b/src/software/SfM/main_openMVG2MVSTEXTURING.cpp @@ -96,7 +96,7 @@ int main(int argc, char **argv) } const string sUndistMsg = bOneHaveDisto ? "undistorded" : ""; - const string sQuitMsg = "Your SfM_Data file was succesfully converted!\n" + + const string sQuitMsg = std::string("Your SfM_Data file was succesfully converted!\n") + "Now you can copy your " + sUndistMsg + " images in the \"" + sOutDir + "\" directory and run MVS Texturing"; std::cout << sQuitMsg << std::endl; return EXIT_SUCCESS; From b5a8fbeb5aa96a2095f75753c04b8494585820e4 Mon Sep 17 00:00:00 2001 From: Romain Janvier Date: Sun, 24 May 2015 10:46:04 +0200 Subject: [PATCH 34/52] Adds Documentation --- docs/sphinx/rst/bibliography.rst | 3 +++ docs/sphinx/rst/software/SfM/MVS.rst | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/docs/sphinx/rst/bibliography.rst b/docs/sphinx/rst/bibliography.rst index 8c61516754..2a7fe4eb0c 100644 --- a/docs/sphinx/rst/bibliography.rst +++ b/docs/sphinx/rst/bibliography.rst @@ -60,6 +60,9 @@ Bibliography .. [CMPMVS] **Multi-View Reconstruction Preserving Weakly-Supported Surfaces.** M. Jancosek, T. Pajdla, CVPR 2011. +.. [Waechter2014] **Let There Be Color! Large-Scale Texturing of 3D Reconstructions.** + M. Waechter, N. Moehrle, and M. Goesele, ECCV 2014. + .. [FLANN] **Fast Approximate Nearest Neighbors with Automatic Algorithm Configuration.** Muja, Marius, and David G. Lowe. VISAPP (1). 2009. diff --git a/docs/sphinx/rst/software/SfM/MVS.rst b/docs/sphinx/rst/software/SfM/MVS.rst index 188c409cd4..b347a957b2 100644 --- a/docs/sphinx/rst/software/SfM/MVS.rst +++ b/docs/sphinx/rst/software/SfM/MVS.rst @@ -55,6 +55,11 @@ Export to MVE (Multi-View Environment) You will need to compile MVE tools and `FSSR `_. +Export to MVS Texturing +======================= + +If you don't want to use the full MVE pipeline but only `MVS Texturing `_ [Waechter2014]_ to project a set of oriented images on a mesh, one solution is to use the openMVG_main_openMVG2MVSTexturing binary. This binary converts your SfM_Data file into one format used by MVS Texturing. In addition, you may need to undistort your images with openMVG_main_ExportUndistortedImages as it's not handled by the openMVG_main_openMVG2MVSTexturing tool. + Export to CMPMVS ======================== From 9ca26554de1f673f57e95c98fb6a5d71a16bf979 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Mon, 25 May 2015 15:15:47 +0200 Subject: [PATCH 35/52] [matching_image_collection] delegate multi-threading to matching matchers. #309 --- src/openMVG/matching/matcher_brute_force.hpp | 3 +++ src/openMVG/matching/matcher_kdtree_flann.hpp | 6 ++++- .../Matcher_Regions_AllInMemory.cpp | 7 +----- src/third_party/CMakeLists.txt | 1 - src/third_party/flann/CMakeLists.txt | 12 ++-------- src/third_party/flann/src/cpp/CMakeLists.txt | 24 +++++++++---------- .../flann/src/cpp/flann/nn/ground_truth.h | 1 - 7 files changed, 23 insertions(+), 31 deletions(-) diff --git a/src/openMVG/matching/matcher_brute_force.hpp b/src/openMVG/matching/matcher_brute_force.hpp index 5dc592e31a..4b7698e6c3 100644 --- a/src/openMVG/matching/matcher_brute_force.hpp +++ b/src/openMVG/matching/matcher_brute_force.hpp @@ -120,6 +120,9 @@ class ArrayMatcherBruteForce : public ArrayMatcher pvec_distance->resize(nbQuery * NN); pvec_indice->resize(nbQuery * NN); +#ifdef OPENMVG_USE_OPENMP +#pragma omp parallel for schedule(dynamic) +#endif for (int queryIndex=0; queryIndex < nbQuery; ++queryIndex) { std::vector vec_distance((*memMapping).rows(), 0.0); const Scalar * queryPtr = mat_query.row(queryIndex).data(); diff --git a/src/openMVG/matching/matcher_kdtree_flann.hpp b/src/openMVG/matching/matcher_kdtree_flann.hpp index 6cc3656214..caadcabf8d 100644 --- a/src/openMVG/matching/matcher_kdtree_flann.hpp +++ b/src/openMVG/matching/matcher_kdtree_flann.hpp @@ -122,7 +122,11 @@ class ArrayMatcher_Kdtree_Flann : public ArrayMatcher flann::Matrix indices(indicePTR, nbQuery, NN); flann::Matrix dists(distancePTR, nbQuery, NN); // do a knn search, using 128 checks - _index->knnSearch(queries, indices, dists, NN, flann::SearchParams(128)); + flann::SearchParams params(128); +#ifdef OPENMVG_USE_OPENMP + params.cores = omp_get_max_threads(); +#endif + _index->knnSearch(queries, indices, dists, NN, params); return true; } else { diff --git a/src/openMVG/matching_image_collection/Matcher_Regions_AllInMemory.cpp b/src/openMVG/matching_image_collection/Matcher_Regions_AllInMemory.cpp index 9dde7193ff..f8a0c44143 100644 --- a/src/openMVG/matching_image_collection/Matcher_Regions_AllInMemory.cpp +++ b/src/openMVG/matching_image_collection/Matcher_Regions_AllInMemory.cpp @@ -105,9 +105,7 @@ void Template_Matcher( ( matcher10.Build(tabI, regions_countI, regionsI->DescriptorLength()) ); const std::vector & indexToCompare = iter->second; -#ifdef OPENMVG_USE_OPENMP -#pragma omp parallel for schedule(dynamic) -#endif + for (int j = 0; j < (int)indexToCompare.size(); ++j) { const size_t J = indexToCompare[j]; @@ -147,9 +145,6 @@ void Template_Matcher( IndMatchDecorator matchDeduplicator(vec_FilteredMatches, pointFeaturesI, pointFeaturesJ); matchDeduplicator.getDeduplicated(vec_FilteredMatches); -#ifdef OPENMVG_USE_OPENMP -#pragma omp critical -#endif { ++my_progress_bar; if (!vec_FilteredMatches.empty()) diff --git a/src/third_party/CMakeLists.txt b/src/third_party/CMakeLists.txt index 4056588518..f3f4f44cc0 100644 --- a/src/third_party/CMakeLists.txt +++ b/src/third_party/CMakeLists.txt @@ -66,7 +66,6 @@ SET_PROPERTY(TARGET ceres PROPERTY FOLDER OpenMVG/3rdParty/ceres) # Add an Approximate Nearest Neighbor library ADD_SUBDIRECTORY(flann) -SET_PROPERTY(TARGET flann_cpp PROPERTY FOLDER OpenMVG/3rdParty) SET_PROPERTY(TARGET flann_cpp_s PROPERTY FOLDER OpenMVG/3rdParty) # Exif data parsing diff --git a/src/third_party/flann/CMakeLists.txt b/src/third_party/flann/CMakeLists.txt index 4bcc75f89a..30944b0988 100644 --- a/src/third_party/flann/CMakeLists.txt +++ b/src/third_party/flann/CMakeLists.txt @@ -38,8 +38,8 @@ list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) # MinSizeRel : w/o debug symbols, w/ optimization, stripped binaries if (NOT CMAKE_BUILD_TYPE) - #set(CMAKE_BUILD_TYPE Release) - set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Build type" FORCE) + set(CMAKE_BUILD_TYPE Release) + #set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Build type" FORCE) #set(CMAKE_BUILD_TYPE Debug) endif() @@ -94,11 +94,3 @@ endif(WIN32) add_subdirectory( cmake ) add_subdirectory( src ) -message(STATUS "Install prefix: ${CMAKE_INSTALL_PREFIX}") -message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") -message(STATUS "Building C bindings: ${BUILD_C_BINDINGS}") -message(STATUS "Building python bindings: ${BUILD_PYTHON_BINDINGS}") -message(STATUS "Building matlab bindings: ${BUILD_MATLAB_BINDINGS}") -message(STATUS "Building CUDA library: ${BUILD_CUDA_LIB}") -message(STATUS "Using OpenMP support: ${USE_OPENMP}") -message(STATUS "Using MPI support: ${USE_MPI}") diff --git a/src/third_party/flann/src/cpp/CMakeLists.txt b/src/third_party/flann/src/cpp/CMakeLists.txt index 2b93bd1eaf..b66fa11846 100644 --- a/src/third_party/flann/src/cpp/CMakeLists.txt +++ b/src/third_party/flann/src/cpp/CMakeLists.txt @@ -12,17 +12,17 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG) endif() SET_PROPERTY(TARGET flann_cpp_s PROPERTY COMPILE_DEFINITIONS FLANN_STATIC FLANN_USE_CUDA) -if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_COMPILER_IS_GNUCC) - add_library(flann_cpp SHARED "") - set_target_properties(flann_cpp PROPERTIES LINKER_LANGUAGE CXX) - target_link_libraries(flann_cpp -Wl,-whole-archive flann_cpp_s -Wl,-no-whole-archive) -else() - add_library(flann_cpp SHARED ${CPP_SOURCES}) -endif() +#if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_COMPILER_IS_GNUCC) +# add_library(flann_cpp SHARED "") +# set_target_properties(flann_cpp PROPERTIES LINKER_LANGUAGE CXX) +# target_link_libraries(flann_cpp -Wl,-whole-archive flann_cpp_s -Wl,-no-whole-archive) +#else() +# add_library(flann_cpp SHARED ${CPP_SOURCES}) +#endif() -set_target_properties(flann_cpp PROPERTIES - VERSION ${FLANN_VERSION} - SOVERSION ${FLANN_SOVERSION} - DEFINE_SYMBOL FLANN_EXPORTS -) +#set_target_properties(flann_cpp PROPERTIES +# VERSION ${FLANN_VERSION} +# SOVERSION ${FLANN_SOVERSION} +# DEFINE_SYMBOL FLANN_EXPORTS +#) diff --git a/src/third_party/flann/src/cpp/flann/nn/ground_truth.h b/src/third_party/flann/src/cpp/flann/nn/ground_truth.h index 94121e84a6..01f7e76985 100644 --- a/src/third_party/flann/src/cpp/flann/nn/ground_truth.h +++ b/src/third_party/flann/src/cpp/flann/nn/ground_truth.h @@ -42,7 +42,6 @@ template void find_nearest(const Matrix& dataset, typename Distance::ElementType* query, size_t* matches, size_t nn, size_t skip = 0, Distance distance = Distance()) { - typedef typename Distance::ElementType ElementType; typedef typename Distance::ResultType DistanceType; int n = nn + skip; From 9b1f11719d1e13b9fe59e08917649ac054b663b6 Mon Sep 17 00:00:00 2001 From: Roman Hiestand Date: Mon, 25 May 2015 20:41:38 +0200 Subject: [PATCH 36/52] Fixes for MinGW compilation, detecting some corner cases Fixes for MinGW compilation Detecting corner cases: Checking for empty matches Using std::move where applicable --- src/CMakeLists.txt | 4 +++- .../matching_image_collection/GeometricFilter.hpp | 2 +- .../Matcher_Regions_AllInMemory.cpp | 12 +++++++----- src/openMVG/numeric/numeric.h | 4 ++-- .../global/sfm_global_engine_relative_motions.cpp | 3 +++ .../filesystemSimplified/portability_fixes.cpp | 2 +- .../filesystemSimplified/portability_fixes.hpp | 2 +- 7 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c720f7e4c8..33fd4c4feb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -30,7 +30,9 @@ ENDIF(NOT CMAKE_BUILD_TYPE AND NOT MSVC) IF (WIN32) ADD_DEFINITIONS(-DNOMINMAX) - ADD_DEFINITIONS(/bigobj) + IF (MSVC) + ADD_DEFINITIONS(/bigobj) + ENDIF (MSVC) ENDIF (WIN32) # ============================================================================== diff --git a/src/openMVG/matching_image_collection/GeometricFilter.hpp b/src/openMVG/matching_image_collection/GeometricFilter.hpp index a8d10fcd9b..997cc0fba0 100644 --- a/src/openMVG/matching_image_collection/GeometricFilter.hpp +++ b/src/openMVG/matching_image_collection/GeometricFilter.hpp @@ -89,7 +89,7 @@ class ImageCollectionGeometricFilter #pragma omp critical #endif { - map_GeometricMatches[std::make_pair(iIndex,jIndex)] = vec_filteredMatches; + map_GeometricMatches.insert(std::make_pair(std::make_pair(iIndex, jIndex), std::move(vec_filteredMatches))); } } } diff --git a/src/openMVG/matching_image_collection/Matcher_Regions_AllInMemory.cpp b/src/openMVG/matching_image_collection/Matcher_Regions_AllInMemory.cpp index f8a0c44143..fd0420aaca 100644 --- a/src/openMVG/matching_image_collection/Matcher_Regions_AllInMemory.cpp +++ b/src/openMVG/matching_image_collection/Matcher_Regions_AllInMemory.cpp @@ -98,8 +98,9 @@ void Template_Matcher( const features::Regions *regionsI = regions_perImage.at(I).get(); const size_t regions_countI = regionsI->RegionCount(); const std::vector pointFeaturesI = regionsI->GetRegionsPositions(); - const typename MatcherT::ScalarT * tabI = - reinterpret_cast(regionsI->DescriptorRawData()); + const typename MatcherT::ScalarT * tabI = NULL; + if(regions_countI > 0) + tabI = reinterpret_cast(regionsI->DescriptorRawData()); MatcherT matcher10; ( matcher10.Build(tabI, regions_countI, regionsI->DescriptorLength()) ); @@ -112,8 +113,9 @@ void Template_Matcher( const features::Regions *regionsJ = regions_perImage.at(J).get(); const size_t regions_countJ = regionsJ->RegionCount(); - const typename MatcherT::ScalarT * tabJ = - reinterpret_cast(regionsJ->DescriptorRawData()); + const typename MatcherT::ScalarT * tabJ = NULL; + if(regions_countJ > 0) + tabJ = reinterpret_cast(regionsJ->DescriptorRawData()); const size_t NNN__ = 2; std::vector vec_nIndice10; @@ -149,7 +151,7 @@ void Template_Matcher( ++my_progress_bar; if (!vec_FilteredMatches.empty()) { - map_PutativesMatches.insert( make_pair( make_pair(I,J), vec_FilteredMatches )); + map_PutativesMatches.insert( make_pair( make_pair(I,J), std::move(vec_FilteredMatches) )); } } } diff --git a/src/openMVG/numeric/numeric.h b/src/openMVG/numeric/numeric.h index 804e62bd55..f0fa7c9bd3 100644 --- a/src/openMVG/numeric/numeric.h +++ b/src/openMVG/numeric/numeric.h @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include @@ -335,7 +335,7 @@ namespace openMVG { inline int is_finite(const double val) { -#ifdef _WIN32 +#ifdef _MSC_VER return _finite(val); #else return std::isfinite(val); diff --git a/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp b/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp index 586ebe6cf9..1e32eafa18 100644 --- a/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp +++ b/src/openMVG/sfm/pipelines/global/sfm_global_engine_relative_motions.cpp @@ -169,6 +169,9 @@ bool GlobalSfMReconstructionEngine_RelativeMotions::Process() { /// Compute from relative rotations the global rotations of the camera poses bool GlobalSfMReconstructionEngine_RelativeMotions::Compute_Global_Rotations() { + if(_relatives_Rt.empty()) + return false; + // Convert RelativeInfo_Map to appropriate input for solving the global rotations // - store the relative rotations and set a weight using namespace openMVG::rotation_averaging; diff --git a/src/third_party/stlplus3/filesystemSimplified/portability_fixes.cpp b/src/third_party/stlplus3/filesystemSimplified/portability_fixes.cpp index d1ad5d2249..41a994013b 100644 --- a/src/third_party/stlplus3/filesystemSimplified/portability_fixes.cpp +++ b/src/third_party/stlplus3/filesystemSimplified/portability_fixes.cpp @@ -16,7 +16,7 @@ // problems with missing functions //////////////////////////////////////////////////////////////////////////////// -#ifdef MSWINDOWS +#if defined(_MSC_VER) unsigned sleep(unsigned seconds) { Sleep(1000*seconds); diff --git a/src/third_party/stlplus3/filesystemSimplified/portability_fixes.hpp b/src/third_party/stlplus3/filesystemSimplified/portability_fixes.hpp index fc497387ac..7ef39db552 100644 --- a/src/third_party/stlplus3/filesystemSimplified/portability_fixes.hpp +++ b/src/third_party/stlplus3/filesystemSimplified/portability_fixes.hpp @@ -93,7 +93,7 @@ namespace std // problems with missing functions //////////////////////////////////////////////////////////////////////////////// -#ifdef MSWINDOWS +#if defined(_MSC_VER) unsigned sleep(unsigned seconds); #else #include From d6ef05360f4ea6286c906ef6ea9cddc08af9d1a8 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Tue, 26 May 2015 09:33:28 +0200 Subject: [PATCH 37/52] Avoid to use NULL pointer. --- .../Matcher_Regions_AllInMemory.cpp | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/openMVG/matching_image_collection/Matcher_Regions_AllInMemory.cpp b/src/openMVG/matching_image_collection/Matcher_Regions_AllInMemory.cpp index fd0420aaca..cd1f752d87 100644 --- a/src/openMVG/matching_image_collection/Matcher_Regions_AllInMemory.cpp +++ b/src/openMVG/matching_image_collection/Matcher_Regions_AllInMemory.cpp @@ -94,28 +94,34 @@ void Template_Matcher( iter != map_Pairs.end(); ++iter) { const size_t I = iter->first; + const std::vector & indexToCompare = iter->second; const features::Regions *regionsI = regions_perImage.at(I).get(); const size_t regions_countI = regionsI->RegionCount(); + if(regions_countI == 0) + { + my_progress_bar += indexToCompare.size(); + continue; + } const std::vector pointFeaturesI = regionsI->GetRegionsPositions(); - const typename MatcherT::ScalarT * tabI = NULL; - if(regions_countI > 0) - tabI = reinterpret_cast(regionsI->DescriptorRawData()); + const typename MatcherT::ScalarT * tabI = + reinterpret_cast(regionsI->DescriptorRawData()); MatcherT matcher10; ( matcher10.Build(tabI, regions_countI, regionsI->DescriptorLength()) ); - const std::vector & indexToCompare = iter->second; - - for (int j = 0; j < (int)indexToCompare.size(); ++j) + for (int j = 0; j < (int)indexToCompare.size(); ++j, ++my_progress_bar) { const size_t J = indexToCompare[j]; const features::Regions *regionsJ = regions_perImage.at(J).get(); const size_t regions_countJ = regionsJ->RegionCount(); - const typename MatcherT::ScalarT * tabJ = NULL; - if(regions_countJ > 0) - tabJ = reinterpret_cast(regionsJ->DescriptorRawData()); + if(regions_countJ == 0) + { + continue; + } + const typename MatcherT::ScalarT * tabJ = + reinterpret_cast(regionsJ->DescriptorRawData()); const size_t NNN__ = 2; std::vector vec_nIndice10; @@ -147,12 +153,9 @@ void Template_Matcher( IndMatchDecorator matchDeduplicator(vec_FilteredMatches, pointFeaturesI, pointFeaturesJ); matchDeduplicator.getDeduplicated(vec_FilteredMatches); + if (!vec_FilteredMatches.empty()) { - ++my_progress_bar; - if (!vec_FilteredMatches.empty()) - { - map_PutativesMatches.insert( make_pair( make_pair(I,J), std::move(vec_FilteredMatches) )); - } + map_PutativesMatches.insert( make_pair( make_pair(I,J), std::move(vec_FilteredMatches) )); } } } From 387ea28d3540171a022d7f7d6110a31d7acd285d Mon Sep 17 00:00:00 2001 From: pmoulon Date: Tue, 26 May 2015 09:35:40 +0200 Subject: [PATCH 38/52] Update AUTHORS list with rhiestan name due to the last pull request --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index be02081328..2c54c76335 100644 --- a/AUTHORS +++ b/AUTHORS @@ -14,6 +14,7 @@ Michael Holroyd Romain Janvier Rory McCann Romuald Perrot +rhiestan sergi pujades-rocamora sflotron vincentweb From a5f74f2d58b50ebd92b703802848545e87799658 Mon Sep 17 00:00:00 2001 From: Roman Hiestand Date: Tue, 26 May 2015 10:13:58 +0200 Subject: [PATCH 39/52] Fix crash in MinGW and Clang compiles Adopting a change from OpenCV flann, seems to fix the crash. --- src/third_party/flann/src/cpp/flann/util/any.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/third_party/flann/src/cpp/flann/util/any.h b/src/third_party/flann/src/cpp/flann/util/any.h index cf0efec503..2057e53a9e 100644 --- a/src/third_party/flann/src/cpp/flann/util/any.h +++ b/src/third_party/flann/src/cpp/flann/util/any.h @@ -47,6 +47,7 @@ struct base_any_policy virtual ::size_t get_size() = 0; virtual const std::type_info& type() = 0; virtual void print(std::ostream& out, void* const* src) = 0; + virtual ~base_any_policy() {} }; template From b6d100e50bd3dc072be91a463856ea13417c71d5 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Tue, 26 May 2015 11:07:36 +0200 Subject: [PATCH 40/52] [sfm] Extend BAF file format with view's id_intrinsic & id_pose. #304 --- src/openMVG/sfm/sfm_data_io_baf.hpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/openMVG/sfm/sfm_data_io_baf.hpp b/src/openMVG/sfm/sfm_data_io_baf.hpp index 3fc12238c7..c9ae94dca2 100644 --- a/src/openMVG/sfm/sfm_data_io_baf.hpp +++ b/src/openMVG/sfm/sfm_data_io_baf.hpp @@ -23,6 +23,10 @@ namespace sfm { // Intrinsic parameters [foc ppx ppy, ...] // Poses [angle axis, camera center] // Landmarks [X Y Z #observations id_intrinsic id_pose x y ...] +//-- +//- Export also a _imgList.txt file with View filename and id_intrinsic & id_pose. +// filename id_intrinsic id_pose +// The ids allow to establish a link between 3D point observations & the corresponding views static bool Save_BAF( const SfM_Data & sfm_data, const std::string & filename, @@ -89,10 +93,11 @@ static bool Save_BAF( bOk = stream.good(); stream.close(); } - // Export View filenames as an imgList.txt file + + // Export View filenames & ids as an imgList.txt file { const std::string sFile = stlplus::create_filespec( - stlplus::folder_part(filename), "imgList", "txt"); + stlplus::folder_part(filename), stlplus::basename_part(filename) + std::string("_imgList"), "txt"); stream.open(sFile.c_str()); if (!stream.is_open()) @@ -103,7 +108,9 @@ static bool Save_BAF( { const std::string sView_filename = stlplus::create_filespec(sfm_data.s_root_path, iterV->second->s_Img_path); - stream << sView_filename << "\n"; + stream << sView_filename + << ' ' << iterV->second->id_intrinsic + << ' ' << iterV->second->id_pose << "\n"; } stream.flush(); bOk = stream.good(); From 36f9d376416a590e676b9f85a4864d74131aa1ab Mon Sep 17 00:00:00 2001 From: Romain Janvier Date: Wed, 27 May 2015 01:10:21 +0200 Subject: [PATCH 41/52] openMVG2MVSTexturing: last additions --- docs/sphinx/rst/software/SfM/MVS.rst | 2 +- .../SfM/main_openMVG2MVSTEXTURING.cpp | 26 ++++++++++++++----- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/docs/sphinx/rst/software/SfM/MVS.rst b/docs/sphinx/rst/software/SfM/MVS.rst index b347a957b2..99b8c3e82d 100644 --- a/docs/sphinx/rst/software/SfM/MVS.rst +++ b/docs/sphinx/rst/software/SfM/MVS.rst @@ -58,7 +58,7 @@ You will need to compile MVE tools and `FSSR `_ [Waechter2014]_ to project a set of oriented images on a mesh, one solution is to use the openMVG_main_openMVG2MVSTexturing binary. This binary converts your SfM_Data file into one format used by MVS Texturing. In addition, you may need to undistort your images with openMVG_main_ExportUndistortedImages as it's not handled by the openMVG_main_openMVG2MVSTexturing tool. +If you don't want to use the full MVE pipeline but only `MVS Texturing `_ [Waechter2014]_ to project a set of oriented images on a mesh, one solution is to use the openMVG_main_openMVG2MVSTEXTURING binary. This binary converts your SfM_Data file into one format used by MVS Texturing. In addition, you may need to undistort your images with openMVG_main_ExportUndistortedImages as it's not handled by the openMVG_main_openMVG2MVSTEXTURING tool. Export to CMPMVS ======================== diff --git a/src/software/SfM/main_openMVG2MVSTEXTURING.cpp b/src/software/SfM/main_openMVG2MVSTEXTURING.cpp index bccf56b964..7571a11bae 100644 --- a/src/software/SfM/main_openMVG2MVSTEXTURING.cpp +++ b/src/software/SfM/main_openMVG2MVSTEXTURING.cpp @@ -72,23 +72,35 @@ int main(int argc, char **argv) const Pose3 pose = sfm_data.GetPoseOrDie(view); Intrinsics::const_iterator iterIntrinsic = sfm_data.GetIntrinsics().find(view->id_intrinsic); const IntrinsicBase * cam = iterIntrinsic->second.get(); - const Mat34 P = cam->get_projective_equivalent(pose); - - Mat3 R, K; - Vec3 t; - KRt_From_P(P, &K, &R, &t); + + if (!cameras::isPinhole(cam->getType())) + continue; + const Pinhole_Intrinsic * pinhole_cam = static_cast(cam); + + // Extrinsic + const Vec3 t = pose.translation(); + const Mat3 R = pose.rotation(); + // Intrinsic + const double f = pinhole_cam->focal(); + const Vec2 pp = pinhole_cam->principal_point(); + + std::cout << "++++" << pp << std::endl; + + // Image size in px + const int w = pinhole_cam->w(); + const int h = pinhole_cam->h(); // We can now create the .cam file for the View in the output dir std::ofstream outfile( stlplus::create_filespec( sOutDir, stlplus::basename_part(view->s_Img_path), "cam" ).c_str() ); // See https://github.com/nmoehrle/mvs-texturing/blob/master/Arguments.cpp // for full specs - const int largerDim = cam->w() > cam->h() ? cam->w() : cam->h(); + const int largerDim = w > h ? w : h; outfile << t(0) << " " << t(1) << " " << t(2) << " " << R(0,0) << " " << R(0,1) << " " << R(0,2) << " " << R(1,0) << " " << R(1,1) << " " << R(1,2) << " " << R(2,0) << " " << R(2,1) << " " << R(2,2) << "\n" - << K(0,0) / largerDim << " 0 0 1 " << K(0,2) / cam->w() << " " << K(1,2) / cam->h(); + << f / largerDim << " 0 0 1 " << pp(0) / w << " " << pp(1) / h; outfile.close(); if(cam->have_disto()) From c1adec1373a436b6989db2a998e68766ec1f9d4b Mon Sep 17 00:00:00 2001 From: Romain Janvier Date: Wed, 27 May 2015 01:15:36 +0200 Subject: [PATCH 42/52] Clean an isolated debug message --- src/software/SfM/main_openMVG2MVSTEXTURING.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/software/SfM/main_openMVG2MVSTEXTURING.cpp b/src/software/SfM/main_openMVG2MVSTEXTURING.cpp index 7571a11bae..5e91724cd7 100644 --- a/src/software/SfM/main_openMVG2MVSTEXTURING.cpp +++ b/src/software/SfM/main_openMVG2MVSTEXTURING.cpp @@ -84,8 +84,6 @@ int main(int argc, char **argv) const double f = pinhole_cam->focal(); const Vec2 pp = pinhole_cam->principal_point(); - std::cout << "++++" << pp << std::endl; - // Image size in px const int w = pinhole_cam->w(); const int h = pinhole_cam->h(); From 1e06fa79727f52ae17c475b8605ffe2c95b8e600 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Wed, 27 May 2015 13:58:19 +0200 Subject: [PATCH 43/52] Make ceres non linear mimization run in DENSE mode if no sparse back end are detected. --- .../multiview/rotation_averaging_l2.cpp | 11 +++++++++- .../translation_averaging_solver.cpp | 16 +++++++++++--- src/openMVG/sfm/sfm_data_BA_ceres.cpp | 21 +++++++++++++++++-- .../ceres-solver/internal/ceres/types.cc | 8 +++++++ 4 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/openMVG/multiview/rotation_averaging_l2.cpp b/src/openMVG/multiview/rotation_averaging_l2.cpp index da92f8f724..853a5a2da1 100644 --- a/src/openMVG/multiview/rotation_averaging_l2.cpp +++ b/src/openMVG/multiview/rotation_averaging_l2.cpp @@ -256,7 +256,16 @@ bool L2RotationAveraging_Refine( } ceres::Solver::Options solverOptions; // Since the problem is sparse, use a sparse solver - solverOptions.linear_solver_type = ceres::SPARSE_NORMAL_CHOLESKY; + if (ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::SUITE_SPARSE) || + ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::CX_SPARSE) || + ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::EIGEN_SPARSE)) + { + solverOptions.linear_solver_type = ceres::SPARSE_NORMAL_CHOLESKY; + } + else + { + solverOptions.linear_solver_type = ceres::DENSE_NORMAL_CHOLESKY; + } #ifdef OPENMVG_USE_OPENMP solverOptions.num_threads = omp_get_max_threads(); solverOptions.num_linear_solver_threads = omp_get_max_threads(); diff --git a/src/openMVG/multiview/translation_averaging_solver.cpp b/src/openMVG/multiview/translation_averaging_solver.cpp index 459b1fb101..a413aa8cb3 100644 --- a/src/openMVG/multiview/translation_averaging_solver.cpp +++ b/src/openMVG/multiview/translation_averaging_solver.cpp @@ -35,7 +35,8 @@ #include "openMVG/multiview/translation_averaging_solver.hpp" #include "ceres/ceres.h" - + +#include #include #include #include @@ -128,8 +129,17 @@ bool solve_translations_problem( //options.minimizer_progress_to_stdout = true; options.max_num_iterations = max_iterations; options.function_tolerance = function_tolerance; - options.parameter_tolerance = parameter_tolerance; - options.linear_solver_type = ceres::SPARSE_NORMAL_CHOLESKY; + options.parameter_tolerance = parameter_tolerance; + if (ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::SUITE_SPARSE) || + ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::CX_SPARSE) || + ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::EIGEN_SPARSE)) + { + options.linear_solver_type = ceres::SPARSE_NORMAL_CHOLESKY; + } + else + { + options.linear_solver_type = ceres::DENSE_NORMAL_CHOLESKY; + } Solver::Summary summary; Solve(options, &problem, &summary); diff --git a/src/openMVG/sfm/sfm_data_BA_ceres.cpp b/src/openMVG/sfm/sfm_data_BA_ceres.cpp index 37b9adfe22..2314267033 100644 --- a/src/openMVG/sfm/sfm_data_BA_ceres.cpp +++ b/src/openMVG/sfm/sfm_data_BA_ceres.cpp @@ -49,13 +49,30 @@ Bundle_Adjustment_Ceres::BA_options::BA_options(const bool bVerbose, bool bmulti _bCeres_Summary = false; - _linear_solver_type = ceres::SPARSE_SCHUR; + // Default configuration use a DENSE representation + _linear_solver_type = ceres::DENSE_SCHUR; _preconditioner_type = ceres::JACOBI; - if (ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::SUITE_SPARSE)) + // If Sparse linear solver are available + // Descending priority order by efficiency (SUITE_SPARSE > CX_SPARSE > EIGEN_SPARSE) + if (ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::SUITE_SPARSE)) + { _sparse_linear_algebra_library_type = ceres::SUITE_SPARSE; + _linear_solver_type = ceres::SPARSE_SCHUR; + } else + { if (ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::CX_SPARSE)) + { _sparse_linear_algebra_library_type = ceres::CX_SPARSE; + _linear_solver_type = ceres::SPARSE_SCHUR; + } + else + if (ceres::IsSparseLinearAlgebraLibraryTypeAvailable(ceres::EIGEN_SPARSE)) + { + _sparse_linear_algebra_library_type = ceres::EIGEN_SPARSE; + _linear_solver_type = ceres::SPARSE_SCHUR; + } + } } diff --git a/src/third_party/ceres-solver/internal/ceres/types.cc b/src/third_party/ceres-solver/internal/ceres/types.cc index 47102616ee..0a0907f688 100644 --- a/src/third_party/ceres-solver/internal/ceres/types.cc +++ b/src/third_party/ceres-solver/internal/ceres/types.cc @@ -338,6 +338,14 @@ bool IsSparseLinearAlgebraLibraryTypeAvailable( #endif } + if (type == EIGEN_SPARSE) { +#ifdef CERES_USE_EIGEN_SPARSE + return true; +#else + return false; +#endif + } + LOG(WARNING) << "Unknown sparse linear algebra library " << type; return false; } From ec006ff46c970d25aff7df9698b68f1adf47d4c1 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Wed, 27 May 2015 14:01:30 +0200 Subject: [PATCH 44/52] WIP to install OpenMVG and use it as a third party library. #222 --- BUILD | 4 +- src/CMakeLists.txt | 170 ++++++++++++++---- src/cmakeFindModules/FindEigen.cmake | 59 ++++++ src/cmakeFindModules/FindOpenMVG.cmake | 2 +- src/cmakeFindModules/OpenMVGConfig.cmake.in | 109 +++++++++++ src/dependencies/osi_clp | 2 +- .../matching_cascade_hashing/CMakeLists.txt | 9 +- src/nonFree/sift/CMakeLists.txt | 1 + src/openMVG/features/CMakeLists.txt | 1 + src/openMVG/image/CMakeLists.txt | 2 +- src/openMVG/linearProgramming/CMakeLists.txt | 2 +- .../lInfinityCV/CMakeLists.txt | 2 +- src/openMVG/matching/kvld/CMakeLists.txt | 2 +- .../matching_image_collection/CMakeLists.txt | 2 +- src/openMVG/multiview/CMakeLists.txt | 2 +- src/openMVG/numeric/CMakeLists.txt | 2 +- src/openMVG/sfm/CMakeLists.txt | 4 +- src/openMVG/system/CMakeLists.txt | 3 +- .../image_describer_matches/CMakeLists.txt | 7 +- .../robust_essential/CMakeLists.txt | 2 +- .../robust_essential_ba/CMakeLists.txt | 2 +- .../undisto_Brown/CMakeLists.txt | 2 +- src/software/SfM/CMakeLists.txt | 62 +++---- src/software/SfMViewer/CMakeLists.txt | 2 +- src/software/colorHarmonize/CMakeLists.txt | 3 +- src/third_party/CMakeLists.txt | 41 +++-- src/third_party/ceres-solver/CMakeLists.txt | 23 ++- .../internal/ceres/CMakeLists.txt | 5 + src/third_party/cxsparse/CMakeLists.txt | 4 +- src/third_party/easyexif/CMakeLists.txt | 4 +- src/third_party/flann/src/cpp/CMakeLists.txt | 2 + src/third_party/jpeg/CMakeLists.txt | 2 +- src/third_party/lemon/CMakeLists.txt | 1 + src/third_party/lemon/lemon/CMakeLists.txt | 21 ++- src/third_party/png/CMakeLists.txt | 2 +- src/third_party/stlplus3/CMakeLists.txt | 1 + src/third_party/tiff/CMakeLists.txt | 2 +- src/third_party/zlib/CMakeLists.txt | 2 +- 38 files changed, 431 insertions(+), 137 deletions(-) create mode 100644 src/cmakeFindModules/FindEigen.cmake create mode 100644 src/cmakeFindModules/OpenMVGConfig.cmake.in diff --git a/BUILD b/BUILD index abd11ec6db..fd82a72b12 100644 --- a/BUILD +++ b/BUILD @@ -130,6 +130,6 @@ Adding following lines to your CMakeLists.txt should provide OpenMVG usable as static library: add_subdirectory(openMVG/src) - include_directories(${OpenMVG_INCLUDES}) - target_link_libraries(target ${OpenMVG_LIBS}) + include_directories(${OpenMVG_INCLUDE_DIRS}) + target_link_libraries(target ${OpenMVG_LIBRARIES}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 33fd4c4feb..1598732699 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,12 +18,18 @@ ENDIF() # OpenMVG build options # ============================================================================== OPTION(OpenMVG_BUILD_TESTS "Build OpenMVG tests" OFF) -OPTION(OpenMVG_BUILD_EXAMPLES "Build OpenMVG example applications. Does not affect binaries under 'software'" ON) +OPTION(OpenMVG_BUILD_EXAMPLES "Build OpenMVG samples applications." ON) OPTION(OpenMVG_BUILD_OPENGL_EXAMPLES "Build OpenMVG openGL examples" OFF) OPTION(OpenMVG_BUILD_COVERAGE "Enable code coverage generation (gcc only)" OFF) OPTION(OpenMVG_USE_OPENMP "Enable OpenMP parallelization" ON) -# By default build in Release mode +SET(OPENMVG_VERSION_MAJOR 0) +SET(OPENMVG_VERSION_MINOR 9) +SET(OPENMVG_VERSION_PATCH 0) +SET(OPENMVG_VERSION + ${OPENMVG_VERSION_MAJOR}.${OPENMVG_VERSION_MINOR}.${OPENMVG_VERSION_PATCH}) + +# Default build is in Release mode IF(NOT CMAKE_BUILD_TYPE AND NOT MSVC) SET(CMAKE_BUILD_TYPE "Release") ENDIF(NOT CMAKE_BUILD_TYPE AND NOT MSVC) @@ -124,11 +130,12 @@ IF (OpenMVG_BUILD_OPENGL_EXAMPLES) SET(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "Do not build the GLFW example programs") SET(GLFW_BUILD_TESTS OFF CACHE BOOL "Do not build the GLFW tests programs") SET(GLFW_BUILD_DOCS OFF CACHE BOOL "Do not build the GLFW documentation") + SET(GLFW_INSTALL OFF CACHE BOOL "Do not generate the GLFW installation target") ADD_SUBDIRECTORY(dependencies/glfw) INCLUDE_DIRECTORIES(SYSTEM dependencies/glfw/include) SET_PROPERTY(TARGET glfw PROPERTY FOLDER OpenMVG/3rdParty/glfw) - SET_PROPERTY(TARGET uninstall PROPERTY FOLDER OpenMVG/3rdParty/glfw) ENDIF (OpenMVG_BUILD_OPENGL_EXAMPLES) + #=============================== #---- LINEAR PROGRAMMING SOLVER #=============================== @@ -138,10 +145,11 @@ ENDIF (OpenMVG_BUILD_OPENGL_EXAMPLES) FIND_PACKAGE(Mosek) IF(MOSEK_FOUND) ADD_DEFINITIONS(-DOPENMVG_HAVE_MOSEK) - INCLUDE_DIRECTORIES( + SET(LP_INCLUDE_DIRS ${MOSEK_INCLUDE} - ./dependencies/osi_clp/Osi/src/OsiMsk/ + ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/osi_clp/Osi/src/OsiMsk/ ) + INCLUDE_DIRECTORIES(${LP_INCLUDE_DIRS}) ENDIF(MOSEK_FOUND) #- osi_clp (linear programming interface) @@ -152,21 +160,33 @@ if(NOT EXISTS ${PROJECT_SOURCE_DIR}/dependencies/osi_clp/Clp) " > git submodule update -i\n") endif() ADD_SUBDIRECTORY(dependencies/osi_clp) -INCLUDE_DIRECTORIES( - ./dependencies/osi_clp/CoinUtils/src/ - ./dependencies/osi_clp/Clp/src/ - ./dependencies/osi_clp/Osi/src/Osi/ - ./dependencies/osi_clp/Clp/src/OsiClp/ +SET(LP_INCLUDE_DIRS "${LP_INCLUDE_DIRS}" + ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/osi_clp/CoinUtils/src/ + ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/osi_clp/Clp/src/ + ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/osi_clp/Osi/src/Osi/ + ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/osi_clp/Clp/src/OsiClp/ ) +INCLUDE_DIRECTORIES(${LP_INCLUDE_DIRS}) SET_PROPERTY(TARGET lib_CoinUtils PROPERTY FOLDER OpenMVG/3rdParty/osi_clp) SET_PROPERTY(TARGET lib_Osi PROPERTY FOLDER OpenMVG/3rdParty/osi_clp) SET_PROPERTY(TARGET lib_OsiClpSolver PROPERTY FOLDER OpenMVG/3rdParty/osi_clp) SET_PROPERTY(TARGET lib_clp PROPERTY FOLDER OpenMVG/3rdParty/osi_clp) -#=============================== -#--END-- LINEAR PROGRAMMING SOLVER -#=============================== +# ================================= +# --END-- LINEAR PROGRAMMING SOLVER +# ================================= + +#INSTALL RULES +INSTALL( + DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/ + DESTINATION include/openMVG_dependencies + COMPONENT headers + FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h" +) +# ============================================================================== +# --END-- SUBMODULE CONFIGURATION +# ============================================================================== # ============================================================================== # Opencv is not used by openMVG but some samples show how to use openCV @@ -195,9 +215,43 @@ MACRO (UNIT_TEST NAMESPACE NAME EXTRA_LIBS) ENDIF (OpenMVG_BUILD_TESTS) ENDMACRO (UNIT_TEST) +# ============================================================================== +# Eigen +# ============================================================================== +# - internal by default, +# - external if EIGEN_INCLUDE_DIR_HINTS is defined +# ============================================================================== +IF(NOT DEFINED EIGEN_INCLUDE_DIR_HINTS) + SET(EIGEN_INCLUDE_DIR_HINTS ${CMAKE_CURRENT_SOURCE_DIR}/third_party/eigen) + SET(OpenMVG_USE_INTERNAL_EIGEN ON) +ENDIF() +FIND_PACKAGE(Eigen QUIET) +IF(EIGEN_FOUND) + INCLUDE_DIRECTORIES(${EIGEN_INCLUDE_DIRS}) +ENDIF(EIGEN_FOUND) + # Configure Eigen to use only MPL2 licensed code ADD_DEFINITIONS(-DEIGEN_MPL2_ONLY) +# ============================================================================== +# Ceres +# ============================================================================== +# - internal by default (ceres-solver+cxsparse+miniglog), +# - external if CERES_DIR_HINTS and FIND_PACKAGE return a valid Ceres setup +# ============================================================================== +FIND_PACKAGE(Ceres QUIET HINTS ${CERES_DIR_HINTS}) +IF(Ceres_FOUND) + MESSAGE("CERES FOUND") +ELSE() + MESSAGE("CERES NOT FOUND") + SET(OpenMVG_USE_INTERNAL_CERES ON) + SET(CERES_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/third_party/ceres-solver/include + ${CMAKE_CURRENT_SOURCE_DIR}/third_party/ceres-solver/internal/ceres/miniglog + ${PROJECT_BINARY_DIR}/third_party/ceres-solver/config) + SET(CERES_LIBRARIES ceres cxsparse) +ENDIF(Ceres_FOUND) + # ============================================================================== # Third-party libraries: # ============================================================================== @@ -206,24 +260,23 @@ ADD_SUBDIRECTORY(third_party) # ============================================================================== # Include directories # ============================================================================== -SET(OpenMVG_INCLUDES +SET(OpenMVG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/third_party ${JPEG_INCLUDE_DIR} ${PNG_INCLUDE_DIRS} ${TIFF_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/cereal/include - ${CMAKE_CURRENT_SOURCE_DIR}/third_party/eigen ${CMAKE_CURRENT_SOURCE_DIR}/third_party/lemon ${PROJECT_BINARY_DIR}/third_party/lemon - ${CMAKE_CURRENT_SOURCE_DIR}/third_party/ceres-solver/include - ${CMAKE_CURRENT_SOURCE_DIR}/third_party/ceres-solver/internal/ceres/miniglog - ${PROJECT_BINARY_DIR}/third_party/ceres-solver/config + ${EIGEN_INCLUDE_DIRS} + ${CERES_INCLUDE_DIRS} + ${LP_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/third_party/flann/src/cpp CACHE PATH "include directories for openMVG and its dependencies" ) -INCLUDE_DIRECTORIES(${OpenMVG_INCLUDES}) +INCLUDE_DIRECTORIES(${OpenMVG_INCLUDE_DIRS}) # ============================================================================== # openMVG modules @@ -231,37 +284,34 @@ INCLUDE_DIRECTORIES(${OpenMVG_INCLUDES}) # The openMVG library itself ADD_SUBDIRECTORY(openMVG) -# software under patent or commercial licence -# Included for research purpose only -ADD_SUBDIRECTORY(nonFree) - # ============================================================================== # openMVG libraries # ============================================================================== -SET(OpenMVG_LIBS +SET(OpenMVG_LIBRARIES openMVG_image openMVG_features openMVG_matching_image_collection + openMVG_kvld openMVG_multiview openMVG_lInftyComputerVision openMVG_system openMVG_sfm) -FOREACH(omvglib ${OpenMVG_LIBS}) +FOREACH(omvglib ${OpenMVG_LIBRARIES}) SET_PROPERTY(TARGET ${omvglib} PROPERTY FOLDER OpenMVG/OpenMVG) ENDFOREACH() -# concat lists -SET(OpenMVG_LIBS "${OpenMVG_LIBS}" ${openMVG_linearProgramming}) #third_party libs -SET(OpenMVG_LIBS "${OpenMVG_LIBS}" +SET(OpenMVG_LIBRARIES + "${OpenMVG_LIBRARIES}" + "${openMVG_linearProgramming}" vlsift stlplus flann_cpp_s - ceres + ${CERES_LIBRARIES} lemon easyexif) -SET(OpenMVG_LIBS "${OpenMVG_LIBS}" +SET(OpenMVG_LIBRARIES "${OpenMVG_LIBRARIES}" ${OPENMVG_LIBRARY_DEPENDENCIES} CACHE STRING "openMVG library names") # openMVG tutorial examples @@ -269,9 +319,13 @@ IF (OpenMVG_BUILD_EXAMPLES) ADD_SUBDIRECTORY(openMVG_Samples) ENDIF (OpenMVG_BUILD_EXAMPLES) -# Complete software build on openMVG +# Complete software(s) build on openMVG libraries ADD_SUBDIRECTORY(software) +# software(s) under patent or commercial licence +# Included for research purpose only +ADD_SUBDIRECTORY(nonFree) + # ============================================================================== # Documentation # -------------------------- @@ -298,3 +352,57 @@ IF (EXISTS ${SPHINX_EXECUTABLE}) ELSE (EXISTS ${SPHINX_EXECUTABLE}) MESSAGE("Sphinx need to be installed to generate the documentation") ENDIF (EXISTS ${SPHINX_EXECUTABLE}) + + +# ============================================================================== +# INSTALL RULES +# ============================================================================== + +INSTALL(EXPORT openMVG-targets DESTINATION lib) +INSTALL(EXPORT openMVG-targets + DESTINATION share/openMVG/cmake FILE OpenMVGTargets.cmake) + +#Adapt build include paths to install path +SET(OpenMVG_INCLUDE_DIRS + "${OpenMVG_INCLUDE_DIRS}" + "${CMAKE_INSTALL_PREFIX}/include/openMVG") + +STRING(REGEX REPLACE + "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_INSTALL_PREFIX}/include" + OpenMVG_INCLUDE_DIRS + "${OpenMVG_INCLUDE_DIRS}" +) +STRING(REGEX REPLACE + "third_party" + "openMVG/third_party" + OpenMVG_INCLUDE_DIRS + "${OpenMVG_INCLUDE_DIRS}" +) +STRING(REGEX REPLACE + "dependencies" + "openMVG_dependencies" + OpenMVG_INCLUDE_DIRS + "${OpenMVG_INCLUDE_DIRS}" +) +STRING(REGEX REPLACE + "ceres-solver" + "ceres" + OpenMVG_INCLUDE_DIRS + "${OpenMVG_INCLUDE_DIRS}" +) + +# Create a OpenMVGConfig.cmake file. Config.cmake files are searched by +# FIND_PACKAGE() automatically. We configure that file so that we can put any +# information we want in it, e.g. version numbers, include directories, etc. +CONFIGURE_FILE("${CMAKE_SOURCE_DIR}/cmakeFindModules/OpenMVGConfig.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/OpenMVGConfig.cmake" @ONLY) + +IF(UNIX) + INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/OpenMVGConfig.cmake" + DESTINATION share/openMVG/cmake) +ELSEIF(WIN32) + INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/OpenMVGConfig.cmake" + DESTINATION cmake) +ENDIF() + diff --git a/src/cmakeFindModules/FindEigen.cmake b/src/cmakeFindModules/FindEigen.cmake new file mode 100644 index 0000000000..c33a9b46b6 --- /dev/null +++ b/src/cmakeFindModules/FindEigen.cmake @@ -0,0 +1,59 @@ +########################################################### +# Find EIGEN Library +#---------------------------------------------------------- + +FIND_PATH(EIGEN_DIR "Eigen/Core" + HINTS "${EIGEN_ROOT}" "$ENV{EIGEN_ROOT}" "${EIGEN_INCLUDE_DIR_HINTS}" + PATHS "$ENV{PROGRAMFILES}/Eigen" "$ENV{PROGRAMW6432}/Eigen" "/usr" "/usr/local" + PATH_SUFFIXES eigen3 include/eigen3 include + DOC "Root directory of EIGEN library") + +##==================================================== +## Include EIGEN library +##---------------------------------------------------- +if(EXISTS "${EIGEN_DIR}" AND NOT "${EIGEN_DIR}" STREQUAL "") + SET(EIGEN_FOUND TRUE) + SET(EIGEN_INCLUDE_DIRS ${EIGEN_DIR}) + SET(EIGEN_DIR "${EIGEN_DIR}" CACHE PATH "" FORCE) + MARK_AS_ADVANCED(EIGEN_DIR) + + # Extract Eigen version from Eigen/src/Core/util/Macros.h + SET(EIGEN_VERSION_FILE ${EIGEN_INCLUDE_DIRS}/Eigen/src/Core/util/Macros.h) + IF (NOT EXISTS ${EIGEN_VERSION_FILE}) + EIGEN_REPORT_NOT_FOUND( + "Could not find file: ${EIGEN_VERSION_FILE} " + "containing version information in Eigen install located at: " + "${EIGEN_INCLUDE_DIRS}.") + ELSE (NOT EXISTS ${EIGEN_VERSION_FILE}) + FILE(READ ${EIGEN_VERSION_FILE} EIGEN_VERSION_FILE_CONTENTS) + + STRING(REGEX MATCH "#define EIGEN_WORLD_VERSION [0-9]+" + EIGEN_WORLD_VERSION "${EIGEN_VERSION_FILE_CONTENTS}") + STRING(REGEX REPLACE "#define EIGEN_WORLD_VERSION ([0-9]+)" "\\1" + EIGEN_WORLD_VERSION "${EIGEN_WORLD_VERSION}") + + STRING(REGEX MATCH "#define EIGEN_MAJOR_VERSION [0-9]+" + EIGEN_MAJOR_VERSION "${EIGEN_VERSION_FILE_CONTENTS}") + STRING(REGEX REPLACE "#define EIGEN_MAJOR_VERSION ([0-9]+)" "\\1" + EIGEN_MAJOR_VERSION "${EIGEN_MAJOR_VERSION}") + + STRING(REGEX MATCH "#define EIGEN_MINOR_VERSION [0-9]+" + EIGEN_MINOR_VERSION "${EIGEN_VERSION_FILE_CONTENTS}") + STRING(REGEX REPLACE "#define EIGEN_MINOR_VERSION ([0-9]+)" "\\1" + EIGEN_MINOR_VERSION "${EIGEN_MINOR_VERSION}") + + # This is on a single line s/t CMake does not interpret it as a list of + # elements and insert ';' separators which would result in 3.;2.;0 nonsense. + SET(EIGEN_VERSION "${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION}") + ENDIF (NOT EXISTS ${EIGEN_VERSION_FILE}) + SET(EIGEN_INCLUDE_DIR ${EIGEN_DIR}) + + MESSAGE(STATUS "Eigen ${EIGEN_VERSION} found (include: ${EIGEN_INCLUDE_DIRS})") +else() + MESSAGE(FATAL_ERROR "You are attempting to build without Eigen. " + "Please use cmake variable -DEIGEN_INCLUDE_DIR_HINTS:STRING=\"PATH\" " + "or EIGEN_INCLUDE_DIR_HINTS env. variable to a valid Eigen path. " + "Or install last Eigen version.") + package_report_not_found(EIGEN "Eigen cannot be found") +endif() +##==================================================== diff --git a/src/cmakeFindModules/FindOpenMVG.cmake b/src/cmakeFindModules/FindOpenMVG.cmake index 4bd583802e..12f23d7e52 100644 --- a/src/cmakeFindModules/FindOpenMVG.cmake +++ b/src/cmakeFindModules/FindOpenMVG.cmake @@ -15,7 +15,7 @@ MESSAGE(STATUS "Looking for OpenMVG.") -FIND_PATH(OPENMVG_INCLUDE_DIR openMVG/version.h +FIND_PATH(OPENMVG_INCLUDE_DIR openMVG/version.hpp HINTS $ENV{OPENMVG_DIR}/include ${OPENMVG_DIR}/include diff --git a/src/cmakeFindModules/OpenMVGConfig.cmake.in b/src/cmakeFindModules/OpenMVGConfig.cmake.in new file mode 100644 index 0000000000..500c11e66b --- /dev/null +++ b/src/cmakeFindModules/OpenMVGConfig.cmake.in @@ -0,0 +1,109 @@ + +# Copyright (c) 2015 Pierre MOULON. + +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +# Config file for OpenMVG libary - Find OpenMVG & dependencies. +# +# This file is used by CMake when FIND_PACKAGE( OpenMVG ) is invoked (and +# the directory containing this file is present in CMAKE_MODULE_PATH). +# +# This module defines the following variables: +# +# OPENMVG_FOUND: True if OpenMVG has been successfully found. +# +# OPENMVG_VERSION: Version of OpenMVG found. +# +# OPENMVG_INCLUDE_DIRS: Include directories for OpenMVG and the +# dependencies which appear in the OpenMVG public +# API and are thus required to use OpenMVG. +# +# OPENMVG_LIBRARIES: Libraries for OpenMVG and all +# dependencies against which OpenMVG was +# compiled. + +# Called if we failed to find Ceres or any of it's required dependencies, +# unsets all public (designed to be used externally) variables and reports +# error message at priority depending upon [REQUIRED/QUIET/] argument. +MACRO(OPENMVG_REPORT_NOT_FOUND REASON_MSG) + # FindPackage() only references Ceres_FOUND, and requires it to be + # explicitly set FALSE to denote not found (not merely undefined). + SET(OPENMVG_FOUND FALSE) + UNSET(OPENMVG_INCLUDE_DIRS) + UNSET(OPENMVG_LIBRARIES) + + # Reset the CMake module path to its state when this script was called. + SET(CMAKE_MODULE_PATH ${CALLERS_CMAKE_MODULE_PATH}) + + # Note _FIND_[REQUIRED/QUIETLY] variables defined by + # FindPackage() use the camelcase library name, not uppercase. + IF (OPENMVG_FIND_QUIETLY) + MESSAGE(STATUS "Failed to find OPENMVG - " ${REASON_MSG} ${ARGN}) + ELSE (OPENMVG_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Failed to find OPENMVG - " ${REASON_MSG} ${ARGN}) + ELSE() + # Neither QUIETLY nor REQUIRED, use SEND_ERROR which emits an error + # that prevents generation, but continues configuration. + MESSAGE(SEND_ERROR "Failed to find OPENMVG - " ${REASON_MSG} ${ARGN}) + ENDIF () + RETURN() +ENDMACRO(OPENMVG_REPORT_NOT_FOUND) + +# Set the version. +SET(OPENMVG_VERSION @OPENMVG_VERSION@) + +# Get the (current, i.e. installed) directory containing this file. +GET_FILENAME_COMPONENT(CURRENT_CONFIG_INSTALL_DIR + "${CMAKE_CURRENT_LIST_FILE}" PATH) + +# Record the state of the CMake module path when this script was +# called so that we can ensure that we leave it in the same state on +# exit as it was on entry, but modify it locally. +SET(CALLERS_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}) +# Reset CMake module path to the installation directory of this +# script. +SET(CMAKE_MODULE_PATH ${CURRENT_CONFIG_INSTALL_DIR}) + +# Build the absolute root install directory as a relative path +GET_FILENAME_COMPONENT(CURRENT_ROOT_INSTALL_DIR + ${CMAKE_MODULE_PATH}/../../../ ABSOLUTE) +IF (NOT EXISTS ${CURRENT_ROOT_INSTALL_DIR}) + OPENMVG_REPORT_NOT_FOUND( + "OpenMVG install root: ${CURRENT_ROOT_INSTALL_DIR}, " + "determined from relative path from OpenMVGConfig.cmake install location: " + "${CMAKE_MODULE_PATH}, does not exist.") +ENDIF (NOT EXISTS ${CURRENT_ROOT_INSTALL_DIR}) + +# Check if OpenMVG header is installed +IF (NOT EXISTS ${CURRENT_ROOT_INSTALL_DIR}/include/openMVG/version.hpp) + OPENMVG_REPORT_NOT_FOUND( + "OpenMVG install root: ${CMAKE_MODULE_PATH}. " + "Cannot find openMVG include files.") +ENDIF (NOT EXISTS ${CURRENT_ROOT_INSTALL_DIR}/include/openMVG/version.hpp) + +# Set the include directories for OpenMVG (itself) and all (potentially optional) +# dependencies with which OpenMVG was compiled. +SET(OPENMVG_INCLUDE_DIRS @OpenMVG_INCLUDE_DIRS@) + +##### the libraries themselves come in via OpenMVGTargets-.cmake +# as link libraries rules as target. + +# Import exported OpenMVG targets +SET(OPENMVG_LIBRARIES @OpenMVG_LIBRARIES@) +INCLUDE(${CURRENT_CONFIG_INSTALL_DIR}/OpenMVGTargets.cmake) + +# As we use OPENMVG_REPORT_NOT_FOUND() to abort, if we reach this point we have +# found OpenMVG and all required dependencies. +MESSAGE(STATUS "----") +MESSAGE(STATUS "OpenMVG Find_Package") +MESSAGE(STATUS "----") +MESSAGE(STATUS "Found OpenMVG version: ${OPENMVG_VERSION}") +MESSAGE(STATUS "Installed in: ${CURRENT_ROOT_INSTALL_DIR}") +MESSAGE(STATUS "Used OpenMVG libraries: ${OPENMVG_LIBRARIES}") +MESSAGE(STATUS "----") + +SET(OPENMVG_FOUND TRUE) + diff --git a/src/dependencies/osi_clp b/src/dependencies/osi_clp index df7c43f4a4..d686a8f919 160000 --- a/src/dependencies/osi_clp +++ b/src/dependencies/osi_clp @@ -1 +1 @@ -Subproject commit df7c43f4a4ed3980d233d742224140802dfbc7cb +Subproject commit d686a8f919b93e8302e6b2c9b193fc997003fd88 diff --git a/src/nonFree/matching_cascade_hashing/CMakeLists.txt b/src/nonFree/matching_cascade_hashing/CMakeLists.txt index 9737d78c04..14262ad68c 100644 --- a/src/nonFree/matching_cascade_hashing/CMakeLists.txt +++ b/src/nonFree/matching_cascade_hashing/CMakeLists.txt @@ -10,13 +10,6 @@ ADD_EXECUTABLE(openMVG_main_computeMatchesCasHas Matcher_CascadeHashing.hpp ) TARGET_LINK_LIBRARIES(openMVG_main_computeMatchesCasHas - openMVG_image - openMVG_features - openMVG_multiview - openMVG_system - openMVG_sfm - vlsift - stlplus - ${OpenMVG_LIBS}) + ${OpenMVG_LIBRARIES}) SET_PROPERTY(TARGET openMVG_main_computeMatchesCasHas PROPERTY FOLDER OpenMVG/nonFree/software) diff --git a/src/nonFree/sift/CMakeLists.txt b/src/nonFree/sift/CMakeLists.txt index f7c38af628..1550eb20fe 100644 --- a/src/nonFree/sift/CMakeLists.txt +++ b/src/nonFree/sift/CMakeLists.txt @@ -12,4 +12,5 @@ SET(FEATS vl/random.c) SET_SOURCE_FILES_PROPERTIES(${FEATS} PROPERTIES LANGUAGE C) ADD_LIBRARY(vlsift ${FEATS}) +INSTALL(TARGETS vlsift DESTINATION lib EXPORT openMVG-targets) SET_PROPERTY(TARGET vlsift PROPERTY FOLDER OpenMVG/nonFree) diff --git a/src/openMVG/features/CMakeLists.txt b/src/openMVG/features/CMakeLists.txt index 05f6583ec5..4c71155d22 100644 --- a/src/openMVG/features/CMakeLists.txt +++ b/src/openMVG/features/CMakeLists.txt @@ -19,6 +19,7 @@ list(REMOVE_ITEM features_files_sources ${REMOVEFILESUNITTEST}) set_source_files_properties(${features_files_sources} PROPERTIES LANGUAGE CXX) ADD_LIBRARY(openMVG_features ${features_files_sources} ${features_files_headers}) +INSTALL(TARGETS openMVG_features DESTINATION lib EXPORT openMVG-targets) SET_PROPERTY(TARGET openMVG_features PROPERTY FOLDER OpenMVG/OpenMVG) UNIT_TEST(openMVG features "openMVG_features") diff --git a/src/openMVG/image/CMakeLists.txt b/src/openMVG/image/CMakeLists.txt index 0c8331f9bf..dbea7ca15a 100644 --- a/src/openMVG/image/CMakeLists.txt +++ b/src/openMVG/image/CMakeLists.txt @@ -18,7 +18,7 @@ list(REMOVE_ITEM image_files_cpp ${REMOVEFILESUNITTEST}) ADD_LIBRARY(openMVG_image ${image_files_header} ${image_files_cpp}) TARGET_LINK_LIBRARIES(openMVG_image ${PNG_LIBRARIES} ${JPEG_LIBRARY} ${TIFF_LIBRARIES} openMVG_numeric) -INSTALL(TARGETS openMVG_image DESTINATION lib/) +INSTALL(TARGETS openMVG_image DESTINATION lib EXPORT openMVG-targets) UNIT_TEST(openMVG image "openMVG_image") UNIT_TEST(openMVG image_drawing "openMVG_image") diff --git a/src/openMVG/linearProgramming/CMakeLists.txt b/src/openMVG/linearProgramming/CMakeLists.txt index 2580ab15d7..74d83f71c0 100644 --- a/src/openMVG/linearProgramming/CMakeLists.txt +++ b/src/openMVG/linearProgramming/CMakeLists.txt @@ -32,7 +32,7 @@ ELSE (NOT MOSEK_FOUND) # MOSEK_FOUND is true ADD_LIBRARY(openMVG_linearProgrammingMSK ${linearProgramming_headers} ${linearProgramming_cpp}) SET_PROPERTY(TARGET openMVG_linearProgrammingMSK PROPERTY FOLDER OpenMVG/OpenMVG) - INSTALL(TARGETS openMVG_linearProgrammingMSK DESTINATION lib/) + INSTALL(TARGETS openMVG_linearProgrammingMSK DESTINATION lib EXPORT openMVG-targets) SET(openMVG_linearProgramming lib_Osi_Msk # OSI solver wrapper for the Mosek backend diff --git a/src/openMVG/linearProgramming/lInfinityCV/CMakeLists.txt b/src/openMVG/linearProgramming/lInfinityCV/CMakeLists.txt index fad155ef4e..8004b97b7c 100644 --- a/src/openMVG/linearProgramming/lInfinityCV/CMakeLists.txt +++ b/src/openMVG/linearProgramming/lInfinityCV/CMakeLists.txt @@ -23,7 +23,7 @@ IF (MSVC) ENDIF (MSVC) ADD_LIBRARY(openMVG_lInftyComputerVision ${lInftycomputervision_headers} ${lInftycomputervision_cpp}) -INSTALL(TARGETS openMVG_lInftyComputerVision DESTINATION lib/) +INSTALL(TARGETS openMVG_lInftyComputerVision DESTINATION lib EXPORT openMVG-targets) SET(LOCAL_LIBS openMVG_multiview_test_data diff --git a/src/openMVG/matching/kvld/CMakeLists.txt b/src/openMVG/matching/kvld/CMakeLists.txt index f6e0f8f965..e2327afc2e 100644 --- a/src/openMVG/matching/kvld/CMakeLists.txt +++ b/src/openMVG/matching/kvld/CMakeLists.txt @@ -1,4 +1,4 @@ ADD_LIBRARY(openMVG_kvld kvld.cpp kvld.h algorithm.cpp algorithm.h) SET_PROPERTY(TARGET openMVG_kvld PROPERTY FOLDER OpenMVG/OpenMVG) -INSTALL(TARGETS openMVG_kvld DESTINATION lib/) \ No newline at end of file +INSTALL(TARGETS openMVG_kvld DESTINATION lib EXPORT openMVG-targets) diff --git a/src/openMVG/matching_image_collection/CMakeLists.txt b/src/openMVG/matching_image_collection/CMakeLists.txt index 1cf716f79f..ac1b228308 100644 --- a/src/openMVG/matching_image_collection/CMakeLists.txt +++ b/src/openMVG/matching_image_collection/CMakeLists.txt @@ -18,6 +18,6 @@ ADD_LIBRARY(openMVG_matching_image_collection ${matching_collection_images_files_header} ${matching_collection_images_files_cpp}) SET_PROPERTY(TARGET openMVG_matching_image_collection PROPERTY FOLDER OpenMVG) -INSTALL(TARGETS openMVG_matching_image_collection DESTINATION lib/) +INSTALL(TARGETS openMVG_matching_image_collection DESTINATION lib EXPORT openMVG-targets) UNIT_TEST(openMVG Pair_Builder "") diff --git a/src/openMVG/multiview/CMakeLists.txt b/src/openMVG/multiview/CMakeLists.txt index 42edc50b50..dce4a4fced 100644 --- a/src/openMVG/multiview/CMakeLists.txt +++ b/src/openMVG/multiview/CMakeLists.txt @@ -20,7 +20,7 @@ ADD_LIBRARY(openMVG_multiview ${multiview_files_header} ${multiview_files_cpp}) SET_PROPERTY(TARGET openMVG_multiview PROPERTY FOLDER OpenMVG) -INSTALL(TARGETS openMVG_multiview DESTINATION lib/) +INSTALL(TARGETS openMVG_multiview DESTINATION lib EXPORT openMVG-targets) #Make multiview library integrate numeric library ADD_LIBRARY(openMVG_multiview_test_data ${MULTIVIEWTESTDATA}) diff --git a/src/openMVG/numeric/CMakeLists.txt b/src/openMVG/numeric/CMakeLists.txt index b31ed6d87f..0755b84936 100644 --- a/src/openMVG/numeric/CMakeLists.txt +++ b/src/openMVG/numeric/CMakeLists.txt @@ -2,7 +2,7 @@ ADD_LIBRARY(openMVG_numeric numeric.cpp numeric.h) SET_PROPERTY(TARGET openMVG_numeric PROPERTY FOLDER OpenMVG/OpenMVG) -INSTALL(TARGETS openMVG_numeric DESTINATION lib/) +INSTALL(TARGETS openMVG_numeric DESTINATION lib EXPORT openMVG-targets) UNIT_TEST(openMVG numeric openMVG_numeric) UNIT_TEST(openMVG poly openMVG_numeric) diff --git a/src/openMVG/sfm/CMakeLists.txt b/src/openMVG/sfm/CMakeLists.txt index de3051ff27..f85e4b3db0 100644 --- a/src/openMVG/sfm/CMakeLists.txt +++ b/src/openMVG/sfm/CMakeLists.txt @@ -17,8 +17,8 @@ FILE(GLOB_RECURSE REMOVEFILESUNITTEST *_test.hpp) list(REMOVE_ITEM sfm_files_header ${REMOVEFILESUNITTEST}) ADD_LIBRARY(openMVG_sfm ${sfm_files_header} ${sfm_files_cpp}) -TARGET_LINK_LIBRARIES(openMVG_sfm ceres openMVG_multiview) -INSTALL(TARGETS openMVG_sfm DESTINATION lib/) +TARGET_LINK_LIBRARIES(openMVG_sfm ceres openMVG_multiview ${OPENMVG_LIBRARY_DEPENDENCIES}) +INSTALL(TARGETS openMVG_sfm DESTINATION lib EXPORT openMVG-targets) UNIT_TEST(openMVG sfm_data_io "stlplus;openMVG_features;openMVG_sfm;${openMVG_linearProgramming}") UNIT_TEST(openMVG sfm_data_BA diff --git a/src/openMVG/system/CMakeLists.txt b/src/openMVG/system/CMakeLists.txt index 5978e5bab4..27a5a99707 100644 --- a/src/openMVG/system/CMakeLists.txt +++ b/src/openMVG/system/CMakeLists.txt @@ -14,4 +14,5 @@ ADD_LIBRARY(openMVG_system ${sytem_files_header} ${system_files_cpp}) SET_PROPERTY(TARGET openMVG_system PROPERTY FOLDER OpenMVG/OpenMVG) -INSTALL(TARGETS openMVG_system DESTINATION lib/) +INSTALL(TARGETS openMVG_system DESTINATION lib/ EXPORT openMVG-targets) + diff --git a/src/openMVG_Samples/image_describer_matches/CMakeLists.txt b/src/openMVG_Samples/image_describer_matches/CMakeLists.txt index e744a984b3..3110f7897d 100644 --- a/src/openMVG_Samples/image_describer_matches/CMakeLists.txt +++ b/src/openMVG_Samples/image_describer_matches/CMakeLists.txt @@ -3,11 +3,6 @@ ADD_DEFINITIONS(-DTHIS_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}") ADD_EXECUTABLE(openMVG_sample_describe_and_match describe_and_match.cpp) TARGET_LINK_LIBRARIES(openMVG_sample_describe_and_match - openMVG_features - ${OpenMVG_LIBS} - vlsift - stlplus - flann_cpp_s - ${OPENMVG_LIBRARY_DEPENDENCIES}) + ${OpenMVG_LIBRARIES}) SET_PROPERTY(TARGET openMVG_sample_describe_and_match PROPERTY FOLDER OpenMVG/Samples) diff --git a/src/openMVG_Samples/robust_essential/CMakeLists.txt b/src/openMVG_Samples/robust_essential/CMakeLists.txt index 2839ddf2a1..5bcf886ea9 100644 --- a/src/openMVG_Samples/robust_essential/CMakeLists.txt +++ b/src/openMVG_Samples/robust_essential/CMakeLists.txt @@ -3,6 +3,6 @@ ADD_DEFINITIONS(-DTHIS_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}") ADD_EXECUTABLE(openMVG_sample_robustEssential robust_essential.cpp) TARGET_LINK_LIBRARIES(openMVG_sample_robustEssential - ${OpenMVG_LIBS}) + ${OpenMVG_LIBRARIES}) SET_PROPERTY(TARGET openMVG_sample_robustEssential PROPERTY FOLDER OpenMVG/Samples) diff --git a/src/openMVG_Samples/robust_essential_ba/CMakeLists.txt b/src/openMVG_Samples/robust_essential_ba/CMakeLists.txt index 8eaf19ab37..5dd6038098 100644 --- a/src/openMVG_Samples/robust_essential_ba/CMakeLists.txt +++ b/src/openMVG_Samples/robust_essential_ba/CMakeLists.txt @@ -3,6 +3,6 @@ ADD_DEFINITIONS(-DTHIS_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}") ADD_EXECUTABLE(openMVG_sample_robustEssential_ba robust_essential_ba.cpp) TARGET_LINK_LIBRARIES(openMVG_sample_robustEssential_ba - ${OpenMVG_LIBS}) + ${OpenMVG_LIBRARIES}) SET_PROPERTY(TARGET openMVG_sample_robustEssential_ba PROPERTY FOLDER OpenMVG/Samples) diff --git a/src/openMVG_Samples/undisto_Brown/CMakeLists.txt b/src/openMVG_Samples/undisto_Brown/CMakeLists.txt index 1b1e3fb284..3ea4e197a3 100644 --- a/src/openMVG_Samples/undisto_Brown/CMakeLists.txt +++ b/src/openMVG_Samples/undisto_Brown/CMakeLists.txt @@ -1,5 +1,5 @@ ADD_EXECUTABLE(openMVG_sample_undistoBrown undistoBrown.cpp) TARGET_LINK_LIBRARIES(openMVG_sample_undistoBrown - ${OpenMVG_LIBS}) + ${OpenMVG_LIBRARIES}) SET_PROPERTY(TARGET openMVG_sample_undistoBrown PROPERTY FOLDER OpenMVG/Samples) diff --git a/src/software/SfM/CMakeLists.txt b/src/software/SfM/CMakeLists.txt index 4c1336da9f..7304637dba 100644 --- a/src/software/SfM/CMakeLists.txt +++ b/src/software/SfM/CMakeLists.txt @@ -3,13 +3,11 @@ # Intrinsic image analysis and SfM_Data container initialization ### ADD_EXECUTABLE(openMVG_main_SfMInit_ImageListing main_SfMInit_ImageListing.cpp) -TARGET_LINK_LIBRARIES(openMVG_main_SfMInit_ImageListing - ${OpenMVG_LIBS}) +TARGET_LINK_LIBRARIES(openMVG_main_SfMInit_ImageListing ${OpenMVG_LIBRARIES}) #convert a v0.6 lists.txt file to the new sfm_data.X format ADD_EXECUTABLE(openMVG_main_ConvertList main_ConvertList.cpp) -TARGET_LINK_LIBRARIES(openMVG_main_ConvertList - ${OpenMVG_LIBS}) +TARGET_LINK_LIBRARIES(openMVG_main_ConvertList ${OpenMVG_LIBRARIES}) # Installation rules SET_PROPERTY(TARGET openMVG_main_SfMInit_ImageListing PROPERTY FOLDER OpenMVG/software) @@ -24,12 +22,10 @@ INSTALL(TARGETS openMVG_main_ConvertList DESTINATION bin/) ### ADD_EXECUTABLE(openMVG_main_ComputeFeatures main_ComputeFeatures.cpp) -TARGET_LINK_LIBRARIES(openMVG_main_ComputeFeatures - ${OpenMVG_LIBS}) +TARGET_LINK_LIBRARIES(openMVG_main_ComputeFeatures ${OpenMVG_LIBRARIES}) ADD_EXECUTABLE(openMVG_main_ComputeMatches main_ComputeMatches.cpp) -TARGET_LINK_LIBRARIES(openMVG_main_ComputeMatches - ${OpenMVG_LIBS}) +TARGET_LINK_LIBRARIES(openMVG_main_ComputeMatches ${OpenMVG_LIBRARIES}) # Installation rules SET_PROPERTY(TARGET openMVG_main_ComputeFeatures PROPERTY FOLDER OpenMVG/software) @@ -48,32 +44,25 @@ INSTALL(TARGETS openMVG_main_ComputeMatches DESTINATION bin/) # - Compute structure color ### ADD_EXECUTABLE(openMVG_main_IncrementalSfM main_IncrementalSfM.cpp) -TARGET_LINK_LIBRARIES(openMVG_main_IncrementalSfM - ${OpenMVG_LIBS}) +TARGET_LINK_LIBRARIES(openMVG_main_IncrementalSfM ${OpenMVG_LIBRARIES}) ADD_EXECUTABLE(openMVG_main_GlobalSfM main_GlobalSfM.cpp) -TARGET_LINK_LIBRARIES( - openMVG_main_GlobalSfM - ${OpenMVG_LIBS}) +TARGET_LINK_LIBRARIES(openMVG_main_GlobalSfM ${OpenMVG_LIBRARIES}) ADD_EXECUTABLE(openMVG_main_ConvertSfM_DataFormat main_ConvertSfM_DataFormat.cpp) -TARGET_LINK_LIBRARIES(openMVG_main_ConvertSfM_DataFormat - ${OpenMVG_LIBS}) +TARGET_LINK_LIBRARIES(openMVG_main_ConvertSfM_DataFormat ${OpenMVG_LIBRARIES}) ADD_EXECUTABLE(openMVG_main_FrustumFiltering main_FrustumFiltering.cpp) -TARGET_LINK_LIBRARIES(openMVG_main_FrustumFiltering - ${OpenMVG_LIBS}) +TARGET_LINK_LIBRARIES(openMVG_main_FrustumFiltering ${OpenMVG_LIBRARIES}) ADD_EXECUTABLE(openMVG_main_ComputeStructureFromKnownPoses main_ComputeStructureFromKnownPoses.cpp) -TARGET_LINK_LIBRARIES(openMVG_main_ComputeStructureFromKnownPoses - ${OpenMVG_LIBS}) +TARGET_LINK_LIBRARIES(openMVG_main_ComputeStructureFromKnownPoses ${OpenMVG_LIBRARIES}) ADD_EXECUTABLE(openMVG_main_ComputeSfM_DataColor main_ComputeSfM_DataColor.cpp) -TARGET_LINK_LIBRARIES(openMVG_main_ComputeSfM_DataColor - ${OpenMVG_LIBS}) +TARGET_LINK_LIBRARIES(openMVG_main_ComputeSfM_DataColor ${OpenMVG_LIBRARIES}) # Installation rules -INSTALL(FILES cameraSensorWidth/cameraGenerated.txt DESTINATION resources/) +INSTALL(FILES cameraSensorWidth/cameraGenerated.txt DESTINATION share/openMVG) SET_PROPERTY(TARGET openMVG_main_IncrementalSfM PROPERTY FOLDER OpenMVG/software) INSTALL(TARGETS openMVG_main_IncrementalSfM DESTINATION bin/) SET_PROPERTY(TARGET openMVG_main_GlobalSfM PROPERTY FOLDER OpenMVG/software) @@ -94,27 +83,23 @@ INSTALL(TARGETS openMVG_main_ComputeSfM_DataColor DESTINATION bin/) # - View extracted Keypoints # ADD_EXECUTABLE(openMVG_main_exportKeypoints main_exportKeypoints.cpp) -TARGET_LINK_LIBRARIES(openMVG_main_exportKeypoints - ${OpenMVG_LIBS}) +TARGET_LINK_LIBRARIES(openMVG_main_exportKeypoints ${OpenMVG_LIBRARIES}) # - View computed matches (putatives, geometrics) per image pair # ADD_EXECUTABLE(openMVG_main_exportMatches main_exportMatches.cpp) -TARGET_LINK_LIBRARIES(openMVG_main_exportMatches - ${OpenMVG_LIBS}) +TARGET_LINK_LIBRARIES(openMVG_main_exportMatches ${OpenMVG_LIBRARIES}) # - View tracks per image pair # ADD_EXECUTABLE(openMVG_main_exportTracks main_exportTracks.cpp) -TARGET_LINK_LIBRARIES(openMVG_main_exportTracks - ${OpenMVG_LIBS}) +TARGET_LINK_LIBRARIES(openMVG_main_exportTracks ${OpenMVG_LIBRARIES}) # - Export undistorted images related to a sfm_data file # ADD_EXECUTABLE(openMVG_main_ExportUndistortedImages main_ExportUndistortedImages.cpp) -TARGET_LINK_LIBRARIES(openMVG_main_ExportUndistortedImages - ${OpenMVG_LIBS}) +TARGET_LINK_LIBRARIES(openMVG_main_ExportUndistortedImages ${OpenMVG_LIBRARIES}) # installation rules SET_PROPERTY(TARGET openMVG_main_exportKeypoints PROPERTY FOLDER OpenMVG/software) @@ -136,26 +121,22 @@ INSTALL(TARGETS openMVG_main_ExportUndistortedImages DESTINATION bin/) # - Export a SfM openMVG scene to PMVS format # ADD_EXECUTABLE(openMVG_main_openMVG2PMVS main_openMVG2PMVS.cpp) -TARGET_LINK_LIBRARIES(openMVG_main_openMVG2PMVS - ${OpenMVG_LIBS}) +TARGET_LINK_LIBRARIES(openMVG_main_openMVG2PMVS ${OpenMVG_LIBRARIES}) # - Export a SfM openMVG scene to CMPMVS format # ADD_EXECUTABLE(openMVG_main_openMVG2CMPMVS main_openMVG2CMPMVS.cpp) -TARGET_LINK_LIBRARIES(openMVG_main_openMVG2CMPMVS - ${OpenMVG_LIBS}) +TARGET_LINK_LIBRARIES(openMVG_main_openMVG2CMPMVS ${OpenMVG_LIBRARIES}) # - Export a SfM openMVG scene to meshlab scene with rasters # - ADD_EXECUTABLE(openMVG_main_openMVG2MESHLAB main_openMVG2MESHLAB.cpp) -TARGET_LINK_LIBRARIES(openMVG_main_openMVG2MESHLAB - ${OpenMVG_LIBS}) +TARGET_LINK_LIBRARIES(openMVG_main_openMVG2MESHLAB ${OpenMVG_LIBRARIES}) # - Export SfM openMVG camera scene as triangle meshes # - ADD_EXECUTABLE(openMVG_main_ExportCameraFrustums main_ExportCameraFrustums.cpp) -TARGET_LINK_LIBRARIES(openMVG_main_ExportCameraFrustums - ${OpenMVG_LIBS}) +TARGET_LINK_LIBRARIES(openMVG_main_ExportCameraFrustums ${OpenMVG_LIBRARIES}) # installation rules SET_PROPERTY(TARGET openMVG_main_openMVG2PMVS PROPERTY FOLDER OpenMVG/software) @@ -180,7 +161,7 @@ IF(OpenMVG_USE_OPENCV) ADD_EXECUTABLE(openMVG_main_ComputeFeatures_OpenCV main_ComputeFeatures_OpenCV.cpp) TARGET_LINK_LIBRARIES(openMVG_main_ComputeFeatures_OpenCV - ${OpenMVG_LIBS} + ${OpenMVG_LIBRARIES} ${OpenCV_LIBS}) SET_PROPERTY(TARGET openMVG_main_ComputeFeatures_OpenCV PROPERTY FOLDER OpenMVG/software) @@ -196,8 +177,7 @@ ENDIF(OpenMVG_USE_OPENCV) # - Quality comparison against a GT camera path (MultiView Evaluation dataset) ### ADD_EXECUTABLE(openMVG_main_evalQuality main_evalQuality.cpp) -TARGET_LINK_LIBRARIES(openMVG_main_evalQuality - ${OpenMVG_LIBS}) +TARGET_LINK_LIBRARIES(openMVG_main_evalQuality ${OpenMVG_LIBRARIES}) #installation rules SET_PROPERTY(TARGET openMVG_main_evalQuality PROPERTY FOLDER OpenMVG/software) diff --git a/src/software/SfMViewer/CMakeLists.txt b/src/software/SfMViewer/CMakeLists.txt index 665cb184f6..9d31169612 100644 --- a/src/software/SfMViewer/CMakeLists.txt +++ b/src/software/SfMViewer/CMakeLists.txt @@ -33,7 +33,7 @@ SET(SOURCES ADD_EXECUTABLE(openMVG_main_sfmViewer ${SOURCES} ) TARGET_LINK_LIBRARIES(openMVG_main_sfmViewer ${OPENGL_gl_LIBRARY} glfw ${GLFW_LIBRARIES} - ${OpenMVG_LIBS} + ${OpenMVG_LIBRARIES} ) SET_PROPERTY(TARGET openMVG_main_sfmViewer PROPERTY FOLDER OpenMVG/software) INSTALL(TARGETS openMVG_main_sfmViewer DESTINATION bin/) diff --git a/src/software/colorHarmonize/CMakeLists.txt b/src/software/colorHarmonize/CMakeLists.txt index 8ca954f5bd..cd191309c8 100644 --- a/src/software/colorHarmonize/CMakeLists.txt +++ b/src/software/colorHarmonize/CMakeLists.txt @@ -2,8 +2,7 @@ ADD_EXECUTABLE(openMVG_main_ColHarmonize main_ColHarmonize.cpp colorHarmonizeEngineGlobal.cpp) TARGET_LINK_LIBRARIES(openMVG_main_ColHarmonize - ${OpenMVG_LIBS} - openMVG_kvld) + ${OpenMVG_LIBRARIES}) SET_PROPERTY(TARGET openMVG_main_ColHarmonize PROPERTY FOLDER OpenMVG/software) diff --git a/src/third_party/CMakeLists.txt b/src/third_party/CMakeLists.txt index f3f4f44cc0..259ca23fbe 100644 --- a/src/third_party/CMakeLists.txt +++ b/src/third_party/CMakeLists.txt @@ -8,7 +8,7 @@ IF (OpenMVG_BUILD_TESTS) ENDIF() # Basic filesystem utils -SET(STLPLUS_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/openMVG_third_party/stlplus) +SET(STLPLUS_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/openMVG/third_party/stlplus3) ADD_SUBDIRECTORY(stlplus3) # Add graph library @@ -20,7 +20,7 @@ SET_PROPERTY(TARGET check PROPERTY FOLDER OpenMVG/3rdParty/lemon) # Image I/O ## IF(NOT JPEG_FOUND) - SET(JPEG_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/openMVG_third_party/jpeg) + SET(JPEG_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/openMVG/third_party/jpeg) ADD_SUBDIRECTORY(jpeg) LIST(APPEND JPEG_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/jpeg ${CMAKE_CURRENT_BINARY_DIR}/jpeg/config) SET(JPEG_INCLUDE_DIR ${JPEG_INCLUDE_DIRECTORIES}) @@ -30,8 +30,8 @@ IF(NOT JPEG_FOUND) ENDIF(NOT JPEG_FOUND) IF (NOT PNG_FOUND) - SET(ZLIB_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/openMVG_third_party/zlib) - SET(PNG_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/openMVG_third_party/png) + SET(ZLIB_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/openMVG/third_party/zlib) + SET(PNG_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/openMVG/third_party/png) ADD_SUBDIRECTORY(zlib) ADD_SUBDIRECTORY(png) SET(PNG_LIBRARIES png zlib) @@ -42,7 +42,7 @@ IF (NOT PNG_FOUND) ENDIF (NOT PNG_FOUND) IF (NOT TIFF_FOUND) - SET(TIFF_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/openMVG_third_party/tiff) + SET(TIFF_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/openMVG/third_party/tiff) ADD_SUBDIRECTORY(tiff) LIST(APPEND TIFF_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/tiff ${CMAKE_CURRENT_BINARY_DIR}/tiff) SET(TIFF_INCLUDE_DIR ${TIFF_INCLUDE_DIRECTORIES}) @@ -58,33 +58,38 @@ ENDIF (NOT TIFF_FOUND) ADD_SUBDIRECTORY(vectorGraphics) # Add ceres-solver (A Nonlinear Least Squares Minimizer) -SET(CXSPARSE_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/openMVG_third_party/cxsparse) -ADD_SUBDIRECTORY(cxsparse) -ADD_SUBDIRECTORY(ceres-solver) -SET_PROPERTY(TARGET cxsparse PROPERTY FOLDER OpenMVG/3rdParty/ceres) -SET_PROPERTY(TARGET ceres PROPERTY FOLDER OpenMVG/3rdParty/ceres) +IF (DEFINED OpenMVG_USE_INTERNAL_CERES) + SET(CXSPARSE_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/openMVG/third_party/cxsparse) + ADD_SUBDIRECTORY(cxsparse) + SET(CERES_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/openMVG/third_party/ceres) + ADD_SUBDIRECTORY(ceres-solver) + SET_PROPERTY(TARGET cxsparse PROPERTY FOLDER OpenMVG/3rdParty/ceres) + SET_PROPERTY(TARGET ceres PROPERTY FOLDER OpenMVG/3rdParty/ceres) +ENDIF() # Add an Approximate Nearest Neighbor library ADD_SUBDIRECTORY(flann) SET_PROPERTY(TARGET flann_cpp_s PROPERTY FOLDER OpenMVG/3rdParty) # Exif data parsing -SET(EASYEXIF_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/openMVG_third_party/easyexif) +SET(EASYEXIF_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/openMVG/third_party/easyexif) ADD_SUBDIRECTORY(easyexif) ## -# Install Header only libraries +# Install Header only libraries if necessary ## -#Configure Eigen install -SET(EIGEN_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/openMVG_third_party/Eigen) -ADD_SUBDIRECTORY(eigen) +IF (DEFINED OpenMVG_USE_INTERNAL_EIGEN) + #Configure Eigen install + SET(EIGEN_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/openMVG/third_party/eigen) + ADD_SUBDIRECTORY(eigen) +ENDIF() -LIST(APPEND directories cmdLine histogram htmlDoc progress stlAddition tinythread vectorGraphics) +LIST(APPEND directories cmdLine histogram htmlDoc progress tinythread vectorGraphics) FOREACH(inDirectory ${directories}) INSTALL( DIRECTORY ./${inDirectory} - DESTINATION include/openMVG_third_party/ + DESTINATION include/openMVG/third_party/ COMPONENT headers - FILES_MATCHING PATTERN "*.hpp" + FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h" ) ENDFOREACH(inDirectory) diff --git a/src/third_party/ceres-solver/CMakeLists.txt b/src/third_party/ceres-solver/CMakeLists.txt index e61a6eb7f5..3b6d02aee9 100644 --- a/src/third_party/ceres-solver/CMakeLists.txt +++ b/src/third_party/ceres-solver/CMakeLists.txt @@ -212,9 +212,6 @@ UNSET(CERES_COMPILE_OPTIONS) # Eigen. #HANDLE_LEGACY_INCLUDE_DEPENDENCY_HINT(EIGEN_INCLUDE EIGEN_INCLUDE_DIR_HINTS) -LIST(APPEND CMAKE_INCLUDE_PATH ../eigen) # OpenMVG -SET(EIGEN_INCLUDE_DIRS ../eigen) # OpenMVG -FIND_PATH(EIGEN_INCLUDE NAMES Eigen/Core) # OpenMVG FIND_PACKAGE(Eigen REQUIRED) IF (EIGEN_FOUND) MESSAGE("-- Found Eigen version ${EIGEN_VERSION}: ${EIGEN_INCLUDE_DIRS}") @@ -732,3 +729,23 @@ IF (BUILD_EXAMPLES) ELSE (BUILD_EXAMPLES) MESSAGE("-- Do not build any example.") ENDIF (BUILD_EXAMPLES) + +# Setup installation of Ceres public headers. +FILE(GLOB CERES_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/include/ceres/*.h) +INSTALL(FILES ${CERES_HDRS} DESTINATION ${CERES_INCLUDE_INSTALL_DIR}) + +FILE(GLOB CERES_PUBLIC_INTERNAL_HDRS ${CMAKE_CURRENT_SOURCE_DIR}/include/ceres/internal/*.h) +INSTALL(FILES ${CERES_PUBLIC_INTERNAL_HDRS} DESTINATION ${CERES_INCLUDE_INSTALL_DIR}/internal) + +# Also setup installation of Ceres config.h configured with the current +# build options into the installed headers directory. +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/config/ceres/internal/config.h + DESTINATION ${CERES_INCLUDE_INSTALL_DIR}/internal) + + +IF (MINIGLOG) + # Install miniglog header if being used as logging #includes appear in + # installed public Ceres headers. + INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/internal/ceres/miniglog/glog/logging.h + DESTINATION ${CERES_INCLUDE_INSTALL_DIR}/miniglog/glog) +ENDIF (MINIGLOG) \ No newline at end of file diff --git a/src/third_party/ceres-solver/internal/ceres/CMakeLists.txt b/src/third_party/ceres-solver/internal/ceres/CMakeLists.txt index 1472e654cd..2673d4c4cb 100644 --- a/src/third_party/ceres-solver/internal/ceres/CMakeLists.txt +++ b/src/third_party/ceres-solver/internal/ceres/CMakeLists.txt @@ -203,6 +203,11 @@ INSTALL(TARGETS ceres RUNTIME DESTINATION bin LIBRARY DESTINATION lib${LIB_SUFFIX} ARCHIVE DESTINATION lib${LIB_SUFFIX}) +INSTALL(TARGETS ceres + EXPORT openMVG-targets + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib${LIB_SUFFIX} + ARCHIVE DESTINATION lib${LIB_SUFFIX}) IF (BUILD_TESTING AND GFLAGS) # The CERES_GFLAGS_NAMESPACE compile definition is NOT stored in diff --git a/src/third_party/cxsparse/CMakeLists.txt b/src/third_party/cxsparse/CMakeLists.txt index 37fbf9a5da..b586424d13 100644 --- a/src/third_party/cxsparse/CMakeLists.txt +++ b/src/third_party/cxsparse/CMakeLists.txt @@ -29,4 +29,6 @@ INSTALL( DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT headers FILES_MATCHING PATTERN "*.h" -) \ No newline at end of file +) +INSTALL(TARGETS cxsparse DESTINATION lib EXPORT openMVG-targets) + diff --git a/src/third_party/easyexif/CMakeLists.txt b/src/third_party/easyexif/CMakeLists.txt index e13c358756..6061ab43a4 100644 --- a/src/third_party/easyexif/CMakeLists.txt +++ b/src/third_party/easyexif/CMakeLists.txt @@ -16,4 +16,6 @@ INSTALL( DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT headers FILES_MATCHING PATTERN "*.h" -) \ No newline at end of file +) +INSTALL(TARGETS easyexif DESTINATION lib EXPORT openMVG-targets) + diff --git a/src/third_party/flann/src/cpp/CMakeLists.txt b/src/third_party/flann/src/cpp/CMakeLists.txt index b66fa11846..3a8fb95c67 100644 --- a/src/third_party/flann/src/cpp/CMakeLists.txt +++ b/src/third_party/flann/src/cpp/CMakeLists.txt @@ -12,6 +12,8 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG) endif() SET_PROPERTY(TARGET flann_cpp_s PROPERTY COMPILE_DEFINITIONS FLANN_STATIC FLANN_USE_CUDA) +INSTALL(TARGETS flann_cpp_s DESTINATION lib EXPORT openMVG-targets) + #if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_COMPILER_IS_GNUCC) # add_library(flann_cpp SHARED "") # set_target_properties(flann_cpp PROPERTIES LINKER_LANGUAGE CXX) diff --git a/src/third_party/jpeg/CMakeLists.txt b/src/third_party/jpeg/CMakeLists.txt index b7ee7946e3..e836a1305c 100644 --- a/src/third_party/jpeg/CMakeLists.txt +++ b/src/third_party/jpeg/CMakeLists.txt @@ -39,4 +39,4 @@ install(FILES ${HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel ) -INSTALL(TARGETS jpeg DESTINATION lib/) \ No newline at end of file +INSTALL(TARGETS jpeg DESTINATION lib EXPORT openMVG-targets) diff --git a/src/third_party/lemon/CMakeLists.txt b/src/third_party/lemon/CMakeLists.txt index 38d4f3f21b..5dc5c4a61c 100644 --- a/src/third_party/lemon/CMakeLists.txt +++ b/src/third_party/lemon/CMakeLists.txt @@ -277,3 +277,4 @@ CONFIGURE_FILE( ${PROJECT_BINARY_DIR}/cmake/version.cmake @ONLY ) + diff --git a/src/third_party/lemon/lemon/CMakeLists.txt b/src/third_party/lemon/lemon/CMakeLists.txt index 78607039bf..b78b2b8b4a 100644 --- a/src/third_party/lemon/lemon/CMakeLists.txt +++ b/src/third_party/lemon/lemon/CMakeLists.txt @@ -56,14 +56,27 @@ ENDIF() ADD_LIBRARY(lemon ${LEMON_SOURCES}) IF(UNIX) - SET_TARGET_PROPERTIES(lemon PROPERTIES OUTPUT_NAME emon) +# SET_TARGET_PROPERTIES(lemon PROPERTIES OUTPUT_NAME emon) + SET_TARGET_PROPERTIES(lemon PROPERTIES OUTPUT_NAME lemon) ENDIF() INSTALL( TARGETS lemon - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib - COMPONENT library + DESTINATION lib + EXPORT openMVG-targets +) + +INSTALL( + DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DESTINATION include/openMVG/third_party/lemon + COMPONENT headers + FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h" +) + +INSTALL( + FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h + DESTINATION include/openMVG/third_party/lemon + COMPONENT headers ) #INSTALL( diff --git a/src/third_party/png/CMakeLists.txt b/src/third_party/png/CMakeLists.txt index d6a61a5f79..a563ec736a 100644 --- a/src/third_party/png/CMakeLists.txt +++ b/src/third_party/png/CMakeLists.txt @@ -79,4 +79,4 @@ install(FILES ${libpng_public_hdrs} DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel ) -INSTALL(TARGETS png DESTINATION lib/) +INSTALL(TARGETS png DESTINATION lib EXPORT openMVG-targets) diff --git a/src/third_party/stlplus3/CMakeLists.txt b/src/third_party/stlplus3/CMakeLists.txt index ed30bf5caa..2229896ba8 100644 --- a/src/third_party/stlplus3/CMakeLists.txt +++ b/src/third_party/stlplus3/CMakeLists.txt @@ -13,6 +13,7 @@ SET_PROPERTY(TARGET stlplus PROPERTY FOLDER OpenMVG/3rdParty) INSTALL( TARGETS stlplus DESTINATION lib + EXPORT openMVG-targets ) IF(STLPLUS_INCLUDE_INSTALL_DIR) diff --git a/src/third_party/tiff/CMakeLists.txt b/src/third_party/tiff/CMakeLists.txt index bea9fbc7d3..fd36c4cce6 100644 --- a/src/third_party/tiff/CMakeLists.txt +++ b/src/third_party/tiff/CMakeLists.txt @@ -106,4 +106,4 @@ install(FILES ${lib_headers} DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel ) -INSTALL(TARGETS tiff DESTINATION lib/) +INSTALL(TARGETS tiff DESTINATION lib EXPORT openMVG-targets) diff --git a/src/third_party/zlib/CMakeLists.txt b/src/third_party/zlib/CMakeLists.txt index c1eaebee7e..8d4d0b6f1d 100644 --- a/src/third_party/zlib/CMakeLists.txt +++ b/src/third_party/zlib/CMakeLists.txt @@ -21,4 +21,4 @@ install(FILES inftrees.h trees.h zconf.h zconf.in.h zlib.h zutil.h DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel ) -INSTALL(TARGETS zlib DESTINATION lib/) +INSTALL(TARGETS zlib DESTINATION lib EXPORT openMVG-targets) From 13c348787b41e461b533b2897741dfa8a99d5262 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Thu, 28 May 2015 11:29:23 +0200 Subject: [PATCH 45/52] Use last uptodate osi_clp --- src/dependencies/osi_clp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dependencies/osi_clp b/src/dependencies/osi_clp index d686a8f919..0605e098b6 160000 --- a/src/dependencies/osi_clp +++ b/src/dependencies/osi_clp @@ -1 +1 @@ -Subproject commit d686a8f919b93e8302e6b2c9b193fc997003fd88 +Subproject commit 0605e098b643b04adf58080900c14e2d16e423bc From 8794363609fe082cdbf52b5425ba91441b301518 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Thu, 28 May 2015 11:34:40 +0200 Subject: [PATCH 46/52] Fix osi_clp submodule status --- src/dependencies/osi_clp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dependencies/osi_clp b/src/dependencies/osi_clp index 0605e098b6..e0a7f5055c 160000 --- a/src/dependencies/osi_clp +++ b/src/dependencies/osi_clp @@ -1 +1 @@ -Subproject commit 0605e098b643b04adf58080900c14e2d16e423bc +Subproject commit e0a7f5055cb25f6b33a13231709441b8e294bc46 From 2b1fcac632d5dbd637cfe7d14494ef0828fb8bec Mon Sep 17 00:00:00 2001 From: pmoulon Date: Fri, 29 May 2015 14:17:50 +0200 Subject: [PATCH 47/52] Fix ceres miniglog include header path. #222 --- src/CMakeLists.txt | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1598732699..52ec5e4566 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -385,12 +385,20 @@ STRING(REGEX REPLACE OpenMVG_INCLUDE_DIRS "${OpenMVG_INCLUDE_DIRS}" ) -STRING(REGEX REPLACE - "ceres-solver" - "ceres" - OpenMVG_INCLUDE_DIRS - "${OpenMVG_INCLUDE_DIRS}" -) +IF (OpenMVG_USE_INTERNAL_CERES) + STRING(REGEX REPLACE + "ceres-solver" + "ceres" + OpenMVG_INCLUDE_DIRS + "${OpenMVG_INCLUDE_DIRS}" + ) + STRING(REGEX REPLACE + "internal/ceres/" + "" + OpenMVG_INCLUDE_DIRS + "${OpenMVG_INCLUDE_DIRS}" + ) +ENDIF(OpenMVG_USE_INTERNAL_CERES) # Create a OpenMVGConfig.cmake file. Config.cmake files are searched by # FIND_PACKAGE() automatically. We configure that file so that we can put any From 66504df29779669249a08fefef3d45f4f7a3fd77 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Fri, 29 May 2015 14:37:50 +0200 Subject: [PATCH 48/52] Fix full BA pose constness checking. Thx @bduisit. --- src/openMVG/sfm/sfm_data_BA_ceres.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openMVG/sfm/sfm_data_BA_ceres.cpp b/src/openMVG/sfm/sfm_data_BA_ceres.cpp index 2314267033..36e975ccc7 100644 --- a/src/openMVG/sfm/sfm_data_BA_ceres.cpp +++ b/src/openMVG/sfm/sfm_data_BA_ceres.cpp @@ -124,7 +124,7 @@ bool Bundle_Adjustment_Ceres::Adjust( double * parameter_block = &map_poses[indexPose][0]; problem.AddParameterBlock(parameter_block, 6); - if (!bRefineTranslations && !bRefineIntrinsics) + if (!bRefineTranslations && !bRefineRotations) { //set the whole parameter block as constant for best performance. problem.SetParameterBlockConstant(parameter_block); From fe8887b144005e77ef1754be58b9e9b7f6c42814 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Fri, 29 May 2015 15:00:06 +0200 Subject: [PATCH 49/52] Merge --- src/software/SfM/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/software/SfM/CMakeLists.txt b/src/software/SfM/CMakeLists.txt index 5e846b8e9c..73453b85d4 100644 --- a/src/software/SfM/CMakeLists.txt +++ b/src/software/SfM/CMakeLists.txt @@ -136,8 +136,7 @@ TARGET_LINK_LIBRARIES(openMVG_main_openMVG2MESHLAB ${OpenMVG_LIBRARIES}) # - Export a SfM openMVG scene to mvs-texturing scene folder # - ADD_EXECUTABLE(openMVG_main_openMVG2MVSTEXTURING main_openMVG2MVSTEXTURING.cpp) -TARGET_LINK_LIBRARIES(openMVG_main_openMVG2MVSTEXTURING - ${OpenMVG_LIBS}) +TARGET_LINK_LIBRARIES(openMVG_main_openMVG2MVSTEXTURING ${OpenMVG_LIBRARIES}) # - Export SfM openMVG camera scene as triangle meshes # - From ab1cc4d4b37d2644a5e84f4dd3c75ac3151ae643 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Sat, 30 May 2015 00:33:31 +0200 Subject: [PATCH 50/52] Compute 3D-2D visibility check for finding best resection images in parallel. #312 --- .../pipelines/sequential/sequential_SfM.cpp | 53 ++++++++++++------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp b/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp index fec2e7b3fe..da826939f5 100644 --- a/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp +++ b/src/openMVG/sfm/pipelines/sequential/sequential_SfM.cpp @@ -631,31 +631,44 @@ bool SequentialSfMReconstructionEngine::FindImagesWithPossibleResection const double dPourcent = 0.75; Pair_Vec vec_putative; // ImageId, NbPutativeCommonPoint +#ifdef OPENMVG_USE_OPENMP + #pragma omp parallel +#endif for (std::set::const_iterator iter = _set_remainingViewId.begin(); iter != _set_remainingViewId.end(); ++iter) { - const size_t viewId = *iter; +#ifdef OPENMVG_USE_OPENMP + #pragma omp single nowait +#endif + { + const size_t viewId = *iter; - // Compute 2D - 3D possible content - openMVG::tracks::STLMAPTracks map_tracksCommon; - std::set set_viewId; - set_viewId.insert(viewId); - tracks::TracksUtilsMap::GetTracksInImages(set_viewId, _map_tracks, map_tracksCommon); + // Compute 2D - 3D possible content + openMVG::tracks::STLMAPTracks map_tracksCommon; + std::set set_viewId; + set_viewId.insert(viewId); + tracks::TracksUtilsMap::GetTracksInImages(set_viewId, _map_tracks, map_tracksCommon); - if (! map_tracksCommon.empty()) - { - std::set set_tracksIds; - tracks::TracksUtilsMap::GetTracksIdVector(map_tracksCommon, &set_tracksIds); - - // Count the common possible putative point - // with the already 3D reconstructed trackId - std::vector vec_trackIdForResection; - set_intersection(set_tracksIds.begin(), set_tracksIds.end(), - reconstructed_trackId.begin(), - reconstructed_trackId.end(), - std::back_inserter(vec_trackIdForResection)); - - vec_putative.push_back( make_pair(viewId, vec_trackIdForResection.size())); + if (! map_tracksCommon.empty()) + { + std::set set_tracksIds; + tracks::TracksUtilsMap::GetTracksIdVector(map_tracksCommon, &set_tracksIds); + + // Count the common possible putative point + // with the already 3D reconstructed trackId + std::vector vec_trackIdForResection; + set_intersection(set_tracksIds.begin(), set_tracksIds.end(), + reconstructed_trackId.begin(), + reconstructed_trackId.end(), + std::back_inserter(vec_trackIdForResection)); + +#ifdef OPENMVG_USE_OPENMP + #pragma omp critical +#endif + { + vec_putative.push_back( make_pair(viewId, vec_trackIdForResection.size())); + } + } } } From 5b77c1c6d1f31f1a8158c711752c223bbb05b13e Mon Sep 17 00:00:00 2001 From: pmoulon Date: Sat, 30 May 2015 10:06:16 +0200 Subject: [PATCH 51/52] Fix install target for WIN platforms. #222 --- src/CMakeLists.txt | 11 +++-------- src/cmakeFindModules/OpenMVGConfig.cmake.in | 4 ++-- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 52ec5e4566..eb90a610f3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -24,8 +24,8 @@ OPTION(OpenMVG_BUILD_COVERAGE "Enable code coverage generation (gcc only)" OFF) OPTION(OpenMVG_USE_OPENMP "Enable OpenMP parallelization" ON) SET(OPENMVG_VERSION_MAJOR 0) -SET(OPENMVG_VERSION_MINOR 9) -SET(OPENMVG_VERSION_PATCH 0) +SET(OPENMVG_VERSION_MINOR 8) +SET(OPENMVG_VERSION_PATCH 1) SET(OPENMVG_VERSION ${OPENMVG_VERSION_MAJOR}.${OPENMVG_VERSION_MINOR}.${OPENMVG_VERSION_PATCH}) @@ -406,11 +406,6 @@ ENDIF(OpenMVG_USE_INTERNAL_CERES) CONFIGURE_FILE("${CMAKE_SOURCE_DIR}/cmakeFindModules/OpenMVGConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/OpenMVGConfig.cmake" @ONLY) -IF(UNIX) - INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/OpenMVGConfig.cmake" +INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/OpenMVGConfig.cmake" DESTINATION share/openMVG/cmake) -ELSEIF(WIN32) - INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/OpenMVGConfig.cmake" - DESTINATION cmake) -ENDIF() diff --git a/src/cmakeFindModules/OpenMVGConfig.cmake.in b/src/cmakeFindModules/OpenMVGConfig.cmake.in index 500c11e66b..f8bf894a7d 100644 --- a/src/cmakeFindModules/OpenMVGConfig.cmake.in +++ b/src/cmakeFindModules/OpenMVGConfig.cmake.in @@ -6,7 +6,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. # -# Config file for OpenMVG libary - Find OpenMVG & dependencies. +# Config file for OpenMVG library - Find OpenMVG & dependencies. # # This file is used by CMake when FIND_PACKAGE( OpenMVG ) is invoked (and # the directory containing this file is present in CMAKE_MODULE_PATH). @@ -86,7 +86,7 @@ ENDIF (NOT EXISTS ${CURRENT_ROOT_INSTALL_DIR}/include/openMVG/version.hpp) # Set the include directories for OpenMVG (itself) and all (potentially optional) # dependencies with which OpenMVG was compiled. -SET(OPENMVG_INCLUDE_DIRS @OpenMVG_INCLUDE_DIRS@) +SET(OPENMVG_INCLUDE_DIRS "@OpenMVG_INCLUDE_DIRS@") ##### the libraries themselves come in via OpenMVGTargets-.cmake # as link libraries rules as target. From c8cfdd057effcefb30baee45fd6933773001c078 Mon Sep 17 00:00:00 2001 From: pmoulon Date: Sat, 30 May 2015 10:07:57 +0200 Subject: [PATCH 52/52] Expend the doc. #222 --- BUILD | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/BUILD b/BUILD index fd82a72b12..3455574c0a 100644 --- a/BUILD +++ b/BUILD @@ -122,14 +122,27 @@ Using openCV sample Add -DOpenMVG_USE_OPENCV=ON to your cmake command line and set OpenCV_DIR variable to your openCV build directory => i.e.: -DOpenCV_DIR="/home/user/Dev/github/itseez/opencv_Build" -DOpenMVG_USE_OPENCV=ON ------------------------------------- -Using as library dependency in cmake ------------------------------------- +------------------------------------------------------------ +Using OpenMVG as a third party library dependency in cmake +------------------------------------------------------------- -Adding following lines to your CMakeLists.txt should provide OpenMVG usable as -static library: +OpenMVG can be used as a third party once it have been installed. +Because it can use it's own ceres version, it's better to install it locally and not in system files. +So please consider using the CMAKE_INSTALL_PREFIX cmake variable to specify a local installation directory. - add_subdirectory(openMVG/src) - include_directories(${OpenMVG_INCLUDE_DIRS}) - target_link_libraries(target ${OpenMVG_LIBRARIES}) +Here the syntax to add the variable to the cmake command line: +-DCMAKE_INSTALL_PREFIX:STRING="./openMVG_install" +Perform "make" and "make install" + +Once the library has been installed, go to your project that want use OpenMVG as an external library and add: + +FIND_PACKAGE(OpenMVG REQUIRED) +INCLUDE_DIRECTORIES(${OPENMVG_INCLUDE_DIRS}) +ADD_EXECUTABLE(main main.cpp) +TARGET_LINK_LIBRARIES(main ${OPENMVG_LIBRARIES}) + +Specify to CMAKE where OpenMVG have been installed by using the cmake OpenMVG_DIR variable that must point to: +-DOpenMVG_DIR:STRING="YourInstallPath"/share/openMVG/cmake + +A message will be displayed if OpenMVG is found or not at the cmake configure step.