├── .clang-format ├── .gitignore ├── .travis.yml ├── CHANGELOG.rst ├── CMakeLists.txt ├── CatkinBuild.cmake ├── ColconBuild.cmake ├── Doxyfile.in ├── PureCMakeBuild.cmake ├── README.md ├── UseDoxygen.cmake ├── cmake └── configExtras.cmake ├── cmake_uninstall.cmake.in ├── contrib ├── CMakeLists.txt └── gtest │ ├── CHANGES │ ├── CONTRIBUTORS │ ├── LICENSE │ ├── README.md │ ├── gtest-all.cc │ ├── gtest.h │ └── gtest_main.cc ├── debian_legacy ├── changelog ├── compat ├── control ├── copyright ├── libpointmatcher-bin.dirs ├── libpointmatcher-bin.install ├── libpointmatcher-dev.dirs ├── libpointmatcher-dev.install ├── libpointmatcher-doc.dirs ├── libpointmatcher-doc.install ├── libpointmatcher1.dirs ├── libpointmatcher1.install ├── rules └── source │ └── format ├── doc ├── ApplicationsAndPub.md ├── ApplyingDatafilters.md ├── BasicRegistration.md ├── Compilation.md ├── CompilationMac.md ├── CompilationWindows.md ├── Configuration.md ├── DataPointsFilterDev.md ├── Datafilters.md ├── DefaultICPConfig.md ├── ICPIntro.md ├── ImportExport.md ├── Introduction.md ├── LinkingProjects.md ├── Pointclouds.md ├── ReleaseNotes.md ├── TransformationDev.md ├── Transformations.md ├── UnitTestDev.md ├── UsingInRos.md ├── icpWithoutYaml.md ├── images │ ├── .DS_Store │ ├── 2dTransMatrix.gif │ ├── 2dtestgrid.png │ ├── 2dvxgrid.png │ ├── 3d50mTrans.gif │ ├── 3dTransMatrix.gif │ ├── DefaultConvertChain.png │ ├── appt_0_maxdens.png │ ├── appt_0_rand.png │ ├── appt_dir.png │ ├── appt_norm.png │ ├── appt_obs_dir.png │ ├── appt_rand.png │ ├── appt_samp_norm_dense.png │ ├── appt_samp_norm_sparse.png │ ├── appt_top.png │ ├── appt_voxel.png │ ├── banner_dark.jpeg │ ├── banner_light.jpeg │ ├── box_filt.png │ ├── box_filt_inside.png │ ├── box_filt_outside.png │ ├── car_example.png │ ├── car_translated.png │ ├── cmake_screenshot.png │ ├── default_icp_chain.png │ ├── default_icp_chain.svg │ ├── descriptorsMatrix.png │ ├── distance_limit.png │ ├── featuresMatrix.png │ ├── floor_plan.png │ ├── hg_noise.png │ ├── icp_tutorial_links.gif │ ├── icp_tutorial_reading.gif │ ├── max_dens_after.png │ ├── max_dens_before.png │ ├── max_dis.png │ ├── max_num.png │ ├── max_quant.png │ ├── modular_cloud_matcher_icp_chain.png │ ├── norm.png │ ├── orient_norm.png │ ├── paraview_2_clouds.png │ ├── paraview_main.png │ ├── paraview_point_properties.png │ ├── samp_norm.png │ ├── win_cmake_libnabo.png │ ├── win_cmake_libpointmatcher.png │ └── youtubeCovers │ │ ├── M5Y99o7um88.jpg │ │ ├── McxpJGOZTPs.jpg │ │ ├── UCCAUf64tD0.jpg │ │ ├── cMgLyLpnsoU.jpg │ │ ├── g8l-Xq4qYeE.jpg │ │ ├── lP5Mj-TGaiw.jpg │ │ ├── rIZud3F5IJw.jpg │ │ ├── ygIvzWVfPYk.jpg │ │ └── youtube-play-button.xcf └── index.md ├── evaluations ├── CMakeLists.txt ├── eval_solution.cpp ├── jupyter │ └── PlotSingleResults.ipynb └── official_solutions │ ├── Besl92_pt2point.yaml │ └── Chen91_pt2plane.yaml ├── examples ├── CMakeLists.txt ├── align_sequence.cpp ├── build_map.cpp ├── compute_overlap.cpp ├── data │ ├── 2D_oneBox.csv │ ├── 2D_twoBoxes.csv │ ├── carCloudList.csv │ ├── car_cloud400.csv │ ├── car_cloud400_scaled.csv │ ├── car_cloud401.csv │ ├── cloud.00000.vtk │ ├── cloud.00001.vtk │ ├── cloud.00002.vtk │ ├── cloudList.csv │ ├── default-convert.yaml │ ├── default-identity.yaml │ ├── default.yaml │ ├── icp_data │ │ ├── SamplingSurfaceNormalDataPointsFilter1.ref_trans │ │ ├── SamplingSurfaceNormalDataPointsFilter1.yaml │ │ ├── SamplingSurfaceNormalDataPointsFilter2.ref_trans │ │ ├── SamplingSurfaceNormalDataPointsFilter2.yaml │ │ ├── SamplingSurfaceNormalDataPointsFilter3.ref_trans │ │ ├── SamplingSurfaceNormalDataPointsFilter3.yaml │ │ ├── defaultBoundingBoxDataPointsFilter.ref_trans │ │ ├── defaultBoundingBoxDataPointsFilter.yaml │ │ ├── defaultDistanceLimitDataPointsFilter.ref_trans │ │ ├── defaultDistanceLimitDataPointsFilter.yaml │ │ ├── defaultFixStepSamplingDataPointsFilter.ref_trans │ │ ├── defaultFixStepSamplingDataPointsFilter.yaml │ │ ├── defaultIdentityDataPointsFilter.ref_trans │ │ ├── defaultIdentityDataPointsFilter.yaml │ │ ├── defaultMaxDensityDataPointsFilter.ref_trans │ │ ├── defaultMaxDensityDataPointsFilter.yaml │ │ ├── defaultMaxDistDataPointsFilter.ref_trans │ │ ├── defaultMaxDistDataPointsFilter.yaml │ │ ├── defaultMaxPointCountDataPointsFilter.ref_trans │ │ ├── defaultMaxPointCountDataPointsFilter.yaml │ │ ├── defaultMaxQuantileOnAxisDataPointsFilter.ref_trans │ │ ├── defaultMaxQuantileOnAxisDataPointsFilter.yaml │ │ ├── defaultObservationDirectionDataPointsFilter.ref_trans │ │ ├── defaultObservationDirectionDataPointsFilter.yaml │ │ ├── defaultOrientNormalsDataPointsFilter.ref_trans │ │ ├── defaultOrientNormalsDataPointsFilter.yaml │ │ ├── defaultPointToPlaneMinDistDataPointsFilter.ref_trans │ │ ├── defaultPointToPlaneMinDistDataPointsFilter.yaml │ │ ├── defaultPointToPlaneWithCovErrorMinimizer.ref_trans │ │ ├── defaultPointToPointMinDistDataPointsFilter.ref_trans │ │ ├── defaultPointToPointMinDistDataPointsFilter.yaml │ │ ├── defaultPointToPointWithCovErrorMinimizer.ref_trans │ │ ├── defaultRemoveNaNDataPointsFilter.ref_trans │ │ ├── defaultRemoveNaNDataPointsFilter.yaml │ │ ├── defaultRobustOutlierFilter.ref_trans │ │ ├── defaultRobustOutlierFilter.yaml │ │ ├── defaultShadowDataPointsFilter.ref_trans │ │ ├── defaultShadowDataPointsFilter.yaml │ │ ├── defaultSimilarityPointToPointMinDistDataPointsFilter.ref_trans │ │ ├── defaultSimilarityPointToPointMinDistDataPointsFilter.yaml │ │ ├── defaultSimpleSensorNoiseDataPointsFilter.ref_trans │ │ ├── defaultSimpleSensorNoiseDataPointsFilter.yaml │ │ ├── force4DOFForPointToPlaneMinimizer.ref_trans │ │ └── force4DOFForPointToPlaneMinimizer.yaml │ ├── icp_point_to_plane.yaml │ ├── icp_scale.yaml │ └── unit_tests │ │ ├── badIcpConfig_InvalidModuleType.yaml │ │ └── badIcpConfig_InvalidParameter.yaml ├── demo_Qt │ ├── demo.pro │ └── main.cpp ├── demo_cmake │ ├── CMakeLists.txt │ ├── convert.cpp │ └── default-convert.yaml ├── filterProfiler.cpp ├── icp.cpp ├── icp_advance_api.cpp ├── icp_customized.cpp ├── icp_simple.cpp ├── icp_tutorial │ ├── cloud_0.vtk │ ├── cloud_1.vtk │ ├── icp_tutorial_cfg.yaml │ └── icp_tutorial_empty.yaml └── list_modules.cpp ├── libpointmatcherConfig.cmake.in ├── libpointmatcherConfigVersion.cmake.in ├── mkdocs.yml ├── package.xml ├── pointmatcher.pc.in ├── pointmatcher ├── Bibliography.cpp ├── Bibliography.h ├── DataPoints.cpp ├── DataPointsFilter.cpp ├── DataPointsFilters │ ├── BoundingBox.cpp │ ├── BoundingBox.h │ ├── CovarianceSampling.cpp │ ├── CovarianceSampling.h │ ├── CutAtDescriptorThreshold.cpp │ ├── CutAtDescriptorThreshold.h │ ├── DistanceLimit.cpp │ ├── DistanceLimit.h │ ├── Elipsoids.cpp │ ├── Elipsoids.h │ ├── FixStepSampling.cpp │ ├── FixStepSampling.h │ ├── Gestalt.cpp │ ├── Gestalt.h │ ├── HiddenPointRemoval.cpp │ ├── HiddenPointRemoval.h │ ├── Identity.cpp │ ├── Identity.h │ ├── IncidenceAngle.cpp │ ├── IncidenceAngle.h │ ├── MaxDensity.cpp │ ├── MaxDensity.h │ ├── MaxDist.cpp │ ├── MaxDist.h │ ├── MaxPointCount.cpp │ ├── MaxPointCount.h │ ├── MaxQuantileOnAxis.cpp │ ├── MaxQuantileOnAxis.h │ ├── MinDist.cpp │ ├── MinDist.h │ ├── NormalSpace.cpp │ ├── NormalSpace.h │ ├── ObservationDirection.cpp │ ├── ObservationDirection.h │ ├── OctreeGrid.cpp │ ├── OctreeGrid.h │ ├── OrganizedCloudSurfaceNormal.cpp │ ├── OrganizedCloudSurfaceNormal.h │ ├── OrientNormals.cpp │ ├── OrientNormals.h │ ├── RandomSampling.cpp │ ├── RandomSampling.h │ ├── RemoveNaN.cpp │ ├── RemoveNaN.h │ ├── RemoveSensorBias.cpp │ ├── RemoveSensorBias.h │ ├── SamplingSurfaceNormal.cpp │ ├── SamplingSurfaceNormal.h │ ├── Shadow.cpp │ ├── Shadow.h │ ├── SimpleSensorNoise.cpp │ ├── SimpleSensorNoise.h │ ├── SurfaceNormal.cpp │ ├── SurfaceNormal.h │ ├── VoxelGrid.cpp │ ├── VoxelGrid.h │ └── utils │ │ ├── octree │ │ ├── Octree.h │ │ ├── Octree.tpp │ │ ├── OctreeLookupTable.h │ │ ├── OctreeSamplers.h │ │ └── OctreeSamplers.tpp │ │ └── utils.h ├── DataPointsFiltersImpl.h ├── DeprecationWarnings.h ├── Documentation.dox ├── ErrorMinimizer.cpp ├── ErrorMinimizers │ ├── Identity.cpp │ ├── Identity.h │ ├── PointToPlane.cpp │ ├── PointToPlane.h │ ├── PointToPlaneWithCov.cpp │ ├── PointToPlaneWithCov.h │ ├── PointToPoint.cpp │ ├── PointToPoint.h │ ├── PointToPointSimilarity.cpp │ ├── PointToPointSimilarity.h │ ├── PointToPointWithCov.cpp │ └── PointToPointWithCov.h ├── ErrorMinimizersImpl.h ├── Exceptions.cpp ├── Functions.h ├── Histogram.cpp ├── Histogram.h ├── ICP.cpp ├── IO.cpp ├── IO.h ├── IOFunctions.cpp ├── IOFunctions.h ├── Inspector.cpp ├── InspectorsImpl.cpp ├── InspectorsImpl.h ├── Logger.cpp ├── LoggerImpl.cpp ├── LoggerImpl.h ├── Matcher.cpp ├── MatchersImpl.cpp ├── MatchersImpl.h ├── Matches.cpp ├── OutlierFilter.cpp ├── OutlierFiltersImpl.cpp ├── OutlierFiltersImpl.h ├── Parametrizable.cpp ├── Parametrizable.h ├── PointCloudGenerator.cpp ├── PointMatcher.h ├── PointMatcherPrivate.h ├── Registrar.cpp ├── Registrar.h ├── Registry.cpp ├── SurfaceNormalEstimatorPCA.cpp ├── Timer.cpp ├── Timer.h ├── Transformation.cpp ├── TransformationChecker.cpp ├── TransformationCheckersImpl.cpp ├── TransformationCheckersImpl.h ├── TransformationsImpl.cpp ├── TransformationsImpl.h └── testing │ ├── RegistrationTestCase.cpp │ ├── RegistrationTestCase.h │ ├── RegistrationTestResult.cpp │ ├── RegistrationTestResult.h │ ├── TransformationError.cpp │ ├── TransformationError.h │ ├── typedefs.h │ ├── utils_filesystem.cpp │ ├── utils_filesystem.h │ ├── utils_geometry.cpp │ ├── utils_geometry.h │ ├── utils_gtest.cpp │ ├── utils_gtest.h │ ├── utils_registration.cpp │ ├── utils_registration.h │ ├── utils_transformations.cpp │ └── utils_transformations.h └── utest ├── CMakeLists.txt ├── listVersionsUbuntu.sh ├── ui ├── DataFilters.cpp ├── DataPoints.cpp ├── ErrorMinimizers.cpp ├── IO.cpp ├── Inspectors.cpp ├── Loggers.cpp ├── Matcher.cpp ├── Outliers.cpp ├── PointCloudGenerator.cpp ├── Transformations.cpp ├── icp │ ├── Conditioning.cpp │ └── GeneralTests.cpp └── octree │ └── Octree.cpp ├── utest.cpp └── utest.h /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Mozilla 2 | AccessModifierOffset: '-4' 3 | AlignConsecutiveAssignments: false 4 | AlignConsecutiveDeclarations: false 5 | AlignEscapedNewlinesLeft: false 6 | AlignOperands: false 7 | AlignTrailingComments: false 8 | PointerAlignment: Left 9 | AllowAllParametersOfDeclarationOnNextLine: false 10 | AllowShortBlocksOnASingleLine: false 11 | AllowShortCaseLabelsOnASingleLine: true 12 | AllowShortFunctionsOnASingleLine: InlineOnly 13 | AllowShortIfStatementsOnASingleLine: false 14 | AllowShortLoopsOnASingleLine: false 15 | AlwaysBreakAfterDefinitionReturnType: None 16 | AlwaysBreakAfterReturnType: None 17 | AlwaysBreakTemplateDeclarations: true 18 | BinPackArguments: false 19 | BinPackParameters: true 20 | BreakBeforeBraces: Custom 21 | BreakBeforeTernaryOperators: true 22 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 23 | Cpp11BracedListStyle: false 24 | IndentCaseLabels: true 25 | Language: Cpp 26 | MaxEmptyLinesToKeep: '2' 27 | NamespaceIndentation: None 28 | FixNamespaceComments: true 29 | ReflowComments: false 30 | IncludeBlocks: Preserve 31 | SortIncludes: false 32 | SpaceBeforeAssignmentOperators: true 33 | SpaceBeforeParens: ControlStatements 34 | SpaceInEmptyParentheses: false 35 | Standard: Auto 36 | TabWidth: 4 37 | IndentWidth: 4 38 | UseTab: Never 39 | ColumnLimit: 140 40 | BreakConstructorInitializers: AfterColon 41 | BreakBeforeInheritanceComma : false 42 | ConstructorInitializerIndentWidth: 4 43 | SpacesInCStyleCastParentheses: false 44 | SpacesBeforeTrailingComments: 1 45 | ExperimentalAutoDetectBinPacking: true 46 | AllowAllParametersOfDeclarationOnNextLine: false 47 | ContinuationIndentWidth: 4 48 | BraceWrapping: 49 | SplitEmptyFunction: false 50 | AfterEnum: true 51 | AfterControlStatement: true 52 | AfterStruct: true 53 | AfterClass: true 54 | AfterFunction: true 55 | AfterNamespace: true 56 | AfterUnion: true 57 | BeforeCatch: true 58 | BeforeElse: true 59 | IndentBraces: false 60 | AlignAfterOpenBracket: Align 61 | BreakBeforeBinaryOperators: NonAssignment 62 | CommentPragmas: '^\\.+' -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.cproject 2 | *.project 3 | *~ 4 | *.swp 5 | *.cur_trans 6 | build 7 | .ipynb_checkpoints/ 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | 3 | compiler: 4 | - gcc 5 | 6 | # by default Ubuntu Trusty is included, so we have 14.04 + 16.04 7 | matrix: 8 | include: 9 | - os: linux 10 | dist: xenial 11 | sudo: required 12 | 13 | addons: 14 | apt: 15 | packages: 16 | - cmake 17 | - libboost-all-dev 18 | - libeigen3-dev 19 | 20 | 21 | install: 22 | - git clone git://github.com/ethz-asl/libnabo.git 23 | - cd libnabo 24 | - mkdir build && cd build 25 | - cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo .. 26 | - make 27 | - sudo make install 28 | 29 | script: 30 | - cd $TRAVIS_BUILD_DIR 31 | - mkdir build && cd build 32 | - cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_TESTS=ON --build . .. 33 | - make -j2 34 | - ctest --verbose -------------------------------------------------------------------------------- /cmake/configExtras.cmake: -------------------------------------------------------------------------------- 1 | find_package(Boost REQUIRED COMPONENTS chrono date_time filesystem program_options system thread timer) 2 | 3 | find_package(yaml-cpp QUIET) 4 | 5 | if(NOT yaml-cpp_FOUND) 6 | find_package(PkgConfig REQUIRED) 7 | pkg_check_modules(yaml-cpp REQUIRED IMPORTED_TARGET yaml-cpp) 8 | set(yaml_cpp_target "PkgConfig::yaml-cpp") 9 | else() 10 | set(yaml_cpp_target "yaml-cpp") 11 | endif() 12 | 13 | -------------------------------------------------------------------------------- /cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 2 | message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 3 | endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 4 | 5 | file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) 6 | string(REGEX REPLACE "\n" ";" files "${files}") 7 | foreach(file ${files}) 8 | message(STATUS "Uninstalling $ENV{DESTDIR}${file}") 9 | if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 10 | exec_program( 11 | "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 12 | OUTPUT_VARIABLE rm_out 13 | RETURN_VALUE rm_retval 14 | ) 15 | if(NOT "${rm_retval}" STREQUAL 0) 16 | message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") 17 | endif(NOT "${rm_retval}" STREQUAL 0) 18 | else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 19 | message(STATUS "File $ENV{DESTDIR}${file} does not exist.") 20 | endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 21 | endforeach(file) 22 | 23 | 24 | -------------------------------------------------------------------------------- /contrib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # External libraries packed with libpointmatcher 2 | 3 | # GTest 4 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 5 | add_library(gtest gtest/gtest-all.cc) 6 | -------------------------------------------------------------------------------- /contrib/gtest/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This file contains a list of people who've made non-trivial 2 | # contribution to the Google C++ Testing Framework project. People 3 | # who commit code to the project are encouraged to add their names 4 | # here. Please keep the list sorted by first names. 5 | 6 | Ajay Joshi 7 | Balázs Dán 8 | Bharat Mediratta 9 | Chandler Carruth 10 | Chris Prince 11 | Chris Taylor 12 | Dan Egnor 13 | Eric Roman 14 | Hady Zalek 15 | Jeffrey Yasskin 16 | Jói Sigurðsson 17 | Keir Mierle 18 | Keith Ray 19 | Kenton Varda 20 | Manuel Klimek 21 | Markus Heule 22 | Mika Raento 23 | Miklós Fazekas 24 | Pasi Valminen 25 | Patrick Hanna 26 | Patrick Riley 27 | Peter Kaminski 28 | Preston Jackson 29 | Rainer Klaffenboeck 30 | Russ Cox 31 | Russ Rufer 32 | Sean Mcafee 33 | Sigurður Ásgeirsson 34 | Tracy Bialik 35 | Vadim Berman 36 | Vlad Losev 37 | Zhanyong Wan 38 | -------------------------------------------------------------------------------- /contrib/gtest/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2008, Google Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following disclaimer 12 | in the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Google Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /contrib/gtest/gtest_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #include 31 | 32 | #include "gtest/gtest.h" 33 | 34 | GTEST_API_ int main(int argc, char **argv) { 35 | printf("Running main() from gtest_main.cc\n"); 36 | testing::InitGoogleTest(&argc, argv); 37 | return RUN_ALL_TESTS(); 38 | } 39 | -------------------------------------------------------------------------------- /debian_legacy/changelog: -------------------------------------------------------------------------------- 1 | libpointmatcher (1.2.0) UNRELEASED; urgency=low 2 | 3 | * Add a new data filter: VoxelGrid 4 | * Add support for PCL (Point Cloud Library) data format: PCD 5 | * Improved *.vtk legacy format to handle UNSTRUCTURED_GRID format 6 | * New ErrorMinimizer producing covariance matrix 7 | * Better user documentation and tutorials 8 | * Avoids point cloud copies when filtering 9 | * Add CMake support for find_package 10 | * Added support for PLY (Polygon File Format or the Stanford Triangle Format) for ascii encoding 11 | * Improved CSV file support with import/export of selected descriptors 12 | 13 | -- Samuel Charreyron Fri, 20 Jun 2014 13:23:06 +0200 14 | 15 | libpointmatcher (1.1.0) precise; urgency=low 16 | 17 | * new upstream release 18 | 19 | -- Stéphane Magnenat Wed, 04 Sep 2013 13:54:46 +0200 20 | 21 | libpointmatcher (1.0.0) precise; urgency=low 22 | 23 | * new upstream release 24 | 25 | -- Stéphane Magnenat Mon, 12 Nov 2012 09:54:00 -0800 26 | 27 | -------------------------------------------------------------------------------- /debian_legacy/compat: -------------------------------------------------------------------------------- 1 | 7 2 | -------------------------------------------------------------------------------- /debian_legacy/control: -------------------------------------------------------------------------------- 1 | Source: libpointmatcher 2 | Priority: extra 3 | Maintainer: Stéphane Magnenat 4 | Build-Depends: debhelper (>= 7.0.50~), cmake, doxygen, cdbs, libboost-all-dev, libeigen3-dev, ros-melodic-libnabo (>= 1.0.1~), yaml-cpp0.2.6-dev|libyaml-cpp-dev, libncurses5-dev 5 | Standards-Version: 3.9.1 6 | Section: libs 7 | Homepage: https://github.com/anybotics/libpointmatcher 8 | Vcs-Git: git://github.com/anybotics/libpointmatcher.git 9 | Vcs-Browser: https://github.com/anybotics/libpointmatcher 10 | 11 | Package: libpointmatcher 12 | Section: libdevel 13 | Architecture: any 14 | Depends: libpointmatcher1 (= ${binary:Version}), ros-melodic-libnabo (>= 1.0.1~), libboost-all-dev, libeigen3-dev, yaml-cpp0.2.6-dev|libyaml-cpp-dev, libncurses5-dev 15 | Suggests: libpointmatcher-doc 16 | Description: A modular ICP library, development headers. 17 | libpointmatcher is a modular ICP library, useful for robotics and 18 | computer vision. 19 | 20 | Package: libpointmatcher1-dbg 21 | Section: debug 22 | Architecture: any 23 | Depends: libpointmatcher1 (= ${binary:Version}), ${misc:Depends} 24 | Description: Debug symbols for libpointmatcher, a fast K Nearset Neighbor library. 25 | libpointmatcher is a modular ICP library, useful for robotics and 26 | computer vision. 27 | 28 | Package: libpointmatcher1 29 | Section: libs 30 | Architecture: any 31 | Depends: ${shlibs:Depends}, ${misc:Depends} 32 | Description: A modular ICP library, version 1. 33 | libpointmatcher is a modular ICP library, useful for robotics and 34 | computer vision. 35 | 36 | Package: libpointmatcher-bin 37 | Section: science 38 | Architecture: any 39 | Depends: libpointmatcher1 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} 40 | Description: A modular ICP library, ICP executable. 41 | libpointmatcher is a modular ICP library, useful for robotics and 42 | computer vision. 43 | 44 | Package: libpointmatcher-doc 45 | Section: doc 46 | Architecture: all 47 | Description: A modular ICP library, API documentation. 48 | libpointmatcher is a modular ICP library, useful for robotics and 49 | computer vision. 50 | 51 | 52 | -------------------------------------------------------------------------------- /debian_legacy/copyright: -------------------------------------------------------------------------------- 1 | Format: http://dep.debian.net/deps/dep5 2 | Upstream-Name: libpointmatcher 3 | Source: https://github.com/anybotics/libpointmatcher 4 | 5 | Files: * 6 | Copyright: 2010--2014, François Pomerleau and Stephane Magnenat , ASL, ETHZ, Switzerland 7 | License: BSD-3-Clause 8 | 9 | Files: debian/* 10 | Copyright: 2011 Stéphane Magnenat 11 | License: BSD-3-Clause 12 | 13 | License: BSD-3-Clause 14 | Redistribution and use in source and binary forms, with or without 15 | modification, are permitted provided that the following conditions 16 | are met: 17 | 1. Redistributions of source code must retain the above copyright 18 | notice, this list of conditions and the following disclaimer. 19 | 2. Redistributions in binary form must reproduce the above copyright 20 | notice, this list of conditions and the following disclaimer in the 21 | documentation and/or other materials provided with the distribution. 22 | 3. Neither the name of the University nor the names of its contributors 23 | may be used to endorse or promote products derived from this software 24 | without specific prior written permission. 25 | . 26 | THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 | SUCH DAMAGE. 37 | -------------------------------------------------------------------------------- /debian_legacy/libpointmatcher-bin.dirs: -------------------------------------------------------------------------------- 1 | usr/bin 2 | -------------------------------------------------------------------------------- /debian_legacy/libpointmatcher-bin.install: -------------------------------------------------------------------------------- 1 | usr/bin/pmicp 2 | -------------------------------------------------------------------------------- /debian_legacy/libpointmatcher-dev.dirs: -------------------------------------------------------------------------------- 1 | usr/include 2 | usr/lib -------------------------------------------------------------------------------- /debian_legacy/libpointmatcher-dev.install: -------------------------------------------------------------------------------- 1 | usr/include/* 2 | usr/lib/lib*.so 3 | -------------------------------------------------------------------------------- /debian_legacy/libpointmatcher-doc.dirs: -------------------------------------------------------------------------------- 1 | usr/share/doc -------------------------------------------------------------------------------- /debian_legacy/libpointmatcher-doc.install: -------------------------------------------------------------------------------- 1 | usr/share/doc/libpointmatcher-doc/* 2 | -------------------------------------------------------------------------------- /debian_legacy/libpointmatcher1.dirs: -------------------------------------------------------------------------------- 1 | usr/lib 2 | -------------------------------------------------------------------------------- /debian_legacy/libpointmatcher1.install: -------------------------------------------------------------------------------- 1 | usr/lib/lib*.so.* 2 | -------------------------------------------------------------------------------- /debian_legacy/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | # Sample debian/rules that uses debhelper. 4 | # This file was originally written by Joey Hess and Craig Small. 5 | # As a special exception, when this file is copied by dh-make into a 6 | # dh-make output file, you may use that output file without restriction. 7 | # This special exception was added by Craig Small in version 0.37 of dh-make. 8 | 9 | # Uncomment this to turn on verbose mode. 10 | #export DH_VERBOSE=1 11 | 12 | #%: 13 | # dh $@ 14 | 15 | DEB_CMAKE_EXTRA_FLAGS=-DSHARED_LIBS=true -DDOC_INSTALL_TARGET="share/doc/libpointmatcher-doc/api" 16 | 17 | include /usr/share/cdbs/1/rules/debhelper.mk 18 | include /usr/share/cdbs/1/class/cmake.mk 19 | -------------------------------------------------------------------------------- /debian_legacy/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /doc/DefaultICPConfig.md: -------------------------------------------------------------------------------- 1 | | [Tutorials Home](index.md) | [Previous](ICPIntro.md) | [Next](Configuration.md) | 2 | | ------------- |:-------------:| -----:| 3 | 4 | # Default Configuration of the ICP Chain 5 | 6 | The following details the default configuration for ICP in libpointmatcher. 7 | 8 | |Figure 1: Default ICP chain configuration| 9 | |:------| 10 | |![Default ICP Chain Configuration](images/default_icp_chain.svg)| 11 | 12 | ## Data Filters 13 | Both the reference and reading clouds are processed with [random sampling](Datafilters.md#randomsamplinghead) filters. These will sample each data point with a probability of 0.75 thus yielding smaller point clouds. 14 | 15 | ## Matcher 16 | The default matcher is the KD tree matcher. Each point is matched to its closest neighbor in the reference cloud. A KD tree with a linear heap is used. 17 | 18 | ## Outlier Filters 19 | One trimmed distance outlier filter is used. The filter ranks the points in the reading cloud by their distance to the reference after a transformation was applied. The top 85% points (those with the smallest distances) are kept. 20 | 21 | ## Minimizer 22 | The point-to-plane variant is used in the minimization step. Point-to-plane allows for points to "slide" along planes and generally performs better than the point-to-point variant. 23 | 24 | ## Transformation Checkers 25 | The counter checker automatically stops the ICP loop after a maximum of 40 iterations. The differential transformation checker stops the ICP loop when the relative transformation motions between iterations is below a threshold. In other words, when each subsequent iteration produces little change in the transformation, then the algorithm is stopped. Because the relative motions are generally prone to jagged oscillations, smoothing is applied by taking the average the relative differences over several iterations. 26 | 27 | ## Inspectors 28 | No inspector is applied. 29 | -------------------------------------------------------------------------------- /doc/Introduction.md: -------------------------------------------------------------------------------- 1 | # What is libpointmatcher about? 2 | 3 | libpointmatcher is a library that implements the Iterative Closest 4 | Point (ICP) algorithm for alignment of point clouds. It supports both 5 | point-to-point and point-to-plane ICP. With the former, it is able to 6 | solve not only for a rigid transform, but also for a scale change 7 | between the clouds (that is, a similarity transform). 8 | 9 | More precisely, given two point clouds, R (the reference) and S (the 10 | source), ICP tries to find the best rigid (or similarity) transform T 11 | so that T * S = R. 12 | 13 | The [Wikipedia article on ICP](https://en.wikipedia.org/wiki/Iterative_closest_point) has more 14 | information. 15 | 16 | libpointmatcher implements a [set of filters](Datafilters.md) to help 17 | denoise and subsample the input point clouds. It supports a [variety 18 | of file types](ImportExport.md) and it can be configured via both 19 | [YAML files](Configuration.md) and an [in-memory API](icpWithoutYaml.md). 20 | 21 | libpointmatcher is written in C++. 22 | 23 | 24 | -------------------------------------------------------------------------------- /doc/Pointclouds.md: -------------------------------------------------------------------------------- 1 | | [Tutorials Home](index.md) | [Previous](UsingInRos.md) | [Next](Transformations.md) | 2 | | ------------- |:-------------:| -----:| 3 | 4 | # Point Clouds in Libpointmatcher 5 | 6 | The base structure containing library functionality is called `PointMatcher`. It is restricted to a particular scalar type T through the use of a template: `PointMatcher`. In almost all situations the type T will either be `double` or `float` and provides developers with the flexibility of choosing which best suits their application. For simplicity, we recommend using an abbreviated type identifier for `PointMatcher`. This could for example be the following: 7 | ```cpp 8 | typedef PointMatcher PM; 9 | ``` 10 | 11 | In libpointmatcher, point clouds are encapsulated in `DataPoints` objects. DataPoints objects are composed of the following members : 12 | 13 | * Features matrix 14 | * Feature Labels 15 | * Descriptors matrix 16 | * Descriptor Labels 17 | 18 | ### Features Matrix 19 | Features is an [Eigen matrix](http://eigen.tuxfamily.org/dox/classEigen_1_1Matrix.html) typically containing the coordinates of the points which form the cloud. Each column corresponds to a point in the cloud. The rows correspond to the dimensions of the points in homogeneous coordinates. Homogeneous coordinates are used to allow for translations and rotations. For 2D point clouds, there will thus be 3 rows and for 4 rows for 3D point clouds. 20 | 21 | ![features matrix](images/featuresMatrix.png) 22 | 23 | ### Feature Labels 24 | Each row of the features matrix can be given a human readable label such as ¨X¨,¨Y¨, or ¨Z¨ and the group of labels is stored as a vector. 25 | 26 | ### Descriptors 27 | Descriptors are additional information about each point in the cloud. For example these may include an orientation vector pointing to the sensor location, or a surface normal vector. Following the structure of the features matrix, descriptors are stored in a single Eigen matrix with each column representing a point in the cloud. Descriptors are stacked in the rows of the features matrix and thus a single descriptors will span several rows. 28 | 29 | ![descriptors matrix](images/descriptorsMatrix.png) 30 | 31 | ### Descriptor Labels 32 | Human readable labels are used to identify the individual descriptors in the descriptors matrix. For example if the point cloud contains a 3D orientation and 3D surface normal descriptors for each points we may assign the label: "orientation" to the first three rows of the descriptor matrix and the label "normal" to the last three. 33 | -------------------------------------------------------------------------------- /doc/ReleaseNotes.md: -------------------------------------------------------------------------------- 1 | Release Notes 2 | ============= 3 | 4 | Wish list for next release 5 | -------------------------- 6 | 7 | * Change the API to allow only on kind of transformation, not a list of transformations. See issue [#164](https://github.com/anybotics/libpointmatcher/issues/164). 8 | * Migrate ffrom yaml-cpp 0.3 to 0.5 9 | * Fix portability problem with FileLogger on Windows 10 | * Support for OpenMP parallel computing 11 | * Handle larger point clouds (100 million points and more) 12 | 13 | Already implemented in the current master: 14 | 15 | * add a new OutlierFilter: RobustWelschOutlierFilter (for robust cost function using Welsch weighting). 16 | * Add a new ErrorMinimizer: PointToPointSimilarityErrorMinimizer (rotation + translation + scale) 17 | * Add a new Transformation: SimilarityTransformation. 18 | * Add a new data filter: [VoxelGrid](https://github.com/anybotics/libpointmatcher/blob/master/doc/Datafilters.md#voxel-grid-filter-) (April 2014, thanks to Samuel Charreyron) 19 | * Add support for PCL ([Point Cloud Library](http://pointclouds.org/)) data format: PCD (April 2014, thanks to Samuel Charreyron) 20 | * Improve *.vtk legacy format to handle UNSTRUCTURED_GRID format (April 2014, thanks to Samuel Charreyron) 21 | * New ErrorMinimizer producing covariance matrix (1 April, 2014, thanks to Francisco J Perez Grau) 22 | * Better user [documentation and tutorials](https://github.com/anybotics/libpointmatcher/blob/master/doc/index.md) (5 Fev. 2014 thanks to Samuel Charreyron) 23 | * Avoid point cloud copies when filtering (10 Jan. 2014 thanks to Oleg Alexandrov) 24 | * Add CMake support for find_package (20 Sept. 2013) 25 | * Added support for PLY ([Polygon File Format or the Stanford Triangle Format](http://en.wikipedia.org/wiki/PLY_(file_format))) for ascii encoding (14 March, 2014) 26 | * Improved CSV file support with import/export of selected descriptors 27 | 28 | 29 | Version 1.1.0 30 | -------------- 31 | 32 | * Removed C++0x dependency 33 | * Added compatibility with Visual Studio 11 34 | * Fixed various bugs 35 | * Added optimisation of 2-D pose with 3-D data 36 | 37 | Version 1.0.0 38 | ------------- 39 | 40 | * First release with a stable API 41 | -------------------------------------------------------------------------------- /doc/UsingInRos.md: -------------------------------------------------------------------------------- 1 | | [Tutorials Home](index.md) | [Previous](LinkingProjects.md) | [Next](Pointclouds.md) | 2 | | ------------- |:-------------:| -----:| 3 | 4 | # Using libpointmatcher in ROS 5 | 6 | If you want to use libpointmatcher in [ROS](http://www.ros.org/), you can use the [pointmatcher_ros](https://github.com/anybotics/pointmatcher-ros) stack. It allows the conversion of pointclouds from ROS message formats to a libpointmatcher-compatible format and provides a mapping node that is already functionnal and that can be customized using YAML configuration files to suite your needs. It also provides an odometry estimation based on the results of the pointcloud registrations. It includes a wide range of launch files that can be used as usage examples of the different nodes of the stack. Finally, it is recommended to install it from sources rather than from apt-get, because the last release was a long time ago, and it might not be working. 7 | -------------------------------------------------------------------------------- /doc/images/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/.DS_Store -------------------------------------------------------------------------------- /doc/images/2dTransMatrix.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/2dTransMatrix.gif -------------------------------------------------------------------------------- /doc/images/2dtestgrid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/2dtestgrid.png -------------------------------------------------------------------------------- /doc/images/2dvxgrid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/2dvxgrid.png -------------------------------------------------------------------------------- /doc/images/3d50mTrans.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/3d50mTrans.gif -------------------------------------------------------------------------------- /doc/images/3dTransMatrix.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/3dTransMatrix.gif -------------------------------------------------------------------------------- /doc/images/DefaultConvertChain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/DefaultConvertChain.png -------------------------------------------------------------------------------- /doc/images/appt_0_maxdens.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/appt_0_maxdens.png -------------------------------------------------------------------------------- /doc/images/appt_0_rand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/appt_0_rand.png -------------------------------------------------------------------------------- /doc/images/appt_dir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/appt_dir.png -------------------------------------------------------------------------------- /doc/images/appt_norm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/appt_norm.png -------------------------------------------------------------------------------- /doc/images/appt_obs_dir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/appt_obs_dir.png -------------------------------------------------------------------------------- /doc/images/appt_rand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/appt_rand.png -------------------------------------------------------------------------------- /doc/images/appt_samp_norm_dense.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/appt_samp_norm_dense.png -------------------------------------------------------------------------------- /doc/images/appt_samp_norm_sparse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/appt_samp_norm_sparse.png -------------------------------------------------------------------------------- /doc/images/appt_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/appt_top.png -------------------------------------------------------------------------------- /doc/images/appt_voxel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/appt_voxel.png -------------------------------------------------------------------------------- /doc/images/banner_dark.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/banner_dark.jpeg -------------------------------------------------------------------------------- /doc/images/banner_light.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/banner_light.jpeg -------------------------------------------------------------------------------- /doc/images/box_filt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/box_filt.png -------------------------------------------------------------------------------- /doc/images/box_filt_inside.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/box_filt_inside.png -------------------------------------------------------------------------------- /doc/images/box_filt_outside.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/box_filt_outside.png -------------------------------------------------------------------------------- /doc/images/car_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/car_example.png -------------------------------------------------------------------------------- /doc/images/car_translated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/car_translated.png -------------------------------------------------------------------------------- /doc/images/cmake_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/cmake_screenshot.png -------------------------------------------------------------------------------- /doc/images/default_icp_chain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/default_icp_chain.png -------------------------------------------------------------------------------- /doc/images/descriptorsMatrix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/descriptorsMatrix.png -------------------------------------------------------------------------------- /doc/images/distance_limit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/distance_limit.png -------------------------------------------------------------------------------- /doc/images/featuresMatrix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/featuresMatrix.png -------------------------------------------------------------------------------- /doc/images/floor_plan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/floor_plan.png -------------------------------------------------------------------------------- /doc/images/hg_noise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/hg_noise.png -------------------------------------------------------------------------------- /doc/images/icp_tutorial_links.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/icp_tutorial_links.gif -------------------------------------------------------------------------------- /doc/images/icp_tutorial_reading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/icp_tutorial_reading.gif -------------------------------------------------------------------------------- /doc/images/max_dens_after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/max_dens_after.png -------------------------------------------------------------------------------- /doc/images/max_dens_before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/max_dens_before.png -------------------------------------------------------------------------------- /doc/images/max_dis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/max_dis.png -------------------------------------------------------------------------------- /doc/images/max_num.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/max_num.png -------------------------------------------------------------------------------- /doc/images/max_quant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/max_quant.png -------------------------------------------------------------------------------- /doc/images/modular_cloud_matcher_icp_chain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/modular_cloud_matcher_icp_chain.png -------------------------------------------------------------------------------- /doc/images/norm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/norm.png -------------------------------------------------------------------------------- /doc/images/orient_norm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/orient_norm.png -------------------------------------------------------------------------------- /doc/images/paraview_2_clouds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/paraview_2_clouds.png -------------------------------------------------------------------------------- /doc/images/paraview_main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/paraview_main.png -------------------------------------------------------------------------------- /doc/images/paraview_point_properties.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/paraview_point_properties.png -------------------------------------------------------------------------------- /doc/images/samp_norm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/samp_norm.png -------------------------------------------------------------------------------- /doc/images/win_cmake_libnabo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/win_cmake_libnabo.png -------------------------------------------------------------------------------- /doc/images/win_cmake_libpointmatcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/win_cmake_libpointmatcher.png -------------------------------------------------------------------------------- /doc/images/youtubeCovers/M5Y99o7um88.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/youtubeCovers/M5Y99o7um88.jpg -------------------------------------------------------------------------------- /doc/images/youtubeCovers/McxpJGOZTPs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/youtubeCovers/McxpJGOZTPs.jpg -------------------------------------------------------------------------------- /doc/images/youtubeCovers/UCCAUf64tD0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/youtubeCovers/UCCAUf64tD0.jpg -------------------------------------------------------------------------------- /doc/images/youtubeCovers/cMgLyLpnsoU.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/youtubeCovers/cMgLyLpnsoU.jpg -------------------------------------------------------------------------------- /doc/images/youtubeCovers/g8l-Xq4qYeE.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/youtubeCovers/g8l-Xq4qYeE.jpg -------------------------------------------------------------------------------- /doc/images/youtubeCovers/lP5Mj-TGaiw.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/youtubeCovers/lP5Mj-TGaiw.jpg -------------------------------------------------------------------------------- /doc/images/youtubeCovers/rIZud3F5IJw.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/youtubeCovers/rIZud3F5IJw.jpg -------------------------------------------------------------------------------- /doc/images/youtubeCovers/ygIvzWVfPYk.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/youtubeCovers/ygIvzWVfPYk.jpg -------------------------------------------------------------------------------- /doc/images/youtubeCovers/youtube-play-button.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANYbotics/libpointmatcher/a12060c9cd44e1ec5a8bacecb93ddbd6a9eb95f9/doc/images/youtubeCovers/youtube-play-button.xcf -------------------------------------------------------------------------------- /doc/index.md: -------------------------------------------------------------------------------- 1 | ![alt tag](images/banner_light.jpeg) 2 | 3 | 4 | --- 5 | 6 | Tutorials 7 | ========= 8 | 9 | This page lists the available tutorials for libpointmatcher. The [Beginner Section](#beginner) is aimed at the more casual user and contains high-level information on the various steps of point cloud registration. The [Advanced Section](#advanced) is targeted at those with existing experience with point cloud registration and proficiency in C++ development. Those who wish to contribute to libpointmatcher can follow the guidelines in the [Developer](#developer) section. 10 | 11 | Beginner 12 | --------- 13 | 14 | - [What is libpointmatcher about?](Introduction.md) 15 | - [What can I do with libpointmatcher?](ApplicationsAndPub.md) 16 | - [Ubuntu: How to compile libpointmatcher](Compilation.md) 17 | - [Windows: How to compile libpointmatcher](CompilationWindows.md) 18 | - [Mac OS X: How to compile libpointmatcher](CompilationMac.md) 19 | - [What the different data filters do?](Datafilters.md) 20 | - [Example: Applying a chain of data filters](ApplyingDatafilters.md) 21 | - [Example: An introduction to ICP](ICPIntro.md) 22 | - [The ICP chain configuration and its variants](DefaultICPConfig.md) 23 | - [Configuring libpointmatcher using YAML](Configuration.md) 24 | - [Supported file types and importing/exporting point clouds](ImportExport.md) 25 | 26 | Advanced 27 | ------- 28 | - [How to link a project to libpointmatcher?](LinkingProjects.md) 29 | - [How to use libpointmatcher in ROS?](UsingInRos.md) 30 | - [How are point clouds represented?](Pointclouds.md) 31 | - [Example: Writing a program which performs ICP](BasicRegistration.md) 32 | - [How to move a point cloud using a rigid transformation?](Transformations.md) 33 | - [Example: Configure an ICP solution without yaml](icpWithoutYaml.md) 34 | - Measuring Hausdorff distance, Haussdorff quantile and mean residual error? [See this discussion for code examples.](https://github.com/anybotics/libpointmatcher/issues/125) 35 | - How to compute the residual error with `ErrorMinimizer::getResidualError(...)` [See the example code provided here.](https://github.com/anybotics/libpointmatcher/issues/193#issue-203885636) 36 | - How to I build a global map from a sequence of scans? [See the example align_sequence.cpp](../examples/align_sequence.cpp ). 37 | - How to minimize the error with translation, rotation and scale? [See this example.](https://github.com/anybotics/libpointmatcher/issues/188#issuecomment-270960696) 38 | - How to do a nearest neighbor search between two point clouds without an ICP object? [See the comments here.](https://github.com/anybotics/libpointmatcher/issues/193#issuecomment-276093785) 39 | - How to construct a `DataPoints` from my own point cloud? [See the unit test on `Datapoints` here.](https://github.com/anybotics/libpointmatcher/blob/master/utest/ui/DataFilters.cpp#L52) 40 | 41 | Developer 42 | --------- 43 | - [Creating a DataPointsFilter](DataPointsFilterDev.md) 44 | - [Creating a Transformation](TransformationDev.md) 45 | - [Creating unit tests](UnitTestDev.md) 46 | 47 | **Note**: if you don't find what you need, don't hesitate to propose or participate to new tutorials. 48 | 49 | --- 50 | 51 | 52 | ![alt tag](images/banner_dark.jpeg) 53 | -------------------------------------------------------------------------------- /evaluations/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if (yamlcpp_FOUND) 2 | find_package(Curses) 3 | if (CURSES_FOUND) 4 | add_executable(eval_solution eval_solution.cpp) 5 | target_link_libraries(eval_solution pointmatcher ${NABO_LIBRARY} ${EXTRA_LIBS} ${Boost_LIBRARIES} ${CURSES_LIBRARY}) 6 | else(CURSES_FOUND) 7 | message("-- ncurses not found, disabling evaluation") 8 | endif(CURSES_FOUND) 9 | endif (yamlcpp_FOUND) -------------------------------------------------------------------------------- /evaluations/official_solutions/Besl92_pt2point.yaml: -------------------------------------------------------------------------------- 1 | # Solution based on: 2 | # P Besl and H McKay, 1992. A method for registration of 3-D shapes. 3 | # Pattern Analysis and Machine Intelligence, IEEE Transactions on, 14, pp. 239 - 256. 4 | # - and - 5 | # Chetverikov, D and Svirko, D and Stepanov, D and Krsek, P, 2002. The Trimmed Iterative Closest 6 | # Point algorithm. Pattern Recognition, 2002. Proceedings. 16th International Conference on, 3, pp. 2724 - 2729. 7 | readingDataPointsFilters: 8 | - MinDistDataPointsFilter: 9 | minDist: 1.0 10 | - RandomSamplingDataPointsFilter: 11 | prob: 0.05 12 | 13 | referenceDataPointsFilters: 14 | - MinDistDataPointsFilter: 15 | minDist: 1.0 16 | - RandomSamplingDataPointsFilter: 17 | prob: 0.05 18 | 19 | matcher: 20 | KDTreeMatcher: 21 | knn: 1 22 | epsilon: 3.16 23 | 24 | outlierFilters: 25 | - TrimmedDistOutlierFilter: 26 | ratio: 0.75 27 | 28 | errorMinimizer: 29 | PointToPointErrorMinimizer 30 | 31 | transformationCheckers: 32 | - CounterTransformationChecker: 33 | maxIterationCount: 150 34 | - DifferentialTransformationChecker: 35 | minDiffRotErr: 0.001 36 | minDiffTransErr: 0.01 37 | smoothLength: 4 38 | 39 | inspector: 40 | PerformanceInspector 41 | 42 | logger: 43 | # FileLogger 44 | NullLogger 45 | 46 | -------------------------------------------------------------------------------- /evaluations/official_solutions/Chen91_pt2plane.yaml: -------------------------------------------------------------------------------- 1 | # Solution based on: 2 | # Y Chen and G Medioni, 1991. Object modeling by registration of multiple range images. Robotics and 3 | # Automation. Proc. of IEEE International Conf. on, 3, pp. 2724 - 2729. 4 | # - and - 5 | # Chetverikov, D and Svirko, D and Stepanov, D and Krsek, P, 2002. The Trimmed Iterative Closest 6 | # Point algorithm. Pattern Recognition, 2002. Proceedings. 16th International Conference on, 3, pp. 2724 - 2729. 7 | readingDataPointsFilters: 8 | - MinDistDataPointsFilter: 9 | minDist: 1.0 10 | - RandomSamplingDataPointsFilter: 11 | prob: 0.05 12 | 13 | referenceDataPointsFilters: 14 | - MinDistDataPointsFilter: 15 | minDist: 1.0 16 | - SamplingSurfaceNormalDataPointsFilter: 17 | knn: 7 18 | samplingMethod: 1 19 | ratio: 0.1 20 | 21 | matcher: 22 | KDTreeMatcher: 23 | knn: 1 24 | epsilon: 3.16 25 | 26 | outlierFilters: 27 | - TrimmedDistOutlierFilter: 28 | ratio: 0.7 29 | 30 | errorMinimizer: 31 | PointToPlaneErrorMinimizer 32 | 33 | transformationCheckers: 34 | - CounterTransformationChecker: 35 | maxIterationCount: 150 36 | - DifferentialTransformationChecker: 37 | minDiffRotErr: 0.001 38 | minDiffTransErr: 0.01 39 | smoothLength: 4 40 | 41 | inspector: 42 | PerformanceInspector 43 | 44 | logger: 45 | # FileLogger 46 | NullLogger 47 | 48 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(pmicp icp.cpp) 2 | target_link_libraries(pmicp pointmatcher) 3 | install(TARGETS pmicp RUNTIME DESTINATION bin) 4 | 5 | add_executable(icp_simple icp_simple.cpp) 6 | target_link_libraries(icp_simple pointmatcher) 7 | 8 | add_executable(align_sequence align_sequence.cpp) 9 | target_link_libraries(align_sequence pointmatcher) 10 | 11 | add_executable(list_modules list_modules.cpp) 12 | target_link_libraries(list_modules pointmatcher) 13 | 14 | add_executable(build_map build_map.cpp) 15 | target_link_libraries(build_map pointmatcher) 16 | 17 | add_executable(compute_overlap compute_overlap.cpp) 18 | target_link_libraries(compute_overlap pointmatcher) 19 | 20 | add_executable(icp_advance_api icp_advance_api.cpp) 21 | target_link_libraries(icp_advance_api pointmatcher) 22 | 23 | add_executable(icp_customized icp_customized.cpp) 24 | target_link_libraries(icp_customized pointmatcher) 25 | -------------------------------------------------------------------------------- /examples/data/carCloudList.csv: -------------------------------------------------------------------------------- 1 | reading, gT00, gT01, gT02, gT03, gT10, gT11, gT12, gT13, gT20, gT21, gT22, gT23, gT30, gT31, gT32, gT33 2 | car_cloud400.csv, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 3 | car_cloud401.csv, 0.981715, 0.169605, -0.0864239, 0.0614127, -0.152902, 0.973034, 0.172703, 0.191433, 0.113385, -0.15633, 0.981175, -0.0338571, 0, 0, 0, 1 4 | -------------------------------------------------------------------------------- /examples/data/cloudList.csv: -------------------------------------------------------------------------------- 1 | reading 2 | cloud.00000.vtk 3 | cloud.00001.vtk 4 | cloud.00002.vtk 5 | -------------------------------------------------------------------------------- /examples/data/default-convert.yaml: -------------------------------------------------------------------------------- 1 | - BoundingBoxDataPointsFilter: 2 | xMin: -4.0 3 | xMax: 4.0 4 | yMin: -4.0 5 | yMax: 4.0 6 | zMin: -4.0 7 | zMax: 4.0 8 | removeInside: 1 9 | - SamplingSurfaceNormalDataPointsFilter: 10 | knn: 10 11 | - ObservationDirectionDataPointsFilter 12 | - OrientNormalsDataPointsFilter 13 | -------------------------------------------------------------------------------- /examples/data/default-identity.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - IdentityDataPointsFilter: 3 | 4 | referenceDataPointsFilters: 5 | - SamplingSurfaceNormalDataPointsFilter: 6 | knn: 10 7 | ratio: 1.0 8 | samplingMethod: 0 9 | averageExistingDescriptors: 0 10 | 11 | matcher: 12 | KDTreeMatcher: 13 | knn: 1 14 | epsilon: 0 15 | 16 | outlierFilters: 17 | - TrimmedDistOutlierFilter: 18 | ratio: 1.0 19 | 20 | errorMinimizer: 21 | PointToPlaneErrorMinimizer 22 | 23 | transformationCheckers: 24 | - CounterTransformationChecker: 25 | maxIterationCount: 40 26 | - DifferentialTransformationChecker: 27 | minDiffRotErr: 0.001 28 | minDiffTransErr: 0.01 29 | smoothLength: 4 30 | 31 | inspector: 32 | NullInspector 33 | # VTKFileInspector 34 | 35 | logger: 36 | NullLogger 37 | # FileLogger 38 | 39 | -------------------------------------------------------------------------------- /examples/data/default.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - RandomSamplingDataPointsFilter: 3 | prob: 0.5 4 | 5 | referenceDataPointsFilters: 6 | - SamplingSurfaceNormalDataPointsFilter: 7 | knn: 10 8 | 9 | matcher: 10 | KDTreeMatcher: 11 | knn: 1 12 | epsilon: 0 13 | 14 | outlierFilters: 15 | - TrimmedDistOutlierFilter: 16 | ratio: 0.75 17 | 18 | errorMinimizer: 19 | PointToPlaneErrorMinimizer 20 | 21 | transformationCheckers: 22 | - CounterTransformationChecker: 23 | maxIterationCount: 40 24 | - DifferentialTransformationChecker: 25 | minDiffRotErr: 0.001 26 | minDiffTransErr: 0.01 27 | smoothLength: 4 28 | 29 | #inspector: 30 | # NullInspector 31 | 32 | inspector: 33 | VTKFileInspector: 34 | baseFileName: pointmatcher-run1 35 | dumpPerfOnExit: 0 36 | dumpStats: 0 37 | dumpIterationInfo: 1 38 | dumpDataLinks: 0 39 | dumpReading: 0 40 | dumpReference: 0 41 | 42 | 43 | logger: 44 | NullLogger 45 | # FileLogger 46 | 47 | -------------------------------------------------------------------------------- /examples/data/icp_data/SamplingSurfaceNormalDataPointsFilter1.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9807664752006531 -0.1583272665739059 0.1141471043229103 -0.08772790431976318 2 | 0.1750310957431793 0.9722270369529724 -0.1553668081760406 -0.2176001071929932 3 | -0.08637809008359909 0.1723578721284866 0.9812397956848145 -0.05287289619445801 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/SamplingSurfaceNormalDataPointsFilter1.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - RandomSamplingDataPointsFilter: 3 | prob: 0.5 4 | 5 | referenceDataPointsFilters: 6 | - SamplingSurfaceNormalDataPointsFilter: 7 | knn: 10 8 | ratio: 0.7 9 | samplingMethod: 0 10 | 11 | matcher: 12 | KDTreeMatcher: 13 | knn: 1 14 | epsilon: 0 15 | 16 | outlierFilters: 17 | - TrimmedDistOutlierFilter: 18 | ratio: 0.75 19 | 20 | errorMinimizer: 21 | PointToPlaneErrorMinimizer 22 | 23 | transformationCheckers: 24 | - CounterTransformationChecker: 25 | maxIterationCount: 40 26 | - DifferentialTransformationChecker: 27 | minDiffRotErr: 0.001 28 | minDiffTransErr: 0.01 29 | smoothLength: 4 30 | 31 | inspector: 32 | NullInspector 33 | # VTKFileInspector 34 | 35 | logger: 36 | NullLogger 37 | # FileLogger 38 | 39 | -------------------------------------------------------------------------------- /examples/data/icp_data/SamplingSurfaceNormalDataPointsFilter2.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9800660610198975 -0.160915344953537 0.1165167614817619 -0.1030929088592529 2 | 0.1780297160148621 0.9716479778289795 -0.1555817723274231 -0.2162790298461914 3 | -0.08817778527736664 0.1732239276170731 0.9809271693229675 -0.05410361289978027 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/SamplingSurfaceNormalDataPointsFilter2.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - RandomSamplingDataPointsFilter: 3 | prob: 0.5 4 | 5 | referenceDataPointsFilters: 6 | - SamplingSurfaceNormalDataPointsFilter: 7 | knn: 10 8 | ratio: 0.666666 9 | samplingMethod: 1 10 | averageExistingDescriptors: 0 11 | 12 | matcher: 13 | KDTreeMatcher: 14 | knn: 1 15 | epsilon: 0 16 | 17 | outlierFilters: 18 | - TrimmedDistOutlierFilter: 19 | ratio: 0.75 20 | 21 | errorMinimizer: 22 | PointToPlaneErrorMinimizer 23 | 24 | transformationCheckers: 25 | - CounterTransformationChecker: 26 | maxIterationCount: 40 27 | - DifferentialTransformationChecker: 28 | minDiffRotErr: 0.001 29 | minDiffTransErr: 0.01 30 | smoothLength: 4 31 | 32 | inspector: 33 | NullInspector 34 | # VTKFileInspector 35 | 36 | logger: 37 | NullLogger 38 | # FileLogger 39 | 40 | -------------------------------------------------------------------------------- /examples/data/icp_data/SamplingSurfaceNormalDataPointsFilter3.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9799573421478271 -0.1613964289426804 0.1167683973908424 -0.1059442758560181 2 | 0.1786032468080521 0.9714489579200745 -0.1561653017997742 -0.2180365920066833 3 | -0.08822999894618988 0.1738905906677246 0.9808042645454407 -0.0513763427734375 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/SamplingSurfaceNormalDataPointsFilter3.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - RandomSamplingDataPointsFilter: 3 | prob: 0.5 4 | 5 | referenceDataPointsFilters: 6 | - SamplingSurfaceNormalDataPointsFilter: 7 | knn: 10 8 | ratio: 0.666666 9 | samplingMethod: 1 10 | averageExistingDescriptors: 1 11 | 12 | matcher: 13 | KDTreeMatcher: 14 | knn: 1 15 | epsilon: 0 16 | 17 | outlierFilters: 18 | - TrimmedDistOutlierFilter: 19 | ratio: 0.75 20 | 21 | errorMinimizer: 22 | PointToPlaneErrorMinimizer 23 | 24 | transformationCheckers: 25 | - CounterTransformationChecker: 26 | maxIterationCount: 40 27 | - DifferentialTransformationChecker: 28 | minDiffRotErr: 0.001 29 | minDiffTransErr: 0.01 30 | smoothLength: 4 31 | 32 | inspector: 33 | NullInspector 34 | # VTKFileInspector 35 | 36 | logger: 37 | NullLogger 38 | # FileLogger 39 | 40 | -------------------------------------------------------------------------------- /examples/data/icp_data/defaultBoundingBoxDataPointsFilter.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9801148772239685 -0.1606823354959488 0.1164287924766541 -0.1039974689483643 2 | 0.1777812242507935 0.9716974496841431 -0.1555580049753189 -0.216127872467041 3 | -0.08813809603452682 0.173163577914238 0.9809413552284241 -0.05247235298156738 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/defaultBoundingBoxDataPointsFilter.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - BoundingBoxDataPointsFilter: 3 | xMin: 0.2 4 | 5 | referenceDataPointsFilters: 6 | - SamplingSurfaceNormalDataPointsFilter: 7 | knn: 10 8 | ratio: 0.666666 9 | samplingMethod: 1 10 | averageExistingDescriptors: 0 11 | 12 | matcher: 13 | KDTreeMatcher: 14 | knn: 1 15 | epsilon: 0 16 | 17 | outlierFilters: 18 | - TrimmedDistOutlierFilter: 19 | ratio: 0.75 20 | 21 | errorMinimizer: 22 | PointToPlaneErrorMinimizer 23 | 24 | transformationCheckers: 25 | - CounterTransformationChecker: 26 | maxIterationCount: 40 27 | - DifferentialTransformationChecker: 28 | minDiffRotErr: 0.001 29 | minDiffTransErr: 0.01 30 | smoothLength: 4 31 | 32 | inspector: 33 | NullInspector 34 | # VTKFileInspector 35 | 36 | logger: 37 | NullLogger 38 | # FileLogger 39 | 40 | -------------------------------------------------------------------------------- /examples/data/icp_data/defaultDistanceLimitDataPointsFilter.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9801148772239685 -0.1606823354959488 0.1164287924766541 -0.1039974689483643 2 | 0.1777812242507935 0.9716974496841431 -0.1555580049753189 -0.216127872467041 3 | -0.08813809603452682 0.173163577914238 0.9809413552284241 -0.05247235298156738 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/defaultDistanceLimitDataPointsFilter.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - DistanceLimitDataPointsFilter: 3 | dist: 200 4 | removeInside: 0 5 | 6 | referenceDataPointsFilters: 7 | - SamplingSurfaceNormalDataPointsFilter: 8 | knn: 10 9 | ratio: 0.666666 10 | samplingMethod: 1 11 | averageExistingDescriptors: 0 12 | 13 | matcher: 14 | KDTreeMatcher: 15 | knn: 1 16 | epsilon: 0 17 | 18 | outlierFilters: 19 | - TrimmedDistOutlierFilter: 20 | ratio: 0.75 21 | 22 | errorMinimizer: 23 | PointToPlaneErrorMinimizer 24 | 25 | transformationCheckers: 26 | - CounterTransformationChecker: 27 | maxIterationCount: 40 28 | - DifferentialTransformationChecker: 29 | minDiffRotErr: 0.001 30 | minDiffTransErr: 0.01 31 | smoothLength: 4 32 | 33 | inspector: 34 | NullInspector 35 | # VTKFileInspector 36 | 37 | logger: 38 | NullLogger 39 | # FileLogger 40 | 41 | -------------------------------------------------------------------------------- /examples/data/icp_data/defaultFixStepSamplingDataPointsFilter.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9797301888465881 -0.1610165983438492 0.1191739067435265 -0.1010794639587402 2 | 0.1785348951816559 0.9716610908508301 -0.1549203097820282 -0.2270656824111938 3 | -0.09085189551115036 0.1730567514896393 0.9807124137878418 -0.0547327995300293 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/defaultFixStepSamplingDataPointsFilter.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - FixStepSamplingDataPointsFilter: 3 | startStep: 10 4 | endStep: 10 5 | stepMult: 1 6 | 7 | referenceDataPointsFilters: 8 | - SamplingSurfaceNormalDataPointsFilter: 9 | knn: 10 10 | ratio: 0.666666 11 | samplingMethod: 1 12 | averageExistingDescriptors: 0 13 | 14 | matcher: 15 | KDTreeMatcher: 16 | knn: 1 17 | epsilon: 0 18 | 19 | outlierFilters: 20 | - TrimmedDistOutlierFilter: 21 | ratio: 0.75 22 | 23 | errorMinimizer: 24 | PointToPlaneErrorMinimizer 25 | 26 | transformationCheckers: 27 | - CounterTransformationChecker: 28 | maxIterationCount: 40 29 | - DifferentialTransformationChecker: 30 | minDiffRotErr: 0.001 31 | minDiffTransErr: 0.01 32 | smoothLength: 4 33 | 34 | inspector: 35 | NullInspector 36 | # VTKFileInspector 37 | 38 | logger: 39 | NullLogger 40 | # FileLogger 41 | 42 | -------------------------------------------------------------------------------- /examples/data/icp_data/defaultIdentityDataPointsFilter.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9801148772239685 -0.1606823354959488 0.1164287924766541 -0.1039974689483643 2 | 0.1777812242507935 0.9716974496841431 -0.1555580049753189 -0.216127872467041 3 | -0.08813809603452682 0.173163577914238 0.9809413552284241 -0.05247235298156738 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/defaultIdentityDataPointsFilter.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - IdentityDataPointsFilter: 3 | 4 | referenceDataPointsFilters: 5 | - SamplingSurfaceNormalDataPointsFilter: 6 | knn: 10 7 | ratio: 0.666666 8 | samplingMethod: 1 9 | averageExistingDescriptors: 0 10 | 11 | matcher: 12 | KDTreeMatcher: 13 | knn: 1 14 | epsilon: 0 15 | 16 | outlierFilters: 17 | - TrimmedDistOutlierFilter: 18 | ratio: 0.75 19 | 20 | errorMinimizer: 21 | PointToPlaneErrorMinimizer 22 | 23 | transformationCheckers: 24 | - CounterTransformationChecker: 25 | maxIterationCount: 40 26 | - DifferentialTransformationChecker: 27 | minDiffRotErr: 0.001 28 | minDiffTransErr: 0.01 29 | smoothLength: 4 30 | 31 | inspector: 32 | NullInspector 33 | # VTKFileInspector 34 | 35 | logger: 36 | NullLogger 37 | # FileLogger 38 | 39 | -------------------------------------------------------------------------------- /examples/data/icp_data/defaultMaxDensityDataPointsFilter.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9797302484512329 -0.1622524261474609 0.1174839362502098 -0.1621661186218262 2 | 0.1795323640108109 0.971358060836792 -0.1556648015975952 -0.1850830912590027 3 | -0.08886195719242096 0.1736017018556595 0.9807986617088318 -0.1617109775543213 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/defaultMaxDensityDataPointsFilter.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - SurfaceNormalDataPointsFilter: 3 | knn: 10 4 | keepDensities: 1 5 | 6 | - MaxDensityDataPointsFilter: 7 | maxDensity: 0.3 8 | 9 | referenceDataPointsFilters: 10 | - SurfaceNormalDataPointsFilter: 11 | knn: 10 12 | 13 | matcher: 14 | KDTreeMatcher: 15 | knn: 1 16 | epsilon: 0 17 | 18 | outlierFilters: 19 | - TrimmedDistOutlierFilter: 20 | ratio: 0.75 21 | 22 | errorMinimizer: 23 | PointToPlaneErrorMinimizer 24 | 25 | transformationCheckers: 26 | - CounterTransformationChecker: 27 | maxIterationCount: 40 28 | - DifferentialTransformationChecker: 29 | minDiffRotErr: 0.001 30 | minDiffTransErr: 0.01 31 | smoothLength: 4 32 | 33 | inspector: 34 | NullInspector 35 | # VTKFileInspector 36 | 37 | logger: 38 | NullLogger 39 | # FileLogger 40 | 41 | -------------------------------------------------------------------------------- /examples/data/icp_data/defaultMaxDistDataPointsFilter.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9801148772239685 -0.1606823354959488 0.1164287924766541 -0.1039974689483643 2 | 0.1777812242507935 0.9716974496841431 -0.1555580049753189 -0.216127872467041 3 | -0.08813809603452682 0.173163577914238 0.9809413552284241 -0.05247235298156738 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/defaultMaxDistDataPointsFilter.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - MaxDistDataPointsFilter: 3 | maxDist: 200 4 | 5 | referenceDataPointsFilters: 6 | - SamplingSurfaceNormalDataPointsFilter: 7 | knn: 10 8 | ratio: 0.666666 9 | samplingMethod: 1 10 | averageExistingDescriptors: 0 11 | 12 | matcher: 13 | KDTreeMatcher: 14 | knn: 1 15 | epsilon: 0 16 | 17 | outlierFilters: 18 | - TrimmedDistOutlierFilter: 19 | ratio: 0.75 20 | 21 | errorMinimizer: 22 | PointToPlaneErrorMinimizer 23 | 24 | transformationCheckers: 25 | - CounterTransformationChecker: 26 | maxIterationCount: 40 27 | - DifferentialTransformationChecker: 28 | minDiffRotErr: 0.001 29 | minDiffTransErr: 0.01 30 | smoothLength: 4 31 | 32 | inspector: 33 | NullInspector 34 | # VTKFileInspector 35 | 36 | logger: 37 | NullLogger 38 | # FileLogger 39 | 40 | -------------------------------------------------------------------------------- /examples/data/icp_data/defaultMaxPointCountDataPointsFilter.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9801519513130188 -0.1603859663009644 0.1165294796228409 -0.1041241884231567 2 | 0.1775060296058655 0.9717456102371216 -0.1555691659450531 -0.2163921594619751 3 | -0.0882859081029892 0.1731660962104797 0.980927586555481 -0.05197405815124512 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/defaultMaxPointCountDataPointsFilter.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - MaxPointCountDataPointsFilter: 3 | maxCount: 500 4 | 5 | referenceDataPointsFilters: 6 | - SamplingSurfaceNormalDataPointsFilter: 7 | knn: 10 8 | ratio: 0.666666 9 | samplingMethod: 1 10 | averageExistingDescriptors: 0 11 | 12 | matcher: 13 | KDTreeMatcher: 14 | knn: 1 15 | epsilon: 0 16 | 17 | outlierFilters: 18 | - TrimmedDistOutlierFilter: 19 | ratio: 0.75 20 | 21 | errorMinimizer: 22 | PointToPlaneErrorMinimizer 23 | 24 | transformationCheckers: 25 | - CounterTransformationChecker: 26 | maxIterationCount: 40 27 | - DifferentialTransformationChecker: 28 | minDiffRotErr: 0.001 29 | minDiffTransErr: 0.01 30 | smoothLength: 4 31 | 32 | inspector: 33 | NullInspector 34 | # VTKFileInspector 35 | 36 | logger: 37 | NullLogger 38 | # FileLogger 39 | 40 | -------------------------------------------------------------------------------- /examples/data/icp_data/defaultMaxQuantileOnAxisDataPointsFilter.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9807453155517578 -0.1591110229492188 0.1132368147373199 -0.07697427272796631 2 | 0.1757358014583588 0.971940815448761 -0.1563583761453629 -0.2175577878952026 3 | -0.08518113195896149 0.1732474863529205 0.9811879396438599 -0.04933023452758789 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/defaultMaxQuantileOnAxisDataPointsFilter.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - MaxQuantileOnAxisDataPointsFilter: 3 | ratio: 0.72 4 | 5 | referenceDataPointsFilters: 6 | - SamplingSurfaceNormalDataPointsFilter: 7 | knn: 10 8 | ratio: 0.666666 9 | samplingMethod: 1 10 | averageExistingDescriptors: 0 11 | 12 | matcher: 13 | KDTreeMatcher: 14 | knn: 1 15 | epsilon: 0 16 | 17 | outlierFilters: 18 | - TrimmedDistOutlierFilter: 19 | ratio: 0.75 20 | 21 | errorMinimizer: 22 | PointToPlaneErrorMinimizer 23 | 24 | transformationCheckers: 25 | - CounterTransformationChecker: 26 | maxIterationCount: 40 27 | - DifferentialTransformationChecker: 28 | minDiffRotErr: 0.001 29 | minDiffTransErr: 0.01 30 | smoothLength: 4 31 | 32 | inspector: 33 | NullInspector 34 | # VTKFileInspector 35 | 36 | logger: 37 | NullLogger 38 | # FileLogger 39 | 40 | -------------------------------------------------------------------------------- /examples/data/icp_data/defaultObservationDirectionDataPointsFilter.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9808356165885925 -0.1581308841705322 0.1138257682323456 -0.08235859870910645 2 | 0.1748028993606567 0.9722275137901306 -0.1556223481893539 -0.2180026173591614 3 | -0.08605584502220154 0.1725370734930038 0.9812365770339966 -0.0498192310333252 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/defaultObservationDirectionDataPointsFilter.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - SurfaceNormalDataPointsFilter: 3 | knn: 10 4 | 5 | - ObservationDirectionDataPointsFilter: 6 | x: 1 7 | y: 2 8 | z: 3 9 | 10 | referenceDataPointsFilters: 11 | - SurfaceNormalDataPointsFilter: 12 | knn: 10 13 | 14 | matcher: 15 | KDTreeMatcher: 16 | knn: 1 17 | epsilon: 0 18 | 19 | outlierFilters: 20 | - TrimmedDistOutlierFilter: 21 | ratio: 0.75 22 | 23 | errorMinimizer: 24 | PointToPlaneErrorMinimizer 25 | 26 | transformationCheckers: 27 | - CounterTransformationChecker: 28 | maxIterationCount: 40 29 | - DifferentialTransformationChecker: 30 | minDiffRotErr: 0.001 31 | minDiffTransErr: 0.01 32 | smoothLength: 4 33 | 34 | inspector: 35 | NullInspector 36 | # VTKFileInspector 37 | 38 | logger: 39 | NullLogger 40 | # FileLogger 41 | 42 | -------------------------------------------------------------------------------- /examples/data/icp_data/defaultOrientNormalsDataPointsFilter.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9808356165885925 -0.1581308841705322 0.1138257682323456 -0.08235859870910645 2 | 0.1748028993606567 0.9722275137901306 -0.1556223481893539 -0.2180026173591614 3 | -0.08605584502220154 0.1725370734930038 0.9812365770339966 -0.0498192310333252 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/defaultOrientNormalsDataPointsFilter.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - SurfaceNormalDataPointsFilter: 3 | knn: 10 4 | 5 | - ObservationDirectionDataPointsFilter: 6 | x: 1 7 | y: 2 8 | z: 3 9 | 10 | - OrientNormalsDataPointsFilter: 11 | towardCenter: 1 12 | 13 | referenceDataPointsFilters: 14 | - SurfaceNormalDataPointsFilter: 15 | knn: 10 16 | 17 | matcher: 18 | KDTreeMatcher: 19 | knn: 1 20 | epsilon: 0 21 | 22 | outlierFilters: 23 | - TrimmedDistOutlierFilter: 24 | ratio: 0.75 25 | 26 | errorMinimizer: 27 | PointToPlaneErrorMinimizer 28 | 29 | transformationCheckers: 30 | - CounterTransformationChecker: 31 | maxIterationCount: 40 32 | - DifferentialTransformationChecker: 33 | minDiffRotErr: 0.001 34 | minDiffTransErr: 0.01 35 | smoothLength: 4 36 | 37 | inspector: 38 | NullInspector 39 | # VTKFileInspector 40 | 41 | logger: 42 | NullLogger 43 | # FileLogger 44 | 45 | -------------------------------------------------------------------------------- /examples/data/icp_data/defaultPointToPlaneMinDistDataPointsFilter.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9801148772239685 -0.1606823354959488 0.1164287924766541 -0.1039974689483643 2 | 0.1777812242507935 0.9716974496841431 -0.1555580049753189 -0.216127872467041 3 | -0.08813809603452682 0.173163577914238 0.9809413552284241 -0.05247235298156738 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/defaultPointToPlaneMinDistDataPointsFilter.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - MinDistDataPointsFilter: 3 | minDist: 1 4 | 5 | referenceDataPointsFilters: 6 | - SamplingSurfaceNormalDataPointsFilter: 7 | knn: 10 8 | ratio: 0.666666 9 | samplingMethod: 1 10 | averageExistingDescriptors: 0 11 | 12 | matcher: 13 | KDTreeMatcher: 14 | knn: 1 15 | epsilon: 0 16 | 17 | outlierFilters: 18 | - TrimmedDistOutlierFilter: 19 | ratio: 0.75 20 | 21 | errorMinimizer: 22 | PointToPlaneErrorMinimizer 23 | 24 | transformationCheckers: 25 | - CounterTransformationChecker: 26 | maxIterationCount: 40 27 | - DifferentialTransformationChecker: 28 | minDiffRotErr: 0.001 29 | minDiffTransErr: 0.01 30 | smoothLength: 4 31 | 32 | inspector: 33 | NullInspector 34 | # VTKFileInspector 35 | 36 | logger: 37 | NullLogger 38 | # FileLogger 39 | 40 | -------------------------------------------------------------------------------- /examples/data/icp_data/defaultPointToPlaneWithCovErrorMinimizer.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9808169603347778 -0.158151313662529 0.1139567270874977 -0.08499085903167725 2 | 0.1748128086328506 0.9722858071327209 -0.155243769288063 -0.21916264295578 3 | -0.08624652028083801 0.172186866402626 0.9812814593315125 -0.05274653434753418 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/defaultPointToPointMinDistDataPointsFilter.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9810525178909302 -0.158873662352562 0.1109369620680809 -0.09044396877288818 2 | 0.1747461557388306 0.9727798104286194 -0.152223140001297 -0.2512578964233398 3 | -0.08373246341943741 0.1687234789133072 0.9821048378944397 -0.06846070289611816 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/defaultPointToPointMinDistDataPointsFilter.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - MinDistDataPointsFilter: 3 | minDist: 1 4 | - RandomSamplingDataPointsFilter: 5 | prob: 0.05 6 | 7 | referenceDataPointsFilters: 8 | - MinDistDataPointsFilter: 9 | minDist: 1.0 10 | - RandomSamplingDataPointsFilter: 11 | prob: 0.05 12 | 13 | matcher: 14 | KDTreeMatcher: 15 | knn: 1 16 | epsilon: 3.16 17 | 18 | outlierFilters: 19 | - TrimmedDistOutlierFilter: 20 | ratio: 0.75 21 | 22 | errorMinimizer: 23 | PointToPointErrorMinimizer 24 | 25 | transformationCheckers: 26 | - CounterTransformationChecker: 27 | maxIterationCount: 150 28 | - DifferentialTransformationChecker: 29 | minDiffRotErr: 0.001 30 | minDiffTransErr: 0.01 31 | smoothLength: 4 32 | 33 | inspector: 34 | NullInspector 35 | # VTKFileInspector 36 | 37 | logger: 38 | NullLogger 39 | # FileLogger 40 | 41 | 42 | -------------------------------------------------------------------------------- /examples/data/icp_data/defaultPointToPointWithCovErrorMinimizer.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9837196469306946 -0.1375317871570587 0.1157093048095703 -0.1278921365737915 2 | 0.1548487842082977 0.9753625988960266 -0.1571529656648636 -0.2221848368644714 3 | -0.09124428033828735 0.1725115478038788 0.9807750582695007 -0.05452704429626465 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/defaultRemoveNaNDataPointsFilter.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9801148772239685 -0.1606823354959488 0.1164287924766541 -0.1039974689483643 2 | 0.1777812242507935 0.9716974496841431 -0.1555580049753189 -0.216127872467041 3 | -0.08813809603452682 0.173163577914238 0.9809413552284241 -0.05247235298156738 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/defaultRemoveNaNDataPointsFilter.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - RemoveNaNDataPointsFilter: 3 | 4 | referenceDataPointsFilters: 5 | - SamplingSurfaceNormalDataPointsFilter: 6 | knn: 10 7 | ratio: 0.666666 8 | samplingMethod: 1 9 | averageExistingDescriptors: 0 10 | 11 | matcher: 12 | KDTreeMatcher: 13 | knn: 1 14 | epsilon: 0 15 | 16 | outlierFilters: 17 | - TrimmedDistOutlierFilter: 18 | ratio: 0.75 19 | 20 | errorMinimizer: 21 | PointToPlaneErrorMinimizer 22 | 23 | transformationCheckers: 24 | - CounterTransformationChecker: 25 | maxIterationCount: 40 26 | - DifferentialTransformationChecker: 27 | minDiffRotErr: 0.001 28 | minDiffTransErr: 0.01 29 | smoothLength: 4 30 | 31 | inspector: 32 | NullInspector 33 | # VTKFileInspector 34 | 35 | logger: 36 | NullLogger 37 | # FileLogger 38 | 39 | -------------------------------------------------------------------------------- /examples/data/icp_data/defaultRobustOutlierFilter.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9790875911712646 -0.1649211347103119 0.1191405802965164 -0.1759523153305054 2 | 0.1822330206632614 0.9712686538696289 -0.153078094124794 -0.2485396265983582 3 | -0.09047131240367889 0.171587347984314 0.9810070991516113 -0.06492233276367188 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/defaultRobustOutlierFilter.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | 3 | referenceDataPointsFilters: 4 | 5 | matcher: 6 | KDTreeMatcher: 7 | knn: 10 8 | epsilon: 0 9 | 10 | outlierFilters: 11 | - RobustOutlierFilter: 12 | robustFct: cauchy 13 | scaleEstimator: mad 14 | tuning: 1 15 | 16 | errorMinimizer: 17 | PointToPointErrorMinimizer 18 | 19 | transformationCheckers: 20 | - CounterTransformationChecker: 21 | maxIterationCount: 40 22 | - DifferentialTransformationChecker: 23 | minDiffRotErr: 0.001 24 | minDiffTransErr: 0.01 25 | smoothLength: 4 26 | 27 | inspector: 28 | NullInspector 29 | # VTKFileInspector: 30 | # dumpDataLinks: 1 31 | # dumpReading: 1 32 | # dumpReference: 1 33 | 34 | logger: 35 | NullLogger 36 | # FileLogger 37 | 38 | -------------------------------------------------------------------------------- /examples/data/icp_data/defaultShadowDataPointsFilter.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9808356165885925 -0.1581308841705322 0.1138257682323456 -0.08235859870910645 2 | 0.1748028993606567 0.9722275137901306 -0.1556223481893539 -0.2180026173591614 3 | -0.08605584502220154 0.1725370734930038 0.9812365770339966 -0.0498192310333252 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/defaultShadowDataPointsFilter.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - SurfaceNormalDataPointsFilter: 3 | knn: 10 4 | 5 | - ShadowDataPointsFilter: 6 | eps: 0.00001 7 | 8 | referenceDataPointsFilters: 9 | - SurfaceNormalDataPointsFilter: 10 | knn: 10 11 | 12 | matcher: 13 | KDTreeMatcher: 14 | knn: 1 15 | epsilon: 0 16 | 17 | outlierFilters: 18 | - TrimmedDistOutlierFilter: 19 | ratio: 0.75 20 | 21 | errorMinimizer: 22 | PointToPlaneErrorMinimizer 23 | 24 | transformationCheckers: 25 | - CounterTransformationChecker: 26 | maxIterationCount: 40 27 | - DifferentialTransformationChecker: 28 | minDiffRotErr: 0.001 29 | minDiffTransErr: 0.01 30 | smoothLength: 4 31 | 32 | inspector: 33 | NullInspector 34 | # VTKFileInspector 35 | 36 | logger: 37 | NullLogger 38 | # FileLogger 39 | 40 | -------------------------------------------------------------------------------- /examples/data/icp_data/defaultSimilarityPointToPointMinDistDataPointsFilter.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9824342131614685 -0.15690678358078 0.1140052080154419 -0.08646523952484131 2 | 0.1735319942235947 0.9740102887153625 -0.1548466235399246 -0.2217669486999512 3 | -0.08662448823451996 0.1716707795858383 0.9827582240104675 -0.05477428436279297 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/defaultSimilarityPointToPointMinDistDataPointsFilter.yaml: -------------------------------------------------------------------------------- 1 | # Test for PointToPointSimilarityErrorMinimizer 2 | readingDataPointsFilters: 3 | - MinDistDataPointsFilter: 4 | minDist: 1.0 5 | - RandomSamplingDataPointsFilter: 6 | prob: 1 7 | 8 | referenceDataPointsFilters: 9 | - MinDistDataPointsFilter: 10 | minDist: 1.0 11 | - RandomSamplingDataPointsFilter: 12 | prob: 1 13 | 14 | matcher: 15 | KDTreeMatcher: 16 | knn: 1 17 | epsilon: 3.16 18 | 19 | outlierFilters: 20 | - TrimmedDistOutlierFilter: 21 | ratio: 0.75 22 | 23 | errorMinimizer: 24 | PointToPointSimilarityErrorMinimizer 25 | 26 | transformationCheckers: 27 | - CounterTransformationChecker: 28 | maxIterationCount: 150 29 | - DifferentialTransformationChecker: 30 | minDiffRotErr: 0.001 31 | minDiffTransErr: 0.01 32 | smoothLength: 4 33 | 34 | inspector: 35 | PerformanceInspector 36 | 37 | logger: 38 | # FileLogger 39 | NullLogger 40 | 41 | -------------------------------------------------------------------------------- /examples/data/icp_data/defaultSimpleSensorNoiseDataPointsFilter.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9808356165885925 -0.1581308841705322 0.1138257682323456 -0.08235859870910645 2 | 0.1748028993606567 0.9722275137901306 -0.1556223481893539 -0.2180026173591614 3 | -0.08605584502220154 0.1725370734930038 0.9812365770339966 -0.0498192310333252 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/defaultSimpleSensorNoiseDataPointsFilter.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - SurfaceNormalDataPointsFilter: 3 | knn: 10 4 | 5 | - SimpleSensorNoiseDataPointsFilter: 6 | gain: 2 7 | 8 | referenceDataPointsFilters: 9 | - SurfaceNormalDataPointsFilter: 10 | knn: 10 11 | 12 | matcher: 13 | KDTreeMatcher: 14 | knn: 1 15 | epsilon: 0 16 | 17 | outlierFilters: 18 | - TrimmedDistOutlierFilter: 19 | ratio: 0.75 20 | 21 | errorMinimizer: 22 | PointToPlaneErrorMinimizer 23 | 24 | transformationCheckers: 25 | - CounterTransformationChecker: 26 | maxIterationCount: 40 27 | - DifferentialTransformationChecker: 28 | minDiffRotErr: 0.001 29 | minDiffTransErr: 0.01 30 | smoothLength: 4 31 | 32 | inspector: 33 | NullInspector 34 | # VTKFileInspector 35 | 36 | logger: 37 | NullLogger 38 | # FileLogger 39 | 40 | -------------------------------------------------------------------------------- /examples/data/icp_data/force4DOFForPointToPlaneMinimizer.ref_trans: -------------------------------------------------------------------------------- 1 | 0.9836155772209167 -0.1802777200937271 0 0.2438895702362061 2 | 0.1802777200937271 0.9836155772209167 0 -0.709206759929657 3 | 0 0 1 -0.1967320442199707 4 | 0 0 0 1 -------------------------------------------------------------------------------- /examples/data/icp_data/force4DOFForPointToPlaneMinimizer.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - SurfaceNormalDataPointsFilter: 3 | knn: 12 4 | epsilon: 0.3 5 | keepNormals: 1 6 | keepDensities: 1 7 | 8 | referenceDataPointsFilters: 9 | - SurfaceNormalDataPointsFilter: 10 | knn: 15 11 | 12 | - ObservationDirectionDataPointsFilter 13 | 14 | - OrientNormalsDataPointsFilter: 15 | towardCenter: 1 16 | 17 | 18 | matcher: 19 | KDTreeMatcher: 20 | knn: 10 21 | maxDist: 1.5 22 | epsilon: 1 23 | 24 | outlierFilters: 25 | - TrimmedDistOutlierFilter: 26 | ratio: 0.80 27 | 28 | - SurfaceNormalOutlierFilter: 29 | maxAngle: 0.42 30 | 31 | errorMinimizer: 32 | PointToPlaneErrorMinimizer: 33 | force4DOF: 1 34 | 35 | transformationCheckers: 36 | - DifferentialTransformationChecker: 37 | minDiffRotErr: 0.001 38 | minDiffTransErr: 0.01 39 | smoothLength: 2 40 | - CounterTransformationChecker: 41 | maxIterationCount: 100 42 | - BoundTransformationChecker: 43 | maxRotationNorm: 0.5 44 | maxTranslationNorm: 2 #1 45 | 46 | inspector: 47 | NullInspector 48 | # VTKFileInspector: 49 | 50 | logger: 51 | NullLogger 52 | # FileLogger 53 | 54 | -------------------------------------------------------------------------------- /examples/data/icp_point_to_plane.yaml: -------------------------------------------------------------------------------- 1 | # See https://github.com/anybotics/libpointmatcher/blob/master/doc/ 2 | 3 | readingDataPointsFilters: {} 4 | 5 | referenceDataPointsFilters: {} 6 | 7 | matcher: 8 | MirrorMatcher 9 | 10 | outlierFilters: {} 11 | 12 | errorMinimizer: 13 | PointToPlaneErrorMinimizer 14 | 15 | transformationCheckers: 16 | - DifferentialTransformationChecker: 17 | minDiffRotErr: 0.00001 18 | minDiffTransErr: 0.0001 19 | smoothLength: 3 20 | - CounterTransformationChecker: 21 | maxIterationCount: 30 22 | 23 | inspector: 24 | NullInspector 25 | # VTKFileInspector: 26 | # baseFileName: /debug- 27 | # dumpDataLinks: 1 28 | # dumpReading: 1 29 | # dumpReference: 1 30 | # writeBinary: 1 31 | 32 | logger: 33 | NullLogger 34 | -------------------------------------------------------------------------------- /examples/data/icp_scale.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - RandomSamplingDataPointsFilter: 3 | prob: 0.5 4 | 5 | referenceDataPointsFilters: 6 | - SamplingSurfaceNormalDataPointsFilter: 7 | knn: 10 8 | 9 | matcher: 10 | KDTreeMatcher: 11 | knn: 3 12 | epsilon: 0 13 | 14 | outlierFilters: 15 | - TrimmedDistOutlierFilter: 16 | ratio: 0.95 17 | 18 | errorMinimizer: 19 | PointToPointSimilarityErrorMinimizer 20 | 21 | transformationCheckers: 22 | - CounterTransformationChecker: 23 | maxIterationCount: 80 24 | - DifferentialTransformationChecker: 25 | minDiffRotErr: 0.08 26 | minDiffTransErr: 0.01 27 | smoothLength: 4 28 | 29 | #inspector: 30 | # NullInspector 31 | 32 | inspector: 33 | VTKFileInspector: 34 | baseFileName: pointmatcher-run1 35 | dumpPerfOnExit: 0 36 | dumpStats: 0 37 | dumpIterationInfo: 1 38 | dumpDataLinks: 1 39 | dumpReading: 1 40 | dumpReference: 1 41 | 42 | 43 | logger: 44 | # NullLogger 45 | FileLogger 46 | 47 | -------------------------------------------------------------------------------- /examples/data/unit_tests/badIcpConfig_InvalidModuleType.yaml: -------------------------------------------------------------------------------- 1 | FAKE_MODULE_NAME: 2 | - RandomSamplingDataPointsFilter: 3 | prob: 0.5 4 | 5 | referenceDataPointsFilters: 6 | - SamplingSurfaceNormalDataPointsFilter: 7 | knn: 10 8 | 9 | matcher: 10 | KDTreeMatcher: 11 | knn: 1 12 | epsilon: 0 13 | 14 | outlierFilters: 15 | - TrimmedDistOutlierFilter: 16 | ratio: 0.75 17 | 18 | errorMinimizer: 19 | PointToPlaneErrorMinimizer 20 | 21 | transformationCheckers: 22 | - CounterTransformationChecker: 23 | maxIterationCount: 40 24 | - DifferentialTransformationChecker: 25 | minDiffRotErr: 0.001 26 | minDiffTransErr: 0.01 27 | smoothLength: 4 28 | 29 | inspector: 30 | NullInspector 31 | # VTKFileInspector 32 | 33 | logger: 34 | NullLogger 35 | # FileLogger 36 | 37 | -------------------------------------------------------------------------------- /examples/data/unit_tests/badIcpConfig_InvalidParameter.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - RandomSamplingDataPointsFilter: 3 | FAKE_PARAM: 0.5 4 | prob: 0.5 5 | 6 | referenceDataPointsFilters: 7 | - SamplingSurfaceNormalDataPointsFilter: 8 | knn: 10 9 | 10 | matcher: 11 | KDTreeMatcher: 12 | knn: 1 13 | epsilon: 0 14 | 15 | outlierFilters: 16 | - TrimmedDistOutlierFilter: 17 | ratio: 0.75 18 | 19 | errorMinimizer: 20 | PointToPlaneErrorMinimizer 21 | 22 | transformationCheckers: 23 | - CounterTransformationChecker: 24 | maxIterationCount: 40 25 | - DifferentialTransformationChecker: 26 | minDiffRotErr: 0.001 27 | minDiffTransErr: 0.01 28 | smoothLength: 4 29 | 30 | inspector: 31 | NullInspector 32 | # VTKFileInspector 33 | 34 | logger: 35 | NullLogger 36 | # FileLogger 37 | 38 | -------------------------------------------------------------------------------- /examples/demo_Qt/demo.pro: -------------------------------------------------------------------------------- 1 | # Example of a configuration file for QT Creator 2 | # 3 | # NOTE: you will need to adapt the paths to your own system 4 | 5 | QT += core gui 6 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 7 | TARGET = LAUPointMatcher 8 | TEMPLATE = app 9 | SOURCES += main.cpp 10 | 11 | INCLUDEPATH += /Users/francoispomerleau/Research/Code/libpointmatcher/pointmatcher \ 12 | /Users/francoispomerleau/Research/Code/libnabo/ \ 13 | /usr/local/Cellar/eigen/3.2.4/include/eigen3 \ 14 | /usr/local/include/ 15 | 16 | CONFIG += c++11 17 | #QMAKE_CXXFLAGS += -mmacosx-version-min=10.7 18 | #QMAKE_LFLAGS += -mmacosx-version-min=10.7 19 | 20 | LIBS += /usr/local/lib/libboost_thread-mt.dylib \ 21 | /usr/local/lib/libboost_filesystem-mt.dylib \ 22 | /usr/local/lib/libboost_system-mt.dylib \ 23 | /usr/local/lib/libboost_program_options-mt.dylib \ 24 | /usr/local/lib/libboost_date_time-mt.dylib \ 25 | /usr/local/lib/libboost_chrono-mt.dylib \ 26 | /Users/francoispomerleau/Research/Code/libpointmatcher/build/libpointmatcher.a \ 27 | /Users/francoispomerleau/Research/Code/libnabo/build/libnabo.a \ 28 | -------------------------------------------------------------------------------- /examples/demo_Qt/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "PointMatcher.h" 4 | 5 | class LAUPointMatcherWidget : public QWidget 6 | { 7 | //Q_OBJECT 8 | 9 | public: 10 | //LAUPointMatcherWidget(QWidget *parent = 0) : QWidget(parent) { ; } 11 | //~LAUPointMatcherWidget(); 12 | 13 | private: 14 | PointMatcher::DataPoints::Label label; 15 | }; 16 | 17 | int main(int argc, char *argv[]) 18 | { 19 | QApplication a(argc, argv); 20 | LAUPointMatcherWidget w; 21 | w.show(); 22 | 23 | return a.exec(); 24 | } 25 | 26 | -------------------------------------------------------------------------------- /examples/demo_cmake/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This is demo on how to link libpointmatcher to an 2 | # external project. 3 | 4 | cmake_minimum_required (VERSION 2.8) 5 | project(convert) 6 | 7 | set (CMAKE_CXX_STANDARD 11) 8 | add_compile_options(-std=c++11) 9 | 10 | find_package(libpointmatcher REQUIRED) 11 | 12 | include_directories(${CMAKE_CURRENT_BINARY_DIR} ${libpointmatcher_INCLUDE_DIRS}) 13 | 14 | add_executable(${PROJECT_NAME} convert.cpp) 15 | 16 | target_link_libraries(${PROJECT_NAME} ${libpointmatcher_LIBRARIES}) 17 | -------------------------------------------------------------------------------- /examples/demo_cmake/convert.cpp: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2012, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "pointmatcher/PointMatcher.h" 37 | #include 38 | #include 39 | #include 40 | 41 | using namespace std; 42 | using namespace PointMatcherSupport; 43 | 44 | typedef PointMatcher PM; 45 | typedef PM::DataPoints DP; 46 | 47 | void usage(char *argv[]) 48 | { 49 | cerr << "Usage " << argv[0] << " [CONFIG.yaml] INPUT.csv/.vtk/.ply OUTPUT.csv/.vtk/.ply" << endl; 50 | cerr << endl << "Example:" << endl; 51 | cerr << argv[0] << " ../examples/data/default-convert.yaml ../examples/data/cloud.00000.vtk /tmp/output.vtk" << endl << endl; 52 | cerr << " or " << endl; 53 | cerr << argv[0] << "../examples/data/cloud.00000.vtk /tmp/output.csv" << endl << endl; 54 | 55 | } 56 | 57 | int main(int argc, char *argv[]) 58 | { 59 | if (argc < 3) 60 | { 61 | usage(argv); 62 | return 1; 63 | } 64 | 65 | setLogger(PM::get().LoggerRegistrar.create("FileLogger")); 66 | 67 | DP d(DP::load(argv[argc-2])); 68 | 69 | if (argc == 4) 70 | { 71 | ifstream ifs(argv[1]); 72 | if (!ifs.good()) 73 | { 74 | cerr << "Cannot open config file " << argv[1] << endl; 75 | usage(argv); 76 | return 2; 77 | } 78 | PM::DataPointsFilters f(ifs); 79 | f.apply(d); 80 | 81 | } 82 | 83 | d.save(argv[argc-1]); 84 | 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /examples/demo_cmake/default-convert.yaml: -------------------------------------------------------------------------------- 1 | - BoundingBoxDataPointsFilter: 2 | xMin: -800.0 3 | xMax: 800.0 4 | yMin: -800.0 5 | yMax: 800.0 6 | zMin: -800.0 7 | zMax: 800.0 8 | removeInside: 0 9 | -------------------------------------------------------------------------------- /examples/filterProfiler.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * filterProfiler.cpp 3 | * 4 | * Created on: Feb 27, 2014 5 | * Author: sam 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | using namespace PointMatcherSupport; 15 | using namespace std; 16 | using namespace boost; 17 | 18 | typedef PointMatcher PM; 19 | typedef PM::DataPoints DP; 20 | typedef PM::Parameters Parameters; 21 | 22 | int main(int argc, char *argv[]) 23 | { 24 | 25 | if (argc < 2 || argc > 3) 26 | { 27 | std::cerr << "USAGE: filterProfiler " << std::endl; 28 | return -1; 29 | } 30 | 31 | char* useCentroid; 32 | if (argc == 3) { 33 | if (strcmp(argv[2],"1") != 0 && strcmp(argv[2],"0")) { 34 | cerr << "param useCentroid must be 1 or 0" << endl; 35 | return -1; 36 | } else 37 | { 38 | useCentroid = argv[2]; 39 | } 40 | } else { 41 | useCentroid = "1"; 42 | } 43 | 44 | //setLogger(PM::get().LoggerRegistrar.create("FileLogger")); 45 | 46 | DP in(DP::load(argv[1])); 47 | 48 | std::shared_ptr randomSample = 49 | PM::get().DataPointsFilterRegistrar.create( 50 | "RandomSamplingDataPointsFilter", 51 | {{"prob", toParam(0.5)}} 52 | ); 53 | 54 | cout << "starting random sample filter" << endl; 55 | clock_t time_a = clock(); 56 | randomSample->inPlaceFilter(in); 57 | clock_t time_b = clock(); 58 | 59 | if (time_a == ((clock_t)-1) || time_b == ((clock_t)-1)) 60 | { 61 | perror("Unable to calculate elapsed time"); 62 | return -1; 63 | } 64 | else 65 | { 66 | cout << "Performed random sampling in " << (float)(time_b - time_a)/CLOCKS_PER_SEC << " seconds" << endl; 67 | } 68 | 69 | std::shared_ptr voxelf = 70 | PM::get().DataPointsFilterRegistrar.create( 71 | "VoxelGridDataPointsFilter", 72 | { 73 | {"vSizeX", "0.2"}, 74 | {"vSizeY", "0.2"}, 75 | {"vSizeZ", "0.2"}, 76 | {"useCentroid",useCentroid}, 77 | {"averageExistingDescriptors","0"} 78 | } 79 | ); 80 | 81 | cout << "starting voxel grid sample filter, useCentroid: " << useCentroid << endl; 82 | time_a = clock(); 83 | voxelf->inPlaceFilter(in); 84 | time_b = clock(); 85 | 86 | if (time_a == ((clock_t)-1) || time_b == ((clock_t)-1)) 87 | { 88 | perror("Unable to calculate elapsed time"); 89 | return -1; 90 | } 91 | else 92 | { 93 | cout << "Performed voxel grid sampling in " << (float)(time_b - time_a)/CLOCKS_PER_SEC << " seconds" << endl; 94 | } 95 | 96 | return 0; 97 | } 98 | 99 | 100 | -------------------------------------------------------------------------------- /examples/icp_tutorial/icp_tutorial_cfg.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - RandomSamplingDataPointsFilter: 3 | prob: 0.5 4 | 5 | referenceDataPointsFilters: 6 | - SamplingSurfaceNormalDataPointsFilter: 7 | knn: 10 8 | 9 | matcher: 10 | KDTreeMatcher: 11 | knn: 1 12 | 13 | outlierFilters: 14 | - TrimmedDistOutlierFilter: 15 | ratio: 0.95 16 | 17 | errorMinimizer: 18 | PointToPlaneErrorMinimizer 19 | 20 | transformationCheckers: 21 | - CounterTransformationChecker: 22 | maxIterationCount: 40 23 | - DifferentialTransformationChecker: 24 | minDiffRotErr: 0.001 25 | minDiffTransErr: 0.01 26 | smoothLength: 4 27 | 28 | inspector: 29 | VTKFileInspector: 30 | baseFileName : vissteps 31 | dumpDataLinks : 1 32 | dumpReading : 1 33 | dumpReference : 1 34 | 35 | logger: 36 | FileLogger 37 | -------------------------------------------------------------------------------- /examples/icp_tutorial/icp_tutorial_empty.yaml: -------------------------------------------------------------------------------- 1 | readingDataPointsFilters: 2 | - IdentityDataPointsFilter 3 | 4 | referenceDataPointsFilters: 5 | - IdentityDataPointsFilter 6 | 7 | matcher: 8 | KDTreeMatcher 9 | 10 | outlierFilters: 11 | - NullOutlierFilter 12 | 13 | errorMinimizer: 14 | IdentityErrorMinimizer 15 | 16 | transformationCheckers: 17 | - CounterTransformationChecker 18 | 19 | inspector: 20 | NullInspector 21 | 22 | logger: 23 | FileLogger 24 | -------------------------------------------------------------------------------- /libpointmatcherConfig.cmake.in: -------------------------------------------------------------------------------- 1 | # - Config file for the libpointmatcher package 2 | # It defines the following variables 3 | # libpointmatcher_INCLUDE_DIRS - include directories for pointmatcher 4 | # libpointmatcher_LIBRARIES - libraries to link against 5 | 6 | # Compute paths 7 | get_filename_component(POINTMATCHER_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) 8 | set(libpointmatcher_INCLUDE_DIRS "@CONF_INCLUDE_DIRS@") 9 | set(LIBPOINTMATCHER_INCLUDE_DIRS "@CONF_INCLUDE_DIRS@") 10 | set(pointmatcher_INCLUDE_DIRS "@CONF_INCLUDE_DIRS@") 11 | set(POINTMATCHER_INCLUDE_DIRS "@CONF_INCLUDE_DIRS@") 12 | 13 | set(libpointmatcher_LIBRARIES "@POINTMATCHER_LIB@;@EXTERNAL_LIBS@") 14 | set(LIBPOINTMATCHER_LIBRARIES "@POINTMATCHER_LIB@;@EXTERNAL_LIBS@") 15 | set(pointmatcher_LIBRARIES "@POINTMATCHER_LIB@;@EXTERNAL_LIBS@") 16 | set(POINTMATCHER_LIBRARIES "@POINTMATCHER_LIB@;@EXTERNAL_LIBS@") 17 | 18 | # This causes catkin simple to link against these libraries 19 | set(libpointmatcher_FOUND_CATKIN_PROJECT true) 20 | set(LIBPOINTMATCHER_FOUND_CATKIN_PROJECT true) 21 | set(pointmatcher_FOUND_CATKIN_PROJECT true) 22 | set(POINTMATCHER_FOUND_CATKIN_PROJECT true) 23 | -------------------------------------------------------------------------------- /libpointmatcherConfigVersion.cmake.in: -------------------------------------------------------------------------------- 1 | set(PACKAGE_VERSION "@PROJECT_VERSION@") 2 | 3 | # Check whether the requested PACKAGE_FIND_VERSION is compatible 4 | if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}") 5 | set(PACKAGE_VERSION_COMPATIBLE FALSE) 6 | else() 7 | set(PACKAGE_VERSION_COMPATIBLE TRUE) 8 | if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}") 9 | set(PACKAGE_VERSION_EXACT TRUE) 10 | endif() 11 | endif() 12 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: libpointmatcher 2 | repo_url: https://github.com/anybotics/libpointmatcher 3 | site_description: An "Iterative Closest Point" library for 2-D/3-D mapping in robotic 4 | google_analytics: ['UA-70950258-1', 'libpointmatcher.readthedocs.org'] 5 | pages: 6 | - Home: 'index.md' 7 | - Introduction: 8 | - 'What is libpointmatcher about?': 'Introduction.md' 9 | - 'What can I do with libpointmatcher': 'ApplicationsAndPub.md' 10 | - 'What the different data filters do?': 'Datafilters.md' 11 | - 'Example: applying a chain of data filters': 'ApplyingDatafilters.md' 12 | - 'Example: An introduction to ICP': 'ICPIntro.md' 13 | - 'The ICP chain configuration and its variants': 'DefaultICPConfig.md' 14 | - 'Configuring libpointmatcher using YAML': 'Configuration.md' 15 | - 'Supported file types and importing/exporting point clouds': 'ImportExport.md' 16 | - Compilation: 17 | - 'Ubuntu': 'Compilation.md' 18 | - 'Windows': 'CompilationWindows.md' 19 | - 'Mac OS X': 'CompilationMac.md' 20 | - Advanced: 21 | - 'How to link a project to libpointmatcher': 'LinkingProjects.md' 22 | - 'How are point clouds represented?': 'Pointclouds.md' 23 | - 'Example: Writing a program which performs ICP': 'BasicRegistration.md' 24 | - 'How to move a point cloud using a rigid transformation?': 'Transformations.md' 25 | - Developer: 26 | - 'Creating a DataPointsFilter': 'DataPointsFilterDev.md' 27 | - 'Creating a Transformation': 'TransformationDev.md' 28 | - 'Creating unit tests': 'UnitTestDev.md' 29 | -------------------------------------------------------------------------------- /package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | libpointmatcher 4 | 1.3.25 5 | libpointmatcher is a modular ICP library, useful for robotics and computer vision. 6 | Francois Pomerleau 7 | Yoshua Nava 8 | Maximilian Wulf 9 | BSD 10 | https://github.com/anybotics/libpointmatcher 11 | catkin 12 | ament_cmake 13 | 14 | boost 15 | libnabo 16 | eigen 17 | yaml-cpp 18 | boost 19 | libnabo 20 | eigen 21 | yaml-cpp 22 | 23 | gtest 24 | ament_cmake_gtest 25 | 26 | ament_cmake 27 | 28 | 29 | -------------------------------------------------------------------------------- /pointmatcher.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | exec_prefix=@CMAKE_INSTALL_PREFIX@ 3 | libdir=${prefix}/lib 4 | includedir=${prefix}/include 5 | 6 | Name: @CMAKE_PROJECT_NAME@ 7 | Description: See https://github.com/anybotics/libpointmatcher 8 | Version: @PROJECT_VERSION@ 9 | Libs: -L${libdir} @LIBRARY_CC_ARGS@ 10 | Cflags: -I${includedir}/ 11 | 12 | -------------------------------------------------------------------------------- /pointmatcher/Bibliography.h: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2012, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #ifndef __POINTMATCHER_BIBLIOGRAPHY_H 37 | #define __POINTMATCHER_BIBLIOGRAPHY_H 38 | 39 | #include 40 | #include 41 | #include 42 | 43 | namespace PointMatcherSupport 44 | { 45 | typedef std::vector StringVector; 46 | typedef std::map StringMap; 47 | typedef std::map StringMapMap; 48 | typedef StringMapMap Bibliography; 49 | typedef std::map BibIndices; 50 | 51 | struct CurrentBibliography 52 | { 53 | enum Mode 54 | { 55 | NORMAL=0, 56 | ROSWIKI=1, 57 | BIBTEX=2 58 | } mode; 59 | BibIndices indices; 60 | StringVector entries; 61 | 62 | CurrentBibliography(Mode mode = NORMAL); 63 | void dump(std::ostream& os) const; 64 | 65 | private: 66 | void dumpText(std::ostream& os) const; 67 | void dumpWiki(std::ostream& os) const; 68 | void dumpBibtex(std::ostream& os) const; 69 | }; 70 | 71 | std::string getAndReplaceBibEntries(const std::string&, CurrentBibliography& curBib); 72 | 73 | } // PointMatcherSupport 74 | 75 | #endif // __POINTMATCHER_BIBLIOGRAPHY_H 76 | 77 | -------------------------------------------------------------------------------- /pointmatcher/DataPointsFilters/HiddenPointRemoval.cpp: -------------------------------------------------------------------------------- 1 | #include "HiddenPointRemoval.h" 2 | 3 | 4 | // HiddenPointRemovalDataPointsFilter 5 | template 6 | HiddenPointRemovalDataPointsFilter::HiddenPointRemovalDataPointsFilter() : 7 | vPositionX(0), 8 | vPositionY(0), 9 | vPositionZ(0), 10 | radius(100) 11 | { 12 | } 13 | 14 | template 15 | HiddenPointRemovalDataPointsFilter::HiddenPointRemovalDataPointsFilter(const Parameters& params) : 16 | PointMatcher::DataPointsFilter("HiddenPointRemovalDataPointsFilter", 17 | HiddenPointRemovalDataPointsFilter::availableParameters(), params), 18 | vPositionX(Parametrizable::get("vPositionX")), 19 | vPositionY(Parametrizable::get("vPositionY")), 20 | vPositionZ(Parametrizable::get("vPositionZ")), 21 | radius(Parametrizable::get("radius")) 22 | 23 | { 24 | } 25 | 26 | template 27 | typename PointMatcher::DataPoints 28 | HiddenPointRemovalDataPointsFilter::filter(const DataPoints& input) 29 | { 30 | DataPoints output(input); 31 | inPlaceFilter(output); 32 | return output; 33 | } 34 | 35 | template 36 | void HiddenPointRemovalDataPointsFilter::inPlaceFilter(DataPoints& /*cloud*/) 37 | { 38 | } 39 | 40 | template struct HiddenPointRemovalDataPointsFilter; 41 | template struct HiddenPointRemovalDataPointsFilter; 42 | 43 | 44 | -------------------------------------------------------------------------------- /pointmatcher/DataPointsFilters/HiddenPointRemoval.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PointMatcher.h" 4 | 5 | template 6 | struct HiddenPointRemovalDataPointsFilter : public PointMatcher::DataPointsFilter 7 | { 8 | // Type definitions 9 | typedef PointMatcher PM; 10 | typedef typename PM::DataPoints DataPoints; 11 | typedef typename PM::DataPointsFilter DataPointsFilter; 12 | 13 | typedef PointMatcherSupport::Parametrizable Parametrizable; 14 | typedef PointMatcherSupport::Parametrizable P; 15 | typedef Parametrizable::Parameters Parameters; 16 | typedef Parametrizable::ParameterDoc ParameterDoc; 17 | typedef Parametrizable::ParametersDoc ParametersDoc; 18 | typedef Parametrizable::InvalidParameter InvalidParameter; 19 | 20 | typedef typename PointMatcher::Matrix Matrix; 21 | typedef typename PointMatcher::Vector Vector; 22 | typedef typename Eigen::Matrix Vector2; 23 | typedef typename Eigen::Matrix Vector3; 24 | typedef typename PointMatcher::DataPoints::InvalidField InvalidField; 25 | 26 | 27 | inline static const std::string description() 28 | { 29 | return "Remove hidden points from the point cloud based on visibility."; 30 | } 31 | 32 | inline static const ParametersDoc availableParameters() 33 | { 34 | return { 35 | {"vPositionX", "The X component of the position which the point cloud is visualized from. ", "0", "-inf", "inf", &P::Comp}, 36 | {"vPositionY", "The Y component of the position which the point cloud is visualized from. ", "0", "-inf", "inf", &P::Comp}, 37 | {"vPositionZ", "The Z component of the position which the point cloud is visualized from. ", "0", "-inf", "inf", &P::Comp}, 38 | {"radius", "The radius of the spherical projection. ", "100", "0", "inf", P::Comp} 39 | }; 40 | } 41 | 42 | const T vPositionX; 43 | const T vPositionY; 44 | const T vPositionZ; 45 | const T radius; 46 | 47 | //Constructor, uses parameter interface 48 | HiddenPointRemovalDataPointsFilter(const Parameters& params = Parameters()); 49 | 50 | HiddenPointRemovalDataPointsFilter(); 51 | // Destructor 52 | virtual ~HiddenPointRemovalDataPointsFilter() {}; 53 | 54 | virtual DataPoints filter(const DataPoints& input); 55 | virtual void inPlaceFilter(DataPoints& cloud); 56 | }; 57 | -------------------------------------------------------------------------------- /pointmatcher/DataPointsFilters/Identity.cpp: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2018, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | #include "Identity.h" 36 | 37 | // IdentityDataPointsFilter 38 | template 39 | typename PointMatcher::DataPoints IdentityDataPointsFilter::filter( 40 | const DataPoints& input) 41 | { 42 | DataPoints output(input); 43 | inPlaceFilter(output); 44 | return output; 45 | } 46 | 47 | // In-place filter 48 | template 49 | void IdentityDataPointsFilter::inPlaceFilter( 50 | DataPoints& /*cloud*/) 51 | { 52 | } 53 | 54 | template struct IdentityDataPointsFilter; 55 | template struct IdentityDataPointsFilter; 56 | -------------------------------------------------------------------------------- /pointmatcher/DataPointsFilters/Identity.h: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2018, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | #pragma once 36 | 37 | #include "PointMatcher.h" 38 | 39 | //! IdentityDataPointsFilter, does nothing 40 | template< typename T> 41 | struct IdentityDataPointsFilter: public PointMatcher::DataPointsFilter 42 | { 43 | typedef typename PointMatcher::DataPoints DataPoints; 44 | 45 | inline static const std::string description() 46 | { 47 | return "Does nothing."; 48 | } 49 | 50 | IdentityDataPointsFilter() : PointMatcher::DataPointsFilter("IdentityDataPointsFilter", 51 | PointMatcherSupport::Parametrizable::ParametersDoc(), 52 | PointMatcherSupport::Parametrizable::Parameters()) {} 53 | 54 | virtual DataPoints filter(const DataPoints& input); 55 | virtual void inPlaceFilter(DataPoints& cloud); 56 | }; 57 | -------------------------------------------------------------------------------- /pointmatcher/DataPointsFilters/IncidenceAngle.cpp: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2018, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | #include "IncidenceAngle.h" 36 | 37 | // IncidenceAngleDataPointsFilter 38 | // Compute 39 | template 40 | typename PointMatcher::DataPoints 41 | IncidenceAngleDataPointsFilter::filter(const DataPoints& input) 42 | { 43 | DataPoints output(input); 44 | inPlaceFilter(output); 45 | return output; 46 | } 47 | 48 | // In-place filter 49 | template 50 | void IncidenceAngleDataPointsFilter::inPlaceFilter(DataPoints& cloud) 51 | { 52 | 53 | if (!cloud.descriptorExists("normals")) 54 | throw InvalidField("IncidenceAngleDataPointsFilter: Error, cannot find normals in descriptors."); 55 | if (!cloud.descriptorExists("observationDirections")) 56 | throw InvalidField("IncidenceAngleDataPointsFilter: Error, cannot find observation directions in descriptors."); 57 | 58 | cloud.allocateDescriptor("incidenceAngles", 1); 59 | BOOST_AUTO(angles, cloud.getDescriptorViewByName("incidenceAngles")); 60 | 61 | const BOOST_AUTO(normals, cloud.getDescriptorViewByName("normals")); 62 | const BOOST_AUTO(observationDirections, cloud.getDescriptorViewByName("observationDirections")); 63 | assert(normals.rows() == observationDirections.rows()); 64 | 65 | const unsigned int nbPts(cloud.getNbPoints()); 66 | 67 | for (unsigned int i = 0; i < nbPts; ++i) 68 | { 69 | // Check normal orientation 70 | const Vector vecP = observationDirections.col(i).normalized(); 71 | const Vector vecN = normals.col(i);// assumed to be normalized 72 | angles(0,i) = acos(vecP.dot(vecN)); 73 | } 74 | } 75 | 76 | template struct IncidenceAngleDataPointsFilter; 77 | template struct IncidenceAngleDataPointsFilter; 78 | -------------------------------------------------------------------------------- /pointmatcher/DataPointsFilters/IncidenceAngle.h: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2018, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | #pragma once 36 | 37 | #include "PointMatcher.h" 38 | 39 | //! Incidence angle, compute the incidence angle of a surface normal with the observation direction 40 | template 41 | struct IncidenceAngleDataPointsFilter: public PointMatcher::DataPointsFilter 42 | { 43 | typedef typename PointMatcher::Vector Vector; 44 | typedef typename PointMatcher::DataPoints DataPoints; 45 | typedef typename PointMatcher::DataPoints::InvalidField InvalidField; 46 | 47 | inline static const std::string description() 48 | { 49 | return "Compute the incidence angle using the dot product of the viewing direction and the surface normal.\n\n" 50 | "Required descriptors: normals, observationDirections.\n" 51 | "Produced descritors: incidenceAngles.\n" 52 | "Altered descriptors: none.\n" 53 | "Altered features: none."; 54 | } 55 | 56 | 57 | IncidenceAngleDataPointsFilter() : PointMatcher::DataPointsFilter("IncidenceAngleDataPointsFilter", 58 | PointMatcherSupport::Parametrizable::ParametersDoc(), 59 | PointMatcherSupport::Parametrizable::Parameters()) {} 60 | virtual DataPoints filter(const DataPoints& input); 61 | virtual void inPlaceFilter(DataPoints& cloud); 62 | }; 63 | -------------------------------------------------------------------------------- /pointmatcher/DataPointsFilters/MaxDensity.h: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2018, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | #pragma once 36 | 37 | #include "PointMatcher.h" 38 | 39 | //! Subsampling. Reduce the points number by randomly removing points with a dentsity higher than a treshold. 40 | template< typename T> 41 | struct MaxDensityDataPointsFilter: public PointMatcher::DataPointsFilter 42 | { 43 | typedef PointMatcherSupport::Parametrizable Parametrizable; 44 | typedef PointMatcherSupport::Parametrizable P; 45 | typedef Parametrizable::Parameters Parameters; 46 | typedef Parametrizable::ParameterDoc ParameterDoc; 47 | typedef Parametrizable::ParametersDoc ParametersDoc; 48 | typedef Parametrizable::InvalidParameter InvalidParameter; 49 | 50 | typedef typename PointMatcher::DataPoints DataPoints; 51 | typedef typename PointMatcher::DataPoints::InvalidField InvalidField; 52 | 53 | inline static const std::string description() 54 | { 55 | return "Subsampling. Reduce the points number by randomly removing points with a density highler than a treshold."; 56 | } 57 | inline static const ParametersDoc availableParameters() 58 | { 59 | return { 60 | {"maxDensity", "Maximum density of points to target. Unit: number of points per m^3.", "10", "0.0000001", "inf", &P::Comp} 61 | }; 62 | } 63 | 64 | const T maxDensity; 65 | 66 | //! Constructor, uses parameter interface 67 | MaxDensityDataPointsFilter(const Parameters& params = Parameters()); 68 | virtual DataPoints filter(const DataPoints& input); 69 | virtual void inPlaceFilter(DataPoints& cloud); 70 | }; 71 | 72 | -------------------------------------------------------------------------------- /pointmatcher/DataPointsFilters/MaxDist.h: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2018, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | #pragma once 36 | 37 | #include "PointMatcher.h" 38 | 39 | //! Subsampling. Filter points beyond a maximum distance measured on a specific axis 40 | template< typename T> 41 | struct MaxDistDataPointsFilter: public PointMatcher::DataPointsFilter 42 | { 43 | typedef PointMatcherSupport::Parametrizable Parametrizable; 44 | typedef PointMatcherSupport::Parametrizable P; 45 | typedef Parametrizable::Parameters Parameters; 46 | typedef Parametrizable::ParameterDoc ParameterDoc; 47 | typedef Parametrizable::ParametersDoc ParametersDoc; 48 | typedef Parametrizable::InvalidParameter InvalidParameter; 49 | 50 | typedef typename PointMatcher::DataPoints DataPoints; 51 | 52 | inline static const std::string description() 53 | { 54 | return "Subsampling. Filter points beyond a maximum distance measured on a specific axis. If dim is set to -1, points are filtered based on a maximum radius."; 55 | } 56 | inline static const ParametersDoc availableParameters() 57 | { 58 | return { 59 | {"dim", "dimension on which the filter will be applied. x=0, y=1, z=2, radius=-1", "-1", "-1", "2", &P::Comp}, 60 | {"maxDist", "maximum distance authorized. If dim is set to -1 (radius), the absolute value of minDist will be used. All points beyond that will be filtered.", "1", "-inf", "inf", &P::Comp} 61 | }; 62 | } 63 | 64 | const int dim; 65 | const T maxDist; 66 | 67 | //! Constructor, uses parameter interface 68 | MaxDistDataPointsFilter(const Parameters& params = Parameters()); 69 | virtual DataPoints filter(const DataPoints& input); 70 | virtual void inPlaceFilter(DataPoints& cloud); 71 | }; 72 | -------------------------------------------------------------------------------- /pointmatcher/DataPointsFilters/MaxPointCount.h: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2018, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | #pragma once 36 | 37 | #include "PointMatcher.h" 38 | 39 | //! Maximum number of points 40 | template 41 | struct MaxPointCountDataPointsFilter: public PointMatcher::DataPointsFilter 42 | { 43 | typedef PointMatcherSupport::Parametrizable Parametrizable; 44 | typedef PointMatcherSupport::Parametrizable P; 45 | typedef Parametrizable::Parameters Parameters; 46 | typedef Parametrizable::ParameterDoc ParameterDoc; 47 | typedef Parametrizable::ParametersDoc ParametersDoc; 48 | typedef Parametrizable::InvalidParameter InvalidParameter; 49 | 50 | typedef typename PointMatcher::DataPoints DataPoints; 51 | 52 | inline static const std::string description() 53 | { 54 | return "Conditional subsampling. This filter reduces the size of the point cloud by randomly dropping points if their number is above maxCount. Based on \\cite{Masuda1996Random}"; 55 | } 56 | inline static const ParametersDoc availableParameters() 57 | { 58 | return { 59 | {"seed", "srand seed", "1", "0", "2147483647", &P::Comp}, 60 | {"maxCount", "maximum number of points", "1000", "0", "2147483647", &P::Comp} 61 | } 62 | ; 63 | } 64 | 65 | const size_t maxCount; 66 | size_t seed; 67 | 68 | MaxPointCountDataPointsFilter(const Parameters& params = Parameters()); 69 | virtual ~MaxPointCountDataPointsFilter() {}; 70 | virtual DataPoints filter(const DataPoints& input); 71 | virtual void inPlaceFilter(DataPoints& cloud); 72 | }; 73 | -------------------------------------------------------------------------------- /pointmatcher/DataPointsFilters/MaxQuantileOnAxis.h: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2018, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | #pragma once 36 | 37 | #include "PointMatcher.h" 38 | 39 | //! Subsampling. Filter points beyond a maximum quantile measured on a specific axis 40 | template< typename T> 41 | struct MaxQuantileOnAxisDataPointsFilter: public PointMatcher::DataPointsFilter 42 | { 43 | typedef PointMatcherSupport::Parametrizable Parametrizable; 44 | typedef PointMatcherSupport::Parametrizable P; 45 | typedef Parametrizable::Parameters Parameters; 46 | typedef Parametrizable::ParameterDoc ParameterDoc; 47 | typedef Parametrizable::ParametersDoc ParametersDoc; 48 | typedef Parametrizable::InvalidParameter InvalidParameter; 49 | 50 | typedef typename PointMatcher::DataPoints DataPoints; 51 | 52 | inline static const std::string description() 53 | { 54 | return "Subsampling. Filter points beyond a maximum quantile measured on a specific axis."; 55 | } 56 | inline static const ParametersDoc availableParameters() 57 | { 58 | return { 59 | {"dim", "dimension on which the filter will be applied. x=0, y=1, z=2", "0", "0", "2", &P::Comp}, 60 | {"ratio", "maximum quantile authorized. All points beyond that will be filtered.", "0.5", "0.0000001", "0.9999999", &P::Comp} 61 | }; 62 | } 63 | 64 | const unsigned dim; 65 | const T ratio; 66 | 67 | //! Constructor, uses parameter interface 68 | MaxQuantileOnAxisDataPointsFilter(const Parameters& params = Parameters()); 69 | virtual DataPoints filter(const DataPoints& input); 70 | virtual void inPlaceFilter(DataPoints& cloud); 71 | }; 72 | -------------------------------------------------------------------------------- /pointmatcher/DataPointsFilters/MinDist.h: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2018, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | #pragma once 36 | 37 | #include "PointMatcher.h" 38 | 39 | //! Subsampling. Filter points before a minimum distance measured on a specific axis 40 | template< typename T> 41 | struct MinDistDataPointsFilter: public PointMatcher::DataPointsFilter 42 | { 43 | typedef PointMatcherSupport::Parametrizable Parametrizable; 44 | typedef PointMatcherSupport::Parametrizable P; 45 | typedef Parametrizable::Parameters Parameters; 46 | typedef Parametrizable::ParameterDoc ParameterDoc; 47 | typedef Parametrizable::ParametersDoc ParametersDoc; 48 | typedef Parametrizable::InvalidParameter InvalidParameter; 49 | 50 | typedef typename PointMatcher::DataPoints DataPoints; 51 | 52 | inline static const std::string description() 53 | { 54 | return "Subsampling. Filter points before a minimum distance measured on a specific axis. If dim is set to -1, points are filtered based on a minimum radius."; 55 | } 56 | inline static const ParametersDoc availableParameters() 57 | { 58 | return { 59 | {"dim", "dimension on which the filter will be applied. x=0, y=1, z=2, radius=-1", "-1", "-1", "2", &P::Comp}, 60 | {"minDist", "minimum value authorized. If dim is set to -1 (radius), the absolute value of minDist will be used. All points before that will be filtered.", "1", "-inf", "inf", &P::Comp} 61 | }; 62 | } 63 | 64 | const int dim; 65 | const T minDist; 66 | 67 | //! Constructor, uses parameter interface 68 | MinDistDataPointsFilter(const Parameters& params = Parameters()); 69 | virtual DataPoints filter(const DataPoints& input); 70 | virtual void inPlaceFilter(DataPoints& cloud); 71 | }; 72 | -------------------------------------------------------------------------------- /pointmatcher/DataPointsFilters/OrientNormals.h: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2018, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | #pragma once 36 | 37 | #include "PointMatcher.h" 38 | 39 | //! Reorientation of normals 40 | template 41 | struct OrientNormalsDataPointsFilter: public PointMatcher::DataPointsFilter 42 | { 43 | typedef PointMatcherSupport::Parametrizable Parametrizable; 44 | typedef PointMatcherSupport::Parametrizable P; 45 | typedef Parametrizable::Parameters Parameters; 46 | typedef Parametrizable::ParameterDoc ParameterDoc; 47 | typedef Parametrizable::ParametersDoc ParametersDoc; 48 | typedef Parametrizable::InvalidParameter InvalidParameter; 49 | 50 | typedef typename PointMatcher::Vector Vector; 51 | typedef typename PointMatcher::DataPoints DataPoints; 52 | typedef typename PointMatcher::DataPoints::View View; 53 | typedef typename PointMatcher::DataPoints::InvalidField InvalidField; 54 | 55 | inline static const std::string description() 56 | { 57 | return "Normals. Reorient normals so that they all point in the same direction, with respect to the observation points."; 58 | } 59 | 60 | inline static const ParametersDoc availableParameters() 61 | { 62 | return { 63 | {"towardCenter", "If set to true(1), all the normals will point inside the surface (i.e. toward the observation points).", "1", "0", "1", &P::Comp} 64 | }; 65 | } 66 | 67 | OrientNormalsDataPointsFilter(const Parameters& params = Parameters()); 68 | virtual ~OrientNormalsDataPointsFilter() {}; 69 | virtual DataPoints filter(const DataPoints& input); 70 | virtual void inPlaceFilter(DataPoints& cloud); 71 | 72 | const bool towardCenter; 73 | }; 74 | -------------------------------------------------------------------------------- /pointmatcher/DataPointsFilters/RandomSampling.h: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2018, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | #pragma once 36 | 37 | #include "PointMatcher.h" 38 | 39 | #include 40 | 41 | //! Random sampling 42 | template 43 | struct RandomSamplingDataPointsFilter: public PointMatcher::DataPointsFilter 44 | { 45 | typedef PointMatcherSupport::Parametrizable Parametrizable; 46 | typedef PointMatcherSupport::Parametrizable P; 47 | typedef Parametrizable::Parameters Parameters; 48 | typedef Parametrizable::ParameterDoc ParameterDoc; 49 | typedef Parametrizable::ParametersDoc ParametersDoc; 50 | typedef Parametrizable::InvalidParameter InvalidParameter; 51 | typedef PointMatcher PM; 52 | typedef typename PM::DataPoints DataPoints; 53 | 54 | inline static const std::string description() 55 | { 56 | return "Subsampling. This filter reduces the size of the point cloud by randomly dropping points. Based on \\cite{Masuda1996Random}"; 57 | } 58 | inline static const ParametersDoc availableParameters() 59 | { 60 | return { 61 | {"prob", "Probability to keep a point, one over decimation factor ", "0.75", "0", "1", &P::Comp}, 62 | {"randomSamplingMethod", "Random sampling method: Direct RNG (0) (fastest), Uniform (1) (more accurate but slower)", "0", "0", "1", &P::Comp} 63 | }; 64 | } 65 | 66 | const double prob; 67 | const int randomSamplingMethod; 68 | 69 | RandomSamplingDataPointsFilter(const Parameters& params = Parameters()); 70 | virtual ~RandomSamplingDataPointsFilter() {}; 71 | virtual DataPoints filter(const DataPoints& input); 72 | virtual void inPlaceFilter(DataPoints& cloud); 73 | typename PM::Vector sampleRandomIndices(const size_t nbPoints); 74 | }; 75 | -------------------------------------------------------------------------------- /pointmatcher/DataPointsFilters/RemoveNaN.cpp: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2018, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | #include "RemoveNaN.h" 36 | 37 | // RemoveNaNDataPointsFilter 38 | template 39 | typename PointMatcher::DataPoints RemoveNaNDataPointsFilter::filter( 40 | const DataPoints& input) 41 | { 42 | DataPoints output(input); 43 | inPlaceFilter(output); 44 | return output; 45 | } 46 | 47 | // In-place filter 48 | template 49 | void RemoveNaNDataPointsFilter::inPlaceFilter( 50 | DataPoints& cloud) 51 | { 52 | using ArrayBooleans = Eigen::Array; 53 | 54 | const int nbPointsIn = cloud.features.cols(); 55 | 56 | // Given that this filter removes the structure from the linear array of points, there is no purpose for keeping the order of the 57 | // point cloud in the index grid anymore. 58 | if(cloud.isOrganized()) { 59 | cloud.deallocateIndexGrid(); 60 | } 61 | 62 | // Instantiate array of booleans to flag points as valid. 63 | // The following line implements a fast version of isNaN(), suggested by the author of Eigen: https://forum.kde.org/viewtopic.php?f=74&t=91514 64 | const ArrayBooleans isValidPoint{ (cloud.features.array() == cloud.features.array()).colwise().all() }; 65 | 66 | int j = 0; 67 | for (int i = 0; i < nbPointsIn; ++i) 68 | { 69 | if (isValidPoint(i)) 70 | { 71 | cloud.setColFrom(j, cloud, i); 72 | ++j; 73 | } 74 | } 75 | 76 | cloud.conservativeResize(j); 77 | } 78 | 79 | template struct RemoveNaNDataPointsFilter; 80 | template struct RemoveNaNDataPointsFilter; 81 | 82 | -------------------------------------------------------------------------------- /pointmatcher/DataPointsFilters/RemoveNaN.h: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2018, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | #pragma once 36 | 37 | #include "PointMatcher.h" 38 | 39 | //! Remove points having NaN as coordinate 40 | template 41 | struct RemoveNaNDataPointsFilter: public PointMatcher::DataPointsFilter 42 | { 43 | typedef typename PointMatcher::DataPoints DataPoints; 44 | 45 | inline static const std::string description() 46 | { 47 | return "Remove points having NaN as coordinate."; 48 | } 49 | 50 | RemoveNaNDataPointsFilter() : PointMatcher::DataPointsFilter("RemoveNaNDataPointsFilter", 51 | PointMatcherSupport::Parametrizable::ParametersDoc(), 52 | PointMatcherSupport::Parametrizable::Parameters()) {} 53 | virtual DataPoints filter(const DataPoints& input); 54 | virtual void inPlaceFilter(DataPoints& cloud); 55 | }; 56 | -------------------------------------------------------------------------------- /pointmatcher/DataPointsFilters/Shadow.h: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2018, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | #pragma once 36 | 37 | #include "PointMatcher.h" 38 | 39 | //! Shadow filter, remove ghost points appearing on edges 40 | template 41 | struct ShadowDataPointsFilter: public PointMatcher::DataPointsFilter 42 | { 43 | typedef PointMatcherSupport::Parametrizable Parametrizable; 44 | typedef PointMatcherSupport::Parametrizable P; 45 | typedef Parametrizable::Parameters Parameters; 46 | typedef Parametrizable::ParameterDoc ParameterDoc; 47 | typedef Parametrizable::ParametersDoc ParametersDoc; 48 | typedef Parametrizable::InvalidParameter InvalidParameter; 49 | 50 | typedef typename PointMatcher::Vector Vector; 51 | typedef typename PointMatcher::DataPoints DataPoints; 52 | typedef typename PointMatcher::DataPoints::InvalidField InvalidField; 53 | 54 | inline static const std::string description() 55 | { 56 | return "Remove ghost points appearing on edge discontinuties. Assume that the origine of the point cloud is close to where the laser center was. Requires surface normal for every points"; 57 | } 58 | 59 | inline static const ParametersDoc availableParameters() 60 | { 61 | return { 62 | {"eps", "Small angle (in rad) around which a normal shoudn't be observable", "0.1", "0.0", "3.1416", &P::Comp} 63 | }; 64 | } 65 | 66 | const T eps; 67 | 68 | //! Constructor, uses parameter interface 69 | ShadowDataPointsFilter(const Parameters& params = Parameters()); 70 | 71 | virtual DataPoints filter(const DataPoints& input); 72 | virtual void inPlaceFilter(DataPoints& cloud); 73 | }; 74 | -------------------------------------------------------------------------------- /pointmatcher/DataPointsFilters/utils/octree/OctreeLookupTable.h: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2018, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include 37 | 38 | template < typename T, std::size_t dim > 39 | class Octree_; 40 | 41 | /** 42 | * @brief Octree offset lookup table. 43 | * 44 | * @tparam T Octree type. 45 | * @tparam dim Dimension of the points stored by the octree (e.g. 2, 3) 46 | */ 47 | template 48 | struct OctreeLookupTable; 49 | 50 | /** 51 | * @brief Octree offset lookup table in 2 dimensions 52 | * 53 | * @tparam T Octree type. 54 | */ 55 | template 56 | struct OctreeLookupTable 57 | { 58 | static const typename Octree_::Point offsetTable[Octree_::nbCells]; 59 | }; 60 | template 61 | const typename Octree_::Point OctreeLookupTable::offsetTable[Octree_::nbCells] = 62 | { 63 | {-0.5, -0.5, -0.5}, 64 | {+0.5, -0.5, -0.5}, 65 | {-0.5, +0.5, -0.5}, 66 | {+0.5, +0.5, -0.5}, 67 | {-0.5, -0.5, +0.5}, 68 | {+0.5, -0.5, +0.5}, 69 | {-0.5, +0.5, +0.5}, 70 | {+0.5, +0.5, +0.5} 71 | }; 72 | 73 | /** 74 | * @brief Octree offset lookup table in 3 dimensions 75 | * 76 | * @tparam T Octree type. 77 | */ 78 | template 79 | struct OctreeLookupTable 80 | { 81 | static const typename Octree_::Point offsetTable[Octree_::nbCells]; 82 | }; 83 | template 84 | const typename Octree_::Point OctreeLookupTable::offsetTable[Octree_::nbCells] = 85 | { 86 | {-0.5, -0.5}, 87 | {+0.5, -0.5}, 88 | {-0.5, +0.5}, 89 | {+0.5, +0.5} 90 | }; 91 | 92 | -------------------------------------------------------------------------------- /pointmatcher/DeprecationWarnings.h: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | Copyright (c) 2010--2012, 5 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 6 | You can contact the authors at and 7 | 8 | All rights reserved. 9 | Redistribution and use in source and binary forms, with or without 10 | modification, are permitted provided that the following conditions are met: 11 | * Redistributions of source code must retain the above copyright 12 | notice, this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above copyright 14 | notice, this list of conditions and the following disclaimer in the 15 | documentation and/or other materials provided with the distribution. 16 | * Neither the name of the nor the 17 | names of its contributors may be used to endorse or promote products 18 | derived from this software without specific prior written permission. 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 23 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef __POINTMATCHER_DEPRECATION_WARNINGS_H 32 | #define __POINTMATCHER_DEPRECATION_WARNINGS_H 33 | 34 | 35 | #if __cplusplus >= 201402L 36 | #define PM_DEPRECATED(msg) [[deprecated(msg)]] 37 | #define PM_DEPRECATION_SUPPORTED 38 | #elif defined(__GNUC__) 39 | #define PM_DEPRECATED(msg) __attribute__((deprecated)) 40 | #define PM_DEPRECATION_SUPPORTED 41 | #elif defined(_MSC_VER) 42 | #define PM_DEPRECATED(msg) __declspec(deprecated) 43 | #define PM_DEPRECATION_SUPPORTED 44 | #else 45 | #define PM_DEPRECATED(msg) 46 | #endif 47 | 48 | #endif /* __POINTMATCHER_DEPRECATION_WARNINGS_H */ 49 | -------------------------------------------------------------------------------- /pointmatcher/ErrorMinimizers/Identity.cpp: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2012, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "ErrorMinimizersImpl.h" 37 | 38 | template 39 | typename PointMatcher::TransformationParameters IdentityErrorMinimizer::compute(ErrorElements& mPts) 40 | { 41 | const int dim = mPts.reading.getHomogeneousDim(); 42 | return TransformationParameters::Identity(dim, dim); 43 | } 44 | 45 | template struct IdentityErrorMinimizer; 46 | template struct IdentityErrorMinimizer; 47 | -------------------------------------------------------------------------------- /pointmatcher/ErrorMinimizers/Identity.h: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2012, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #ifndef LIBPOINTMATCHER_IDENTITY_H 37 | #define LIBPOINTMATCHER_IDENTITY_H 38 | 39 | #include "PointMatcher.h" 40 | 41 | template 42 | struct IdentityErrorMinimizer: PointMatcher::ErrorMinimizer 43 | { 44 | typedef typename PointMatcher::TransformationParameters TransformationParameters; 45 | typedef typename PointMatcher::ErrorMinimizer::ErrorElements ErrorElements; 46 | 47 | inline static const std::string description() 48 | { 49 | return "Does nothing."; 50 | } 51 | 52 | IdentityErrorMinimizer() : PointMatcher::ErrorMinimizer("IdentityErrorMinimizer", 53 | PointMatcherSupport::Parametrizable::ParametersDoc(), 54 | PointMatcherSupport::Parametrizable::Parameters()) {} 55 | //virtual TransformationParameters compute(const DataPoints& filteredReading, const DataPoints& filteredReference, const OutlierWeights& outlierWeights, const Matches& matches); 56 | virtual TransformationParameters compute(ErrorElements& mPts); 57 | }; 58 | 59 | #endif //LIBPOINTMATCHER_IDENTITY_H 60 | -------------------------------------------------------------------------------- /pointmatcher/ErrorMinimizersImpl.h: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2012, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #ifndef __POINTMATCHER_ERRORMINIMIZERS_H 37 | #define __POINTMATCHER_ERRORMINIMIZERS_H 38 | 39 | #include "PointMatcher.h" 40 | #include "ErrorMinimizers/PointToPlane.h" 41 | #include "ErrorMinimizers/PointToPlaneWithCov.h" 42 | #include "ErrorMinimizers/PointToPoint.h" 43 | #include "ErrorMinimizers/PointToPointWithCov.h" 44 | #include "ErrorMinimizers/PointToPointSimilarity.h" 45 | #include "ErrorMinimizers/Identity.h" 46 | 47 | template 48 | struct ErrorMinimizersImpl 49 | { 50 | typedef ::PointToPlaneErrorMinimizer PointToPlaneErrorMinimizer; 51 | typedef ::PointToPlaneWithCovErrorMinimizer PointToPlaneWithCovErrorMinimizer; 52 | typedef ::PointToPointErrorMinimizer PointToPointErrorMinimizer; 53 | typedef ::PointToPointWithCovErrorMinimizer PointToPointWithCovErrorMinimizer; 54 | typedef ::PointToPointSimilarityErrorMinimizer PointToPointSimilarityErrorMinimizer; 55 | typedef ::IdentityErrorMinimizer IdentityErrorMinimizer; 56 | }; // ErrorMinimizersImpl 57 | 58 | #endif // __POINTMATCHER_ERRORMINIMIZER_H 59 | -------------------------------------------------------------------------------- /pointmatcher/Exceptions.cpp: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2012, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "PointMatcher.h" 37 | 38 | //TODO: gather exceptions here and in Exceptions.cpp 39 | 40 | //! Construct the exception with an error message 41 | template 42 | PointMatcher::ConvergenceError::ConvergenceError(const std::string& reason): 43 | runtime_error(reason) 44 | {} 45 | 46 | PointMatcherSupport::ConfigurationError::ConfigurationError(const std::string& reason): 47 | runtime_error(reason) 48 | {} 49 | 50 | template struct PointMatcher::ConvergenceError; 51 | template struct PointMatcher::ConvergenceError; 52 | -------------------------------------------------------------------------------- /pointmatcher/Functions.h: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2012, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #ifndef __POINTMATCHER_FUNCTIONS_H 37 | #define __POINTMATCHER_FUNCTIONS_H 38 | 39 | #include 40 | 41 | namespace PointMatcherSupport 42 | { 43 | template 44 | static inline T anyabs(const T& v) 45 | { 46 | if (v < T(0)) 47 | return -v; 48 | else 49 | return v; 50 | } 51 | 52 | template 53 | static inline T normalizeAngle(T v) 54 | { 55 | while (v > M_PI) 56 | v -= 2*M_PI; 57 | while (v < -M_PI) 58 | v += 2*M_PI; 59 | return v; 60 | } 61 | 62 | 63 | 64 | } // PointMatcherSupport 65 | 66 | #endif // __POINTMATCHER_FUNCTIONS_H 67 | -------------------------------------------------------------------------------- /pointmatcher/Histogram.h: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2012, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #ifndef __POINTMATCHER_HISTOGRAM_H 37 | #define __POINTMATCHER_HISTOGRAM_H 38 | 39 | #include 40 | #include 41 | #include 42 | 43 | namespace PointMatcherSupport 44 | { 45 | template 46 | struct Histogram: public std::vector 47 | { 48 | const size_t binCount; 49 | const std::string name; 50 | const std::string filePrefix; 51 | const bool dumpStdErrOnExit; 52 | 53 | Histogram(const size_t binCount, const std::string& name, const std::string& 54 | filePrefix, const bool dumpStdErrOnExit); 55 | 56 | virtual ~Histogram(); 57 | 58 | //! This function compute statistics and writes them into the variables passed as reference 59 | std::vector computeStats(T& meanV, T& varV, T& medianV, T& lowQt, T& highQt, T& minV, T& maxV, uint64_t& maxBinC); 60 | 61 | void dumpStats(std::ostream& os); 62 | void dumpStatsHeader(std::ostream& os) const; 63 | }; 64 | } // namespace PointMatcherSupport 65 | 66 | #endif // __POINTMATCHER_HISTOGRAM_H 67 | -------------------------------------------------------------------------------- /pointmatcher/IOFunctions.cpp: -------------------------------------------------------------------------------- 1 | #include "IOFunctions.h" 2 | 3 | namespace PointMatcherSupport 4 | { 5 | 6 | 7 | std::istream & safeGetLine( std::istream& is, std::string & t) 8 | { 9 | t.clear(); 10 | 11 | // The characters in the stream are read one-by-one using a std::streambuf. 12 | // That is faster than reading them one-by-one using the std::istream. 13 | // Code that uses streambuf this way must be guarded by a sentry object. 14 | // The sentry object performs various tasks, 15 | // such as thread synchronization and updating the stream state. 16 | 17 | std::istream::sentry se(is, true); 18 | std::streambuf* sb = is.rdbuf(); 19 | 20 | for(;;) { 21 | int c = sb->sbumpc(); 22 | switch (c) { 23 | case '\n': 24 | return is; 25 | case '\r': 26 | if(sb->sgetc() == '\n') 27 | sb->sbumpc(); 28 | return is; 29 | case EOF: 30 | // Also handle the case when the last line has no line ending 31 | if(t.empty()) 32 | is.setstate(std::ios::eofbit); 33 | return is; 34 | default: 35 | t += (char)c; 36 | } 37 | } 38 | } 39 | 40 | }// namespace PointMatcherSupport 41 | -------------------------------------------------------------------------------- /pointmatcher/Matcher.cpp: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2012, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "PointMatcher.h" 37 | #include "PointMatcherPrivate.h" 38 | 39 | #include 40 | 41 | using namespace std; 42 | 43 | //! Construct without parameter 44 | template 45 | PointMatcher::Matcher::Matcher(): 46 | visitCounter(0) 47 | {} 48 | 49 | //! Construct with parameters 50 | template 51 | PointMatcher::Matcher::Matcher(const std::string& className, const ParametersDoc paramsDoc, const Parameters& params): 52 | Parametrizable(className,paramsDoc,params), 53 | visitCounter(0) 54 | {} 55 | 56 | //! virtual destructor 57 | template 58 | PointMatcher::Matcher::~Matcher() 59 | {} 60 | 61 | //! Reset the visit counter 62 | template 63 | void PointMatcher::Matcher::resetVisitCount() 64 | { 65 | visitCounter = 0; 66 | } 67 | 68 | //! Return the visit counter 69 | template 70 | unsigned long PointMatcher::Matcher::getVisitCount() const 71 | { 72 | return visitCounter; 73 | } 74 | 75 | template struct PointMatcher::Matcher; 76 | template struct PointMatcher::Matcher; 77 | -------------------------------------------------------------------------------- /pointmatcher/Registrar.cpp: -------------------------------------------------------------------------------- 1 | #include "PointMatcher.h" 2 | 3 | #include 4 | 5 | namespace PointMatcherSupport 6 | { 7 | void getNameParamsFromYAML(const YAML::Node& module, std::string& name, Parametrizable::Parameters& params) 8 | { 9 | if (module.size() != 1) 10 | { 11 | // parameter-less entry 12 | name = module.as(); 13 | } 14 | else 15 | { 16 | // get parameters 17 | YAML::const_iterator mapIt(module.begin()); 18 | name = mapIt->first.as(); 19 | for (YAML::const_iterator paramIt = mapIt->second.begin(); paramIt != mapIt->second.end(); ++paramIt) 20 | { 21 | auto key = paramIt->first.as(); 22 | auto value = paramIt->second.as(); 23 | params[key] = value; 24 | } 25 | } 26 | } 27 | } // namespace PointMatcherSupport 28 | -------------------------------------------------------------------------------- /pointmatcher/Timer.cpp: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2012, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include "Timer.h" 37 | 38 | #ifdef __MACH__ 39 | #include 40 | #include 41 | #endif 42 | 43 | #ifdef _POSIX_TIMERS 44 | namespace PointMatcherSupport 45 | { 46 | timer::timer(): 47 | _start_time(curTime()) 48 | { 49 | } 50 | 51 | void timer::restart() 52 | { 53 | _start_time = curTime(); 54 | } 55 | 56 | double timer::elapsed() const 57 | { 58 | return double(curTime() - _start_time) / double(1000000000); 59 | } 60 | 61 | timer::Time timer::curTime() const 62 | { 63 | #ifdef __MACH__ // OS X does not have clock_gettime, use clock_get_time 64 | clock_serv_t host_clock; 65 | mach_timespec_t now; 66 | host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &host_clock); 67 | clock_get_time(host_clock, &now); 68 | return Time(now.tv_sec) * Time(1000000000) + Time(now.tv_nsec); 69 | #else // __MACH__ 70 | struct timespec ts; 71 | #ifdef CLOCK_PROCESS_CPUTIME_ID 72 | clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts); 73 | #else // BSD and old Linux 74 | clock_gettime(CLOCK_PROF, &ts); 75 | #endif 76 | return Time(ts.tv_sec) * Time(1000000000) + Time(ts.tv_nsec); 77 | #endif // __MACH__ 78 | } 79 | } // namespace PointMatcherSupport 80 | #endif // _POSIX_TIMERS 81 | 82 | -------------------------------------------------------------------------------- /pointmatcher/Timer.h: -------------------------------------------------------------------------------- 1 | // kate: replace-tabs off; indent-width 4; indent-mode normal 2 | // vim: ts=4:sw=4:noexpandtab 3 | /* 4 | 5 | Copyright (c) 2010--2012, 6 | François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland 7 | You can contact the authors at and 8 | 9 | 10 | All rights reserved. 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are met: 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | * Neither the name of the nor the 20 | names of its contributors may be used to endorse or promote products 21 | derived from this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #ifndef __POINTMATCHER_TIMER_H 37 | #define __POINTMATCHER_TIMER_H 38 | 39 | #include 40 | #ifndef WIN32 41 | #include 42 | #endif // WIN32 43 | 44 | #ifdef _POSIX_TIMERS 45 | namespace PointMatcherSupport 46 | { 47 | /** 48 | High-precision timer class, using clock_gettime() or clock_get_time() 49 | 50 | The interface is a subset of the one boost::timer provides, 51 | but the implementation is much more precise 52 | on systems where clock() has low precision, such as glibc. 53 | 54 | This code gets compiled if _POSIX_TIMERS is set, 55 | generally in time.h or unistd.h 56 | */ 57 | struct timer 58 | { 59 | //! 64-bit time 60 | typedef unsigned long long Time; 61 | 62 | //! Create and start the timer 63 | timer(); 64 | //! Restart the counter 65 | void restart(); 66 | //! Return elapsed time in seconds 67 | double elapsed() const; 68 | 69 | private: 70 | //! Return time at call 71 | Time curTime() const; 72 | 73 | Time _start_time; //! time when counter started 74 | }; 75 | } // namespace PointMatcherSupport 76 | #else // _POSIX_TIMERS 77 | #include 78 | namespace PointMatcherSupport 79 | { 80 | typedef boost::timer timer; 81 | } 82 | #endif // _POSIX_TIMERS 83 | 84 | #endif // __POINTMATCHER_TIMER_H 85 | -------------------------------------------------------------------------------- /pointmatcher/testing/RegistrationTestResult.cpp: -------------------------------------------------------------------------------- 1 | #include "RegistrationTestResult.h" 2 | 3 | #include "utils_geometry.h" 4 | 5 | std::ostream& operator<<(std::ostream& ostream, const RegistrationTestResult& testResult) 6 | { 7 | ostream << "Delta Transformation with respect to the initial guess computed by ICP (icpCorrection_T_origin_read):\n" 8 | << testResult.icpCorrection_T_origin_read.matrix() << "\n"; 9 | ostream << "ICP-Corrected Transformation from reading to coordinate frame origin (icp_T_origin_read):\n" 10 | << testResult.icp_T_origin_read.matrix() << "\n"; 11 | ostream << "Success = " << (testResult.success ? "true" : "false") << "\n"; 12 | if (!testResult.success) 13 | { 14 | ostream << " Reason = " << testResult.message << "\n"; 15 | } 16 | 17 | return ostream; 18 | } 19 | -------------------------------------------------------------------------------- /pointmatcher/testing/RegistrationTestResult.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../PointMatcher.h" 6 | 7 | #include "typedefs.h" 8 | 9 | //! A struct for storing the results of a registration test, containing algorithmic outputs, such as transformations, error messages, success flags, and metrics. 10 | struct RegistrationTestResult 11 | { 12 | //! Computed values. 13 | PM::AffineTransform icpCorrection_T_origin_read{ PM::AffineTransform::Identity() }; 14 | PM::AffineTransform icp_T_origin_read{ PM::AffineTransform::Identity() }; 15 | 16 | //! Transformed point clouds. 17 | // The reading point cloud transformed to the origin frame, according to the initial guess of T_origin_read. 18 | PM::DataPoints readingPointCloudInOriginFrameFollowingInitialGuess; 19 | // The reading point cloud transformed to the origin frame, according to the ICP-corrected T_origin_read. 20 | PM::DataPoints readingPointCloudInOriginFrameFollowingIcpCorrection; 21 | 22 | //! Registration metrics 23 | // Messages written to the logs by ICP. 24 | std::string message; 25 | // Whether ICP successfully converged. 26 | bool success{ false }; 27 | // Overlap between the reference and reading point cloud [0,1]. 28 | PM::ScalarType pointCloudOverlap{ 0.0 }; 29 | // Whether maximum number of iterations were reached. 30 | bool isMaxNumberOfIterationsReached{ false }; 31 | }; 32 | 33 | //! Ostream operator for writing the values of a RegistrationTestResult into a string. 34 | std::ostream& operator<<(std::ostream& ostream, const RegistrationTestResult& testResult); 35 | -------------------------------------------------------------------------------- /pointmatcher/testing/TransformationError.cpp: -------------------------------------------------------------------------------- 1 | #include "TransformationError.h" 2 | 3 | #include "utils_geometry.h" 4 | 5 | TransformationError& TransformationError::operator+=(const TransformationError& rhs) 6 | { 7 | this->translationNorm += rhs.translationNorm; 8 | this->rotationAngle += rhs.rotationAngle; 9 | return *this; 10 | } 11 | 12 | TransformationError operator+(TransformationError lhs, const TransformationError& rhs) 13 | { 14 | lhs += rhs; 15 | return lhs; 16 | } 17 | 18 | TransformationError& TransformationError::operator/=(const PM::ScalarType scalar) 19 | { 20 | this->translationNorm /= scalar; 21 | this->rotationAngle /= scalar; 22 | return *this; 23 | } 24 | 25 | TransformationError operator/(TransformationError lhs, const PM::ScalarType scalar) 26 | { 27 | lhs /= scalar; 28 | return lhs; 29 | } 30 | 31 | std::ostream& operator<<(std::ostream& ostream, const TransformationError& error) 32 | { 33 | ostream << "Translation = " << error.translationNorm << " m\n"; 34 | ostream << "Rotation angle = " << convertRadiansToDegrees(error.rotationAngle) << " degrees\n"; 35 | 36 | return ostream; 37 | } -------------------------------------------------------------------------------- /pointmatcher/testing/TransformationError.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../PointMatcher.h" 6 | 7 | #include "typedefs.h" 8 | 9 | //! A structure used to store the registration error. 10 | struct TransformationError 11 | { 12 | // Value of the translational and rotational deltas. 13 | PM::StaticCoordVector deltaTranslation{PM::StaticCoordVector::Zero()}; 14 | Eigen::AngleAxis deltaRotationAngleAxis{Eigen::AngleAxis::Identity()}; 15 | 16 | //! L2-Norm of the translational error. 17 | PM::ScalarType translationNorm{ 0 }; 18 | //! Rotation angle, coming from an Angle-axis representation of the orientation error. 19 | PM::ScalarType rotationAngle{ 0 }; 20 | 21 | // Sum operators. 22 | TransformationError& operator+=(const TransformationError& rhs); 23 | friend TransformationError operator+(TransformationError lhs, const TransformationError& rhs); 24 | 25 | // Division operators. 26 | TransformationError& operator/=(const PM::ScalarType scalar); 27 | friend TransformationError operator/(TransformationError lhs, const PM::ScalarType scalar); 28 | }; 29 | 30 | //! Ostream operator for writing the values of a TransformationError into a string. 31 | std::ostream& operator<<(std::ostream& ostream, const TransformationError& error); -------------------------------------------------------------------------------- /pointmatcher/testing/typedefs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../PointMatcher.h" 6 | 7 | using NumericType = float; 8 | using PM = PointMatcher; 9 | -------------------------------------------------------------------------------- /pointmatcher/testing/utils_filesystem.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "utils_filesystem.h" 3 | 4 | #include 5 | 6 | #include 7 | 8 | bool createDirectory(const std::string& directoryPath) 9 | { 10 | // If the folder doesn't exist, create it. 11 | try 12 | { 13 | return boost::filesystem::create_directories(directoryPath); 14 | } 15 | catch (const boost::filesystem::filesystem_error& exception) 16 | { 17 | std::cout << "Caught an exception trying to create directory: " << exception.what(); 18 | } 19 | std::cout << "Directory '" << directoryPath.c_str() << "' doesn't exist and could not be created"; 20 | 21 | return false; 22 | } 23 | 24 | bool checkFileExists(const std::string& filePathStr) 25 | { 26 | const boost::filesystem::path filePath(filePathStr); 27 | return boost::filesystem::exists(filePath); 28 | } 29 | 30 | bool checkDirectoryExists(const std::string& directoryPathStr) 31 | { 32 | const boost::filesystem::path directoryPath(directoryPathStr); 33 | return boost::filesystem::is_directory(directoryPath); 34 | } 35 | 36 | bool removeDirectory(const std::string& directoryPath) 37 | { 38 | try 39 | { 40 | return boost::filesystem::remove_all(directoryPath); 41 | } 42 | catch (const boost::filesystem::filesystem_error& exception) 43 | { 44 | std::cout << "Caught an exception trying to remove directory: " << exception.what(); 45 | } 46 | std::cout << "Directory '" << directoryPath.c_str() << "' doesn't exist and could not be removed"; 47 | 48 | return false; 49 | } -------------------------------------------------------------------------------- /pointmatcher/testing/utils_filesystem.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | //! Creates a directory. If the directory to be created contains new sub-folders, they will also be created. 6 | bool createDirectory(const std::string& directoryPath); 7 | 8 | //! Checks if a file exists, based on its path. 9 | bool checkFileExists(const std::string& filePathStr); 10 | 11 | //! Checks if a directory exists, based on its path. 12 | bool checkDirectoryExists(const std::string& directoryPathStr); 13 | 14 | //! Remove a directory. The operation is applied recursively. 15 | bool removeDirectory(const std::string& directoryPath); -------------------------------------------------------------------------------- /pointmatcher/testing/utils_geometry.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "utils_geometry.h" 3 | 4 | #include 5 | 6 | #include 7 | 8 | PM::ScalarType convertRadiansToDegrees(const PM::ScalarType angleRadians) 9 | { 10 | return angleRadians * (180.0 / M_PI); 11 | } 12 | 13 | 14 | PM::ScalarType convertDegreesToRadians(const PM::ScalarType angleDegrees) 15 | { 16 | return angleDegrees * (M_PI / 180.0); 17 | } 18 | 19 | // Creates a quaternion given roll, pitch and yaw (in degrees). 20 | PM::Quaternion buildQuaternionFromRPY(PM::ScalarType roll, PM::ScalarType pitch, PM::ScalarType yaw) 21 | { 22 | PM::Quaternion q{ Eigen::AngleAxisd(convertDegreesToRadians(roll), Eigen::Vector3d::UnitX()) 23 | * Eigen::AngleAxisd(convertDegreesToRadians(pitch), Eigen::Vector3d::UnitY()) 24 | * Eigen::AngleAxisd(convertDegreesToRadians(yaw), Eigen::Vector3d::UnitZ()) }; 25 | q.normalize(); 26 | 27 | return q; 28 | } 29 | 30 | PM::StaticCoordVector buildRandomVectorFromStdDev(PM::ScalarType translationNoiseStdDev) 31 | { 32 | return PM::StaticCoordVector::Random() * translationNoiseStdDev; 33 | } 34 | 35 | PM::Quaternion buildRandomQuaternionFromStdDev(PM::ScalarType rotationNoiseStdDevInRad) 36 | { 37 | // Generate rotation angle and axis. 38 | std::random_device randomDevice; 39 | std::mt19937 randomNumberGenerator(randomDevice()); 40 | std::normal_distribution randomDistribution(0, rotationNoiseStdDevInRad); 41 | const PM::ScalarType rotationAngle{ randomDistribution(randomNumberGenerator) }; 42 | const PM::StaticCoordVector rotationAxis{ PM::StaticCoordVector::Random() }; 43 | 44 | // Build quaternion 45 | PM::Quaternion q{ Eigen::AngleAxis(rotationAngle, rotationAxis.normalized()) }; 46 | q.normalize(); 47 | 48 | return q; 49 | } -------------------------------------------------------------------------------- /pointmatcher/testing/utils_geometry.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../PointMatcher.h" 6 | #include "typedefs.h" 7 | 8 | //! Converts an angle from radians to degrees. 9 | PM::ScalarType convertRadiansToDegrees(const PM::ScalarType angleRadians); 10 | 11 | //! Converts an angle from degrees to radians. 12 | PM::ScalarType convertDegreesToRadians(const PM::ScalarType angleDegrees); 13 | 14 | //! Creates a quaternion given roll, pitch and yaw (in degrees). 15 | //! The quaternion is created through an XYZ Euler Angles parameterization that receives the RPY values. 16 | PM::Quaternion buildQuaternionFromRPY(PM::ScalarType roll, PM::ScalarType pitch, PM::ScalarType yaw); 17 | 18 | //! Creates a random vector with a given standard deviation in its coordinates. 19 | //! The output vector has random components, with a magnitude equal to the standard deviation. 20 | PM::StaticCoordVector buildRandomVectorFromStdDev(PM::ScalarType translationNoiseStdDev); 21 | 22 | //! Creates a quaternion from a single standard deviation factor that defines the span of 23 | //! a distribution of rotation angles. We sample an angle from that distribution 24 | //! to form a quaternion an Angle-Axis parameterization around a randomly-sampled axis. 25 | PM::Quaternion buildRandomQuaternionFromStdDev(PM::ScalarType rotationNoiseStdDevInDeg); -------------------------------------------------------------------------------- /pointmatcher/testing/utils_gtest.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "utils_gtest.h" 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | std::string fetchTestName() 10 | { 11 | // Reference: https://github.com/google/googletest/blob/main/docs/advanced.md#getting-the-current-tests-name 12 | const testing::TestInfo* const test_info{ testing::UnitTest::GetInstance()->current_test_info() }; 13 | if (test_info == nullptr) 14 | { 15 | return ""; 16 | } 17 | 18 | return test_info->name(); 19 | } 20 | 21 | // Sets up Randon Number Generation (RNG) with a known seed. 22 | void setUpKnownRNGSeedForTest(const unsigned int seed) 23 | { 24 | // Seed random number generator and record value of seed. 25 | srand(seed); 26 | ::testing::Test::RecordProperty("random_seed", seed); 27 | } 28 | 29 | // Sets up Randon Number Generation (RNG) with a random (time-based) seed. 30 | void setUpRandomRNGSeedForTest() 31 | { 32 | // Seed random number generator and record value of seed. 33 | const unsigned int seed{ static_cast(std::chrono::system_clock::now().time_since_epoch().count()) }; 34 | srand(seed); 35 | ::testing::Test::RecordProperty("random_seed", seed); 36 | } -------------------------------------------------------------------------------- /pointmatcher/testing/utils_gtest.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | //! Fetches the name of the test case currently running. 6 | std::string fetchTestName(); 7 | 8 | //! Sets up Randon Number Generation (RNG) with a known seed. 9 | void setUpKnownRNGSeedForTest(const unsigned int seed); 10 | 11 | //! Sets up Randon Number Generation (RNG) with a random (time-based) seed. 12 | void setUpRandomRNGSeedForTest(); -------------------------------------------------------------------------------- /pointmatcher/testing/utils_registration.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../PointMatcher.h" 6 | 7 | #include "typedefs.h" 8 | #include "RegistrationTestResult.h" 9 | 10 | //! Configures ICP based on a config file. 11 | bool configureIcp(const std::string& filePath, const std::string& configFileName, PM::ICP& icp); 12 | 13 | //! Registers two point clouds based on an initial guess transformation. 14 | RegistrationTestResult registerPointClouds(const PM::DataPoints& readingPointCloud, 15 | const PM::DataPoints& referencePointCloud, 16 | const PM::AffineTransform& initialGuess_T_origin_read, 17 | PM::ICP& icp); 18 | -------------------------------------------------------------------------------- /pointmatcher/testing/utils_transformations.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "utils_transformations.h" 3 | 4 | #include 5 | 6 | #include 7 | 8 | TransformationError computeError(const PM::AffineTransform& transformA, const PM::AffineTransform& transformB) 9 | { 10 | TransformationError error; 11 | 12 | // Compute delta between A and B. 13 | const PM::AffineTransform deltaTransform{ transformA.inverse() * transformB }; 14 | 15 | // Translation. 16 | error.deltaTranslation = deltaTransform.translation(); 17 | error.translationNorm = error.deltaTranslation.norm(); 18 | 19 | // Rotation. 20 | const PM::Quaternion deltaRotation{ deltaTransform.linear() }; 21 | error.deltaRotationAngleAxis = Eigen::AngleAxis(deltaRotation); 22 | error.rotationAngle = std::abs(error.deltaRotationAngleAxis.angle()); 23 | 24 | return error; 25 | } 26 | 27 | bool isApprox(const PM::AffineTransform& transformA, const PM::AffineTransform& transformB, const PM::ScalarType epsilon, 28 | std::string& message) 29 | { 30 | const TransformationError error{ computeError(transformA, transformB) }; 31 | 32 | // Compute delta between A and B. 33 | const PM::AffineTransform deltaTransform{ transformA.inverse() * transformB }; 34 | 35 | // Translation 36 | std::stringstream messageStream; 37 | bool areApproxEqual{ true }; 38 | if ((error.deltaTranslation.array().abs() >= epsilon).any()) 39 | { 40 | messageStream << "Translation delta = " << error.deltaTranslation.transpose() << std::endl; 41 | messageStream << "Magnitude of translation delta = " << error.translationNorm << std::endl; 42 | areApproxEqual = false; 43 | } 44 | 45 | if (std::abs(error.rotationAngle) >= epsilon) 46 | { 47 | messageStream << "Angle-Axis angle = " << error.rotationAngle << std::endl; 48 | messageStream << "Angle-Axis axis = " << error.deltaRotationAngleAxis.axis().transpose() << std::endl; 49 | areApproxEqual = false; 50 | } 51 | 52 | messageStream << "Epsilon = " << epsilon << std::endl; 53 | message = messageStream.str(); 54 | 55 | return areApproxEqual; 56 | } -------------------------------------------------------------------------------- /pointmatcher/testing/utils_transformations.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../PointMatcher.h" 6 | 7 | #include "TransformationError.h" 8 | 9 | /** 10 | * @brief Computes the error between two transformations A and B 11 | * @remark It bases the error computation on the definition of delta = inverse(T_A) * T_b 12 | * 13 | * @param transformA 14 | * @param transformB 15 | * @return TransformationError 16 | */ 17 | TransformationError computeError(const PM::AffineTransform& transformA, const PM::AffineTransform& transformB); 18 | 19 | /** 20 | * @brief Checks whether two transforms A and B are approximately equal, up to an error tolerance. 21 | * 22 | * @param transformA Transform A. 23 | * @param transformB Transform B. 24 | * @param epsilon Error tolerance. 25 | * @param message Error message, if any. 26 | * @return bool Whether the transformations are approximately equal. 27 | */ 28 | bool isApprox(const PM::AffineTransform& transformA, const PM::AffineTransform& transformB, const PM::ScalarType epsilon, 29 | std::string& message); -------------------------------------------------------------------------------- /utest/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | include_directories(../contrib/gtest) 3 | add_executable(utest 4 | utest.cpp 5 | ui/IO.cpp 6 | ui/DataFilters.cpp 7 | ui/Matcher.cpp 8 | ui/Outliers.cpp 9 | ui/ErrorMinimizers.cpp 10 | ui/Transformations.cpp 11 | ui/DataPoints.cpp 12 | ui/Inspectors.cpp 13 | ui/Loggers.cpp 14 | ui/octree/Octree.cpp 15 | ui/icp/GeneralTests.cpp 16 | ui/utils_filesystem.cpp 17 | ui/utils_geometry.cpp 18 | ui/utils_gtest.cpp 19 | ui/utils_transformations.cpp 20 | ui/TransformationError.cpp 21 | ui/icp/RegistrationTestCase.cpp 22 | ui/icp/RegistrationTestResult.cpp 23 | ui/icp/utils_registration.cpp 24 | ui/icp/Conditioning.cpp 25 | ) 26 | 27 | find_package (Threads) 28 | target_link_libraries(utest gtest pointmatcher ${CMAKE_THREAD_LIBS_INIT}) 29 | 30 | add_test(utest ${CMAKE_CURRENT_BINARY_DIR}/utest --path "${CMAKE_SOURCE_DIR}/examples/data/") 31 | 32 | -------------------------------------------------------------------------------- /utest/listVersionsUbuntu.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo -e "\n Copy-paste those information when reporting a bug in libpointmatcher:\n" 4 | 5 | echo -e "Name \t\t| Version" 6 | echo -e "----------------|-------------------------------" 7 | echo -e "ubuntu: \t|" $(lsb_release -d) 8 | echo -e "architecture: \t|" $(getconf LONG_BIT)"-bit" 9 | echo -e "gcc: \t\t|" $(gcc --version | grep gcc) 10 | echo -e "git: \t\t|" $(git --version) 11 | echo -e "cmake: \t\t|" $(cmake --version) 12 | echo -e "boost: \t\t|" $(dpkg -s libboost-dev | grep Version) 13 | echo -e "eigen3: \t|" $(dpkg -s libeigen3-dev | grep Version) 14 | echo -e "doxygen: \t|" $(dpkg -s doxygen | grep Version) 15 | echo -e "\n\n" 16 | -------------------------------------------------------------------------------- /utest/ui/ErrorMinimizers.cpp: -------------------------------------------------------------------------------- 1 | #include "../utest.h" 2 | 3 | using namespace std; 4 | using namespace PointMatcherSupport; 5 | 6 | //--------------------------- 7 | // Error modules 8 | //--------------------------- 9 | 10 | // Utility classes 11 | class ErrorMinimizerTest: public IcpHelper 12 | { 13 | public: 14 | std::shared_ptr errorMin; 15 | 16 | // Will be called for every tests 17 | virtual void SetUp() 18 | { 19 | icp.setDefault(); 20 | // Uncomment for consol outputs 21 | //setLogger(PM::get().LoggerRegistrar.create("FileLogger")); 22 | } 23 | 24 | // Will be called for every tests 25 | virtual void TearDown(){} 26 | 27 | void setError(string name) 28 | { 29 | errorMin = PM::get().ErrorMinimizerRegistrar.create(name); 30 | icp.errorMinimizer = errorMin; 31 | } 32 | }; 33 | 34 | 35 | TEST_F(ErrorMinimizerTest, PointToPointErrorMinimizer) 36 | { 37 | setError("PointToPointErrorMinimizer"); 38 | validate2dTransformation(); 39 | validate3dTransformation(); 40 | } 41 | 42 | TEST_F(ErrorMinimizerTest, PointToPlaneErrorMinimizer) 43 | { 44 | setError("PointToPlaneErrorMinimizer"); 45 | validate2dTransformation(); 46 | validate3dTransformation(); 47 | } 48 | 49 | TEST_F(ErrorMinimizerTest, ErrorElements) 50 | { 51 | const unsigned int nbPoints = 100; 52 | const unsigned int dimFeatures = 4; 53 | const unsigned int dimDescriptors = 3; 54 | const unsigned int dimTime = 2; 55 | 56 | // Fake DataPoints 57 | PM::Matrix randFeat = PM::Matrix::Random(dimFeatures, nbPoints); 58 | DP::Labels featLabels; 59 | featLabels.push_back(DP::Label("x", 1)); 60 | featLabels.push_back(DP::Label("y", 1)); 61 | featLabels.push_back(DP::Label("z", 1)); 62 | featLabels.push_back(DP::Label("pad", 1)); 63 | 64 | PM::Matrix randDesc = PM::Matrix::Random(dimDescriptors, nbPoints); 65 | DP::Labels descLabels; 66 | descLabels.push_back(DP::Label("dummyDesc", 3)); 67 | 68 | PM::Int64Matrix randTimes = PM::Int64Matrix::Random(dimTime, nbPoints); 69 | DP::Labels timeLabels; 70 | timeLabels.push_back(DP::Label("dummyTime", 2)); 71 | 72 | // Construct the point cloud from the generated matrices 73 | DP request = DP(randFeat, featLabels, randDesc, descLabels, randTimes, timeLabels); 74 | DP source = DP(randFeat, featLabels, randDesc, descLabels, randTimes, timeLabels); 75 | 76 | // Fake Weights 77 | PM::OutlierWeights weights = PM::OutlierWeights::Ones(1, nbPoints); 78 | 79 | // Fake Matches 80 | PM::Matches::Ids ids(1, nbPoints); 81 | PM::Matches::Dists dists(1, nbPoints); 82 | 83 | for(unsigned int i=0; i performances = 12 | PM::get().REG(Inspector).create( 13 | "PerformanceInspector", { 14 | {"baseFileName", "/tmp/utest_performances"}, 15 | {"dumpPerfOnExit", "1"} 16 | } 17 | ) 18 | ; 19 | 20 | performances->init(); 21 | 22 | //TODO: we only test constructor here, check other things... 23 | } 24 | 25 | TEST(Inspectors, VTKFileInspector) 26 | { 27 | std::shared_ptr vtkFile = 28 | PM::get().REG(Inspector).create( 29 | "VTKFileInspector", { 30 | {"baseFileName", "/tmp/utest_vtk"}, 31 | {"dumpPerfOnExit", "1"} 32 | } 33 | ); 34 | //TODO: we only test constructor here, check other things... 35 | } 36 | -------------------------------------------------------------------------------- /utest/ui/Loggers.cpp: -------------------------------------------------------------------------------- 1 | #include "../utest.h" 2 | 3 | using namespace std; 4 | using namespace PointMatcherSupport; 5 | 6 | //--------------------------- 7 | // Loggers 8 | //--------------------------- 9 | 10 | TEST(Loggers, FileLogger) 11 | { 12 | string infoFileName = "utest_info"; 13 | string warningFileName = "utest_warn"; 14 | 15 | std::shared_ptr fileLog = 16 | PM::get().REG(Logger).create( 17 | "FileLogger", { 18 | {"infoFileName", infoFileName}, 19 | { "warningFileName", warningFileName }, 20 | { "displayLocation", "1" } 21 | } 22 | ); 23 | 24 | fileLog.reset(); // The logger needs to release the files to allow them to be removed 25 | 26 | EXPECT_TRUE(boost::filesystem::remove(boost::filesystem::path(infoFileName))); 27 | EXPECT_TRUE(boost::filesystem::remove(boost::filesystem::path(warningFileName))); 28 | } 29 | 30 | TEST(Loggers, FileLoggerInfoToConsole) 31 | { 32 | std::shared_ptr fileLog = 33 | PM::get().REG(Logger).create( 34 | "FileLogger", { 35 | { "displayLocation", "1" } 36 | } 37 | ); 38 | EXPECT_NO_THROW((*fileLog->infoStream()) << "TEST\n"); 39 | } 40 | 41 | TEST(Loggers, FileLoggerWarningToConsole) 42 | { 43 | std::shared_ptr fileLog = 44 | PM::get().REG(Logger).create( 45 | "FileLogger", { 46 | { "displayLocation", "1" } 47 | } 48 | ); 49 | EXPECT_NO_THROW((*fileLog->warningStream()) << "TEST\n"); 50 | } 51 | 52 | TEST(Loggers, FileLoggerInfoToFile) 53 | { 54 | string infoFileName = "utest_info"; 55 | 56 | std::shared_ptr fileLog = 57 | PM::get().REG(Logger).create( 58 | "FileLogger", { 59 | {"infoFileName", infoFileName}, 60 | { "displayLocation", "1" } 61 | } 62 | ); 63 | 64 | EXPECT_NO_THROW((*fileLog->infoStream()) << "TEST"); 65 | 66 | fileLog.reset(); // The logger needs to release the file to allow it to be removed 67 | 68 | EXPECT_TRUE(boost::filesystem::remove(boost::filesystem::path(infoFileName))); 69 | } 70 | 71 | TEST(Loggers, FileLoggerWarningToFile) 72 | { 73 | string warningFileName = "utest_warn"; 74 | 75 | std::shared_ptr fileLog = 76 | PM::get().REG(Logger).create( 77 | "FileLogger", { 78 | { "warningFileName", warningFileName }, 79 | { "displayLocation", "1" } 80 | } 81 | ); 82 | 83 | EXPECT_NO_THROW((*fileLog->warningStream()) << "TEST"); 84 | 85 | fileLog.reset(); // The logger needs to release the file to allow it to be removed 86 | 87 | EXPECT_TRUE(boost::filesystem::remove(boost::filesystem::path(warningFileName))); 88 | } 89 | -------------------------------------------------------------------------------- /utest/ui/Matcher.cpp: -------------------------------------------------------------------------------- 1 | #include "../utest.h" 2 | 3 | using namespace std; 4 | using namespace PointMatcherSupport; 5 | 6 | //--------------------------- 7 | // Matcher modules 8 | //--------------------------- 9 | 10 | // Utility classes 11 | class MatcherTest: public IcpHelper 12 | { 13 | 14 | public: 15 | 16 | std::shared_ptr testedMatcher; 17 | 18 | // Will be called for every tests 19 | virtual void SetUp() 20 | { 21 | icp.setDefault(); 22 | // Uncomment for consol outputs 23 | //setLogger(PM::get().LoggerRegistrar.create("FileLogger")); 24 | } 25 | 26 | // Will be called for every tests 27 | virtual void TearDown(){} 28 | 29 | void addFilter(string name, PM::Parameters params) 30 | { 31 | testedMatcher = 32 | PM::get().MatcherRegistrar.create(name, params); 33 | icp.matcher = testedMatcher; 34 | } 35 | 36 | }; 37 | 38 | TEST_F(MatcherTest, MirrorMatcher) 39 | { 40 | // Generate test data. 41 | const PM::StaticCoordVector translation{ PM::StaticCoordVector::Zero() }; 42 | const PM::Quaternion orientation{ PM::Quaternion::Identity() }; 43 | const PM::DataPoints::Index numberOfPoints{ 10000 }; 44 | const PM::ScalarType radius{ 10 }; 45 | const PM::DataPoints pointCloud{ PM::PointCloudGenerator::generateUniformlySampledSphere( 46 | radius, numberOfPoints, translation, orientation) }; 47 | 48 | // Init matcher. 49 | auto matcher = PM::get().MatcherRegistrar.create("MirrorMatcher", PM::Parameters()); 50 | matcher->init(pointCloud); 51 | 52 | // Find matches. 53 | const auto matches(matcher->findClosests(pointCloud)); 54 | 55 | // Validate matches. 56 | bool areMatchesPerfect{ true }; 57 | for (PM::DataPoints::Index i = 0; i < numberOfPoints; ++i) 58 | { 59 | if ((matches.dists(0, i) != 0) || (matches.ids(0, i) != i)) 60 | { 61 | areMatchesPerfect = false; 62 | break; 63 | } 64 | } 65 | ASSERT_TRUE(areMatchesPerfect); 66 | } 67 | 68 | TEST_F(MatcherTest, KDTreeMatcher) 69 | { 70 | vector knn = {1, 2, 3}; 71 | vector epsilon = {0.0, 0.2}; 72 | vector maxDist = {1.0, 0.5}; 73 | 74 | for(unsigned i=0; i < knn.size(); i++) 75 | { 76 | for(unsigned j=0; j < epsilon.size(); j++) 77 | { 78 | for(unsigned k=0; k < maxDist.size(); k++) 79 | { 80 | params = PM::Parameters(); 81 | params["knn"] = toParam(knn[i]); // remove end parenthesis for bug 82 | params["epsilon"] = toParam(epsilon[j]); 83 | params["searchType"] = "1"; 84 | params["maxDist"] = toParam(maxDist[k]); 85 | 86 | 87 | addFilter("KDTreeMatcher", params); 88 | validate2dTransformation(); 89 | validate3dTransformation(); 90 | } 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /utest/utest.h: -------------------------------------------------------------------------------- 1 | #ifndef UTEST_HPP_ 2 | #define UTEST_HPP_ 3 | 4 | #include "pointmatcher/PointMatcher.h" 5 | #include "pointmatcher/IO.h" 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | #include "boost/filesystem.hpp" 12 | #include "boost/filesystem/path.hpp" 13 | #include "boost/filesystem/operations.hpp" 14 | 15 | typedef float NumericType; 16 | typedef PointMatcher PM; 17 | typedef PM::DataPoints DP; 18 | 19 | extern std::string dataPath; 20 | 21 | extern DP ref2D; 22 | extern DP data2D; 23 | extern DP ref3D; 24 | extern DP data3D; 25 | extern PM::TransformationParameters validT2d; 26 | extern PM::TransformationParameters validT3d; 27 | 28 | //--------------------------- 29 | // Base for ICP tests 30 | //--------------------------- 31 | 32 | class IcpHelper: public testing::Test 33 | { 34 | public: 35 | 36 | PM::ICP icp; 37 | 38 | PM::Parameters params; 39 | 40 | virtual void dumpVTK() 41 | { 42 | // Make available a VTK inspector for manual inspection 43 | icp.inspector = 44 | PM::get().InspectorRegistrar.create( 45 | "VTKFileInspector", 46 | {{"baseFileName", "./unitTest"}} 47 | ); 48 | } 49 | 50 | void validate2dTransformation() 51 | { 52 | const PM::TransformationParameters testT = icp(data2D, ref2D); 53 | const int dim = validT2d.cols(); 54 | 55 | const BOOST_AUTO(validTrans, validT2d.block(0, dim-1, dim-1, 1).norm()); 56 | const BOOST_AUTO(testTrans, testT.block(0, dim-1, dim-1, 1).norm()); 57 | 58 | const BOOST_AUTO(validAngle, acos(validT2d(0,0))); 59 | const BOOST_AUTO(testAngle, acos(testT(0,0))); 60 | 61 | EXPECT_NEAR(validTrans, testTrans, 0.05); 62 | EXPECT_NEAR(validAngle, testAngle, 0.05); 63 | } 64 | 65 | void validate3dTransformation() 66 | { 67 | //dumpVTK(); 68 | 69 | const PM::TransformationParameters testT = icp(data3D, ref3D); 70 | const int dim = validT2d.cols(); 71 | 72 | const BOOST_AUTO(validTrans, validT3d.block(0, dim-1, dim-1, 1).norm()); 73 | const BOOST_AUTO(testTrans, testT.block(0, dim-1, dim-1, 1).norm()); 74 | 75 | const BOOST_AUTO(testRotation, PM::Quaternion(Eigen::Matrix(testT.topLeftCorner(3,3)))); 76 | const BOOST_AUTO(validRotation, PM::Quaternion(Eigen::Matrix(validT3d.topLeftCorner(3,3)))); 77 | 78 | const BOOST_AUTO(angleDist, validRotation.angularDistance(testRotation)); 79 | 80 | //cout << testT << endl; 81 | //cout << "angleDist: " << angleDist << endl; 82 | //cout << "transDist: " << abs(validTrans-testTrans) << endl; 83 | EXPECT_NEAR(validTrans, testTrans, 0.1); 84 | EXPECT_NEAR(angleDist, 0.0, 0.1); 85 | 86 | } 87 | }; 88 | 89 | #endif /* UTEST_HPP_ */ 90 | 91 | 92 | --------------------------------------------------------------------------------