Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@yanxke
Copy link
Contributor

@yanxke yanxke commented Jan 26, 2026

Improve the efficiency of geometric filtering by caching iterators, reducing the traversal complexity from O(n^2) to O(n) for each pair of matches.

I've been running into a wall where as I increase the number of pictures, the processing time increased exponentially and it just didn't make any sense.

image

As the number of pictures and features increased, most of the time was spent on geometric filtering, which should have been a simple and fast process. Eventually traced it down to this bug and and the fix completely eliminated the bottleneck and made the processing tractable.

Hope this helps everyone else who couldn't process a large number of photos.

@pmoulon please take a look at this. It's pretty significant.

my_progress_bar->Restart( putative_matches.size(), "- Geometric filtering -" );

// Cache iterators to avoid O(n^2) std::map traversal with advance().
std::vector<PairWiseMatches::const_iterator> match_iters;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it can be done in a oneliner
std::vector<PairWiseMatches::const_iterator> match_iters(putative_matches.cbegin(), putative_matches.cend());

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does look simpler, and I tried, but it doesn't work.

422.1 [ 81%] Building CXX object _deps/rerun_sdk-build/CMakeFiles/rerun_sdk.dir/src/rerun/datatypes/entity_path.cpp.o 423.2 In file included from /usr/include/c++/11/vector:66, 423.2 from /opt/openMVG/src/openMVG/features/akaze/AKAZE.hpp:37, 423.2 from /opt/openMVG/src/openMVG/features/akaze/image_describer_akaze.hpp:11, 423.2 from /opt/openMVG/src/software/SfM/main_GeometricFilter.cpp:9: 423.2 /usr/include/c++/11/bits/stl_uninitialized.h: In instantiation of '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::_Rb_tree_const_iterator<std::pair<const std::pair<unsigned int, unsigned int>, std::vector<openMVG::matching::IndMatch> > >; _ForwardIterator = std::_Rb_tree_const_iterator<std::pair<const std::pair<unsigned int, unsigned int>, std::vector<openMVG::matching::IndMatch> > >*]': 423.2 /usr/include/c++/11/bits/stl_uninitialized.h:333:37: required from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::_Rb_tree_const_iterator<std::pair<const std::pair<unsigned int, unsigned int>, std::vector<openMVG::matching::IndMatch> > >; _ForwardIterator = std::_Rb_tree_const_iterator<std::pair<const std::pair<unsigned int, unsigned int>, std::vector<openMVG::matching::IndMatch> > >*; _Tp = std::_Rb_tree_const_iterator<std::pair<const std::pair<unsigned int, unsigned int>, std::vector<openMVG::matching::IndMatch> > >]' 423.2 /usr/include/c++/11/bits/stl_vector.h:1585:33: required from 'void std::vector<_Tp, _Alloc>::_M_range_initialize(_ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = std::_Rb_tree_const_iterator<std::pair<const std::pair<unsigned int, unsigned int>, std::vector<openMVG::matching::IndMatch> > >; _Tp = std::_Rb_tree_const_iterator<std::pair<const std::pair<unsigned int, unsigned int>, std::vector<openMVG::matching::IndMatch> > >; _Alloc = std::allocator<std::_Rb_tree_const_iterator<std::pair<const std::pair<unsigned int, unsigned int>, std::vector<openMVG::matching::IndMatch> > > >]' 423.2 /usr/include/c++/11/bits/stl_vector.h:657:23: required from 'std::vector<_Tp, _Alloc>::vector(_InputIterator, _InputIterator, const allocator_type&) [with _InputIterator = std::_Rb_tree_const_iterator<std::pair<const std::pair<unsigned int, unsigned int>, std::vector<openMVG::matching::IndMatch> > >; <template-parameter-2-2> = void; _Tp = std::_Rb_tree_const_iterator<std::pair<const std::pair<unsigned int, unsigned int>, std::vector<openMVG::matching::IndMatch> > >; _Alloc = std::allocator<std::_Rb_tree_const_iterator<std::pair<const std::pair<unsigned int, unsigned int>, std::vector<openMVG::matching::IndMatch> > > >; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<std::_Rb_tree_const_iterator<std::pair<const std::pair<unsigned int, unsigned int>, std::vector<openMVG::matching::IndMatch> > > >]' 423.2 /opt/openMVG/src/openMVG/matching_image_collection/GeometricFilter.hpp:80:48: required from 'void openMVG::matching_image_collection::ImageCollectionGeometricFilter::Robust_model_estimation(const GeometryFunctor&, const openMVG::matching::PairWiseMatches&, bool, double, openMVG::system::ProgressInterface*) [with GeometryFunctor = openMVG::matching_image_collection::GeometricFilter_HMatrix_AC]' 423.2 /opt/openMVG/src/software/SfM/main_GeometricFilter.cpp:292:44: required from here 423.2 /usr/include/c++/11/bits/stl_uninitialized.h:138:72: error: static assertion failed: result type must be constructible from value type of input range 423.2 138 | static_assert(is_constructible<_ValueType2, decltype(*__first)>::value, 423.2 | ^~~~~ 423.2 /usr/include/c++/11/bits/stl_uninitialized.h:138:72: note: 'std::integral_constant<bool, false>::value' evaluates to false 423.9 [ 81%] Building CXX object _deps/rerun_sdk-build/CMakeFiles/rerun_sdk.dir/src/rerun/datatypes/float32.cpp.o

I'm not a C++ expert but it seems something to do with the range constructor copying the map entries instead of the iterators, and thus fails.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants