Adding doc and tests (#1492)

* added doc and tests for util2d.h

* updated cmake-ros ci

* Added util3d.h doc and tests

* util3d_transforms.h: Added doc and tests

* util3d_filtering.h: started doc and test

* util3d_filtering.h: more tests and doc

* Added more doc/tests

* finished util3d_filtering doc and tests

* added test for util2d::depthBleedingFiltering

* Added util3d_registration tests

* Added util3d_features.h doc/tests

* added doc/tests for util3d_correspondences.h

* added doc/gtest for util3d_mapping.h (missing hpp functions)

* finished testing util3d_mapping.hpp

* Added util3d_motion_estimation.h tests (2D->3D done)

* finished util3d_motion_estimation.h tests

* minimal util3d_surface.h

* Added Transform and VisualWord tests

* Added doc for CameraModel and StereoCameraModel

* Added more logs in ros ci

* Passing tests on fical

* improved all devcontainer

* added devcontainer kilted, fixed source setup.bash, removed ldconfig in ros-cmake workflow

* cleanup

* source ros

* Added utilite tests

* Added testing to appveyor, github actions cancellable on re-commit on same branch

* appveyor testing without all targets

* appveyor: specifying ALL_BUILD target

* Fixed Util2dTest.NMSImageBoundsRespected test

* Fixing PCL Indices error on old pcl

* Added VWDictionary tests and doc. Fixed LSH not working (fix from https://github.com/flann-lib/flann/pull/472

* fixing some appveyor CI errors, added test to check dictionary serialization against all type

* Added StereoDense, StereoBM and StereoSGBM doc and tests

* Added Stereo tests

* Added CameraModel and StereoCameraModel tests

* Added doc and test for Statistics

* Added doc/tests for Signature

* Added doc/test for SensorEvent, added doc for SensorCaptureInfo

* Added doc to SensorData

* Added SensorData tests

* Added SensorCapture and SensorCaptureThread doc and tests

* fixed sensordata test

* updated SSC test and doc

* Added doc and tests for BayesFilter class

* Enabled testing on mac, updated windows testing like on linux

* added test_link

* fixed unresolved on windows

* fixed ThreadHandle error on macos ci

* Added GPS and GeodeticCoords tests

* Added tests for compression

* Added Odometry tests (base class only)

* Added DBDriver tests

* Added coverage report

* uniformized test names

* fixing concurancy and coverage ci

* dont built tools, examples and app for coverage build

* fixed report tool rebuilt without qt compilation error

* updated coverage option

* updated coverage config

* added doc CI job

* fixing windows and mac ci errors

* Added DBDriverSqlite3 tests

* Added IMU tests

* Added Graph tests

* fixing flaky macos test

* Added IMUThread and IMUFilter tests

* Added Landmarks tests

* Added LASWriter tests

* fixing seed flaky test

* fixing flaky macos timing tests

* Added LocalGrid tests

* Added LocalGridMaker tests

* fixing ci errors

* Added GlobalMap tests

* Added doc for EnvSensor

* Added Features2D tests

* Added Registration tests

* Added RegistrationVis tests

* Added doc for Rtabmap and Memory classes

* Added Memory and Rtabmap tests

* making some tests less flaky

* lcov 1.14 support

* updated compatible tool arguments

* Added integration tests (RGB-D, Stereo, Lidar2d, Lidar3d)

* More octomap checks

* Refactored how/when python interpretor is created to simplify library usage

* Added python tests

* fixed some flaky tests

* suppressed some third party related warnings

* fixed ceres tests

* more flaky fixes

* Fixing tests without libpointmatcher

* Added RANSAC rejection filter to PCL ICP

* fixing multi platform flakiness

* Added test to detect regression

* Fixing windows pcl link error

* fixed some macos flakiness

* bigger 2D2D registration error on opencv 4.6.0

* flakiness

* fixing flaky tests on windows and mac

* flaky thread test on slow mac VM

* windows slow test

* fixing more ci erros

* fxing temp dir on windows

* Added Optimizer tests and discovered some bugs (fixed)

* fixing flaky tests in mac and windows

* Added Optimizer doc

* Added GTSAM BA, updated Ceres to use g2o ba parameters. Renamed g2o's ba related parameters to Optimizer group and used by both gtsam and ceres.

* fixing build without gtsam

* fixing home dir

* fixing python ci isssues

* Added multicam ba tests

* Added Ceres multicam BA support

* Aligned BundleAdjustment parameters with Optimizer/Strategy to avoid confusion in the code

* Added BA integration test

* Added robust graph optimization integration test

* Added loop3it test

* Added stereo20Hz test

* Added smartfactor gtsam

* Fixed bugged check and warn if python didn't return any descriptors

* Fixing gtsam version build issues

* fixing tilt on windows ci

* loosing ceres integration test for ci

* mac ci flakiness

* updating missing param in gui

* updating test bound for mac

* added appearance-based tests, set min gftt quality to quality level

* testing more stuff

* improving features2d tests

* ci flakiness

* fixing flaky ci

* ci fixes

* flaky fixes

* Added RegistrationIcp tests

* Added icp integration test with real-worl corridor like env

* intermediate nodes

* fixing enum

* Updated test to catch #1714

* Fixed 2d corridor failing on pcl

* flaky pnp test

* flaky brisk test

* Set rtabmap_integration test as long

* updating loop closure test

* flaky ci tests

* TEsting roundtrip g2o/toro save/load

* loosing test bound

* fixed cuda capable checks

* flaky tests

* Debugging test hanging

* more debugging stuff

* updating limit

* windows: disabled cuda on ci to avoid incompatible driver issue. Fixing a bad test mem allocation

* trying fixing cuda hanging issue

* fixing ci flakyness

* flaky tests

* Updated BOW flaky tests by checking min precision/recall instead of recall@100precision. Fixed signature test

* CameraModel::load() test initRectificationMap param

* test dbdriver load dictionary idsOnly

* Memory: test keepLinkedInDb param

* added dummyDictionary tests

* test intermediate nodes count

* Added MarkerDetector tests

* reverted breaking change of UMutex and USemaphore

* Features2d: fixed compiltion warnings with clang about override

* clang warnings

* fixing test build with pcl 1.8

* g2o and gtsam build errors on android

* opencv5 test fixes

* disabled testing for ios and android builds

* normalized endline characters for easier diff

* added LF CRLF rule

* bump 0.23.10. fixing doc version

* Publish rtabmap website doc from ci

* fixing MSCVC build error

* macos icp flaky test

* fixing ceres macos test bound

* ficing more flaky tests

* fixing opencv5 related test errors. Also fixed an actual bug in ENU_WGS84ToGeocentric_WGS84()

* added comment about mrpt change

* removed rosdoc2 (will add it for rtabmap_ros later)

* fixing website style

* updated download links

* locally deployable website with api

* sweep doxygen issues

* improved/revised doxygen main pages

* removed examples empty page

* Updated doxygen style

* more concise doxygen groups

* added api link on main readme

* fixing utilite test error

* fixing CommonFilteringGroundNormalsUp test

* updated precisionRecall test bounds for Freak and brief descriptors

* fixing scale check in ba tests

* disabled tests on windows cuda build (missing dlls amd runner cannot test cuda anyway)

* ceres: missing suitesparse dep in windows ci

* adjusting recall thr for fast/freak

* ficing more flaky tests

* fixing flaky tests

* disabled coverage in ros ci

* Enable integration tests for ros ci jobs

* loosing up some threshold for failing tests

* trigger cache

* fixing test data in ros ci. Updated flaky test for mac

* slaking some test limit

* Fixed rtabmap-detectMoreLoopClosures inverted output value

* loosing up sift recall on mac

* optimizer re-ordered distribution for reproducible results (mac g2o)

* macos dump test crash log

* combining all tests to save time on shared library reload. Also fixed Logs with missing arguments.

* Added ENABLE_FORMAT_ERRORS cmake option

* do test only one time

* fixed all format warnings

* format security android build errors

* less verbose tests

* updated ImuUThread test

* fixed a log

* Fixed libpointmatcher 2d normals eigen issue

* Fixing libpointmatcher conversion issues

* fixing libpointmatcher test on windows ci

* cleanup comments, relax some test thr

* disabled sequoia-intel ci build (too flaky, would need extensive testing directly on that machine)
This commit is contained in:
matlabbe
2026-08-06 13:32:20 -07:00
committed by GitHub
parent bcdb4b4546
commit ee49beaf4f
309 changed files with 67468 additions and 3069 deletions
+158 -17
View File
@@ -302,7 +302,7 @@ void Feature2D::limitKeypoints(std::vector<cv::KeyPoint> & keypoints, std::vecto
cv::Mat descriptorsTmp;
if(ssc)
{
ULOGGER_DEBUG("too many words (%d), removing words with SSC", keypoints.size());
ULOGGER_DEBUG("too many words (%d), removing words with SSC", (int)keypoints.size());
// Sorting keypoints by deacreasing order of strength
std::vector<float> responseVector;
@@ -354,7 +354,7 @@ void Feature2D::limitKeypoints(std::vector<cv::KeyPoint> & keypoints, std::vecto
}
else
{
ULOGGER_DEBUG("too many words (%d), removing words with the hessian threshold", keypoints.size());
ULOGGER_DEBUG("too many words (%d), removing words with the hessian threshold", (int)keypoints.size());
// Remove words under the new hessian threshold
// Sort words by hessian
@@ -418,7 +418,7 @@ void Feature2D::limitKeypoints(const std::vector<cv::KeyPoint> & keypoints, std:
inliers.resize(keypoints.size(), false);
if(ssc)
{
ULOGGER_DEBUG("too many words (%d), removing words with SSC", keypoints.size());
ULOGGER_DEBUG("too many words (%d), removing words with SSC", (int)keypoints.size());
// Sorting keypoints by deacreasing order of strength
std::vector<float> responseVector;
@@ -445,7 +445,7 @@ void Feature2D::limitKeypoints(const std::vector<cv::KeyPoint> & keypoints, std:
}
else
{
ULOGGER_DEBUG("too much words (%d), removing words with the hessian threshold", keypoints.size());
ULOGGER_DEBUG("too much words (%d), removing words with the hessian threshold", (int)keypoints.size());
// Remove words under the new hessian threshold
// Sort words by hessian
@@ -465,7 +465,7 @@ void Feature2D::limitKeypoints(const std::vector<cv::KeyPoint> & keypoints, std:
minimumHessian = iter->first;
}
}
ULOGGER_DEBUG("%d keypoints removed, (kept %d), minimum response=%f", removed, keypoints.size()-removed, minimumHessian);
ULOGGER_DEBUG("%d keypoints removed, (kept %d), minimum response=%f", removed, (int)(keypoints.size()-removed), minimumHessian);
ULOGGER_DEBUG("filter keypoints time = %f s", timer.ticks());
}
else
@@ -613,6 +613,69 @@ Feature2D * Feature2D::create(const ParametersMap & parameters)
Parameters::parse(parameters, Parameters::kKpDetectorStrategy(), type);
return create((Feature2D::Type)type, parameters);
}
bool Feature2D::isAvailable(Feature2D::Type type)
{
// kFeatureUndef is a sentinel ("strategy not specified"); create() falls
// through to a default backend, so the type isn't really "available" as
// requested.
if(type == kFeatureUndef)
{
return false;
}
// SURF / SIFT / SURF-FREAK / SURF-DAISY require either OpenCV < 3.4.11
// (built-in) OR the xfeatures2d module + RTABMAP_NONFREE for OpenCV >= 3.4.11.
#if CV_MAJOR_VERSION < 3 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION <= 3) || (CV_MAJOR_VERSION == 3 && (CV_MINOR_VERSION < 4 || (CV_MINOR_VERSION==4 && CV_SUBMINOR_VERSION<11)))
#ifndef RTABMAP_NONFREE
if(type == kFeatureSurf || type == kFeatureSift || type == kFeatureSurfFreak || type == kFeatureSurfDaisy)
{
return false;
}
#endif
#else
#ifndef RTABMAP_NONFREE
if(type == kFeatureSurf || type == kFeatureSurfFreak || type == kFeatureSurfDaisy)
{
return false;
}
#endif
#endif
#if !defined(HAVE_OPENCV_XFEATURES2D) && CV_MAJOR_VERSION >= 3
if(type == kFeatureFastBrief ||
type == kFeatureFastFreak ||
type == kFeatureGfttBrief ||
type == kFeatureGfttFreak ||
type == kFeatureSurfFreak ||
type == kFeatureGfttDaisy ||
type == kFeatureSurfDaisy)
{
return false;
}
#elif CV_MAJOR_VERSION < 3
if(type == kFeatureKaze ||
type == kFeatureGfttDaisy ||
type == kFeatureSurfDaisy)
{
return false;
}
#endif
#ifndef RTABMAP_ORB_OCTREE
if(type == kFeatureOrbOctree) return false;
#endif
#ifndef RTABMAP_TORCH
if(type == kFeatureSuperPointTorch) return false;
#endif
#if !defined(RTABMAP_TORCH) || !defined(RTABMAP_PYTHON)
if(type == kFeatureSuperPointRpautrat) return false;
#endif
#ifndef RTABMAP_PYTHON
if(type == kFeaturePyDetector) return false;
#endif
return true;
}
Feature2D * Feature2D::create(Feature2D::Type type, const ParametersMap & parameters)
{
@@ -855,7 +918,7 @@ std::vector<cv::KeyPoint> Feature2D::generateKeypoints(const cv::Mat & image, co
}
}
UDEBUG("Keypoints extraction time = %f s, keypoints extracted = %d (grid=%dx%d, mask empty=%d)",
timer.ticks(), keypoints.size(), gridCols_, gridRows_, mask.empty()?1:0);
timer.ticks(), (int)keypoints.size(), gridCols_, gridRows_, mask.empty()?1:0);
if(keypoints.size() && _subPixWinSize > 0 && _subPixIterations > 0)
{
@@ -1147,13 +1210,13 @@ void SURF::parseParameters(const ParametersMap & parameters)
#ifdef RTABMAP_NONFREE
#if CV_MAJOR_VERSION < 3
if(gpuVersion_ && cv::gpu::getCudaEnabledDeviceCount() == 0)
if(gpuVersion_ && cv::gpu::getCudaEnabledDeviceCount() <= 0)
{
UWARN("GPU version of SURF not available! Using CPU version instead...");
gpuVersion_ = false;
}
#else
if(gpuVersion_ && cv::cuda::getCudaEnabledDeviceCount() == 0)
if(gpuVersion_ && cv::cuda::getCudaEnabledDeviceCount() <= 0)
{
UWARN("GPU version of SURF not available! Using CPU version instead...");
gpuVersion_ = false;
@@ -1176,6 +1239,19 @@ void SURF::parseParameters(const ParametersMap & parameters)
#endif
}
bool SURF::isGpuAvailable() const
{
#ifdef RTABMAP_NONFREE
#if CV_MAJOR_VERSION < 3
return cv::gpu::getCudaEnabledDeviceCount() > 0;
#else
return cv::cuda::getCudaEnabledDeviceCount() > 0;
#endif
#else
return false;
#endif
}
std::vector<cv::KeyPoint> SURF::generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi, const cv::Mat & mask)
{
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
@@ -1340,6 +1416,15 @@ void SIFT::parseParameters(const ParametersMap & parameters)
}
bool SIFT::isGpuAvailable() const
{
#ifdef RTABMAP_CUDASIFT
return cv::cuda::getCudaEnabledDeviceCount() > 0;
#else
return false;
#endif
}
std::vector<cv::KeyPoint> SIFT::generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi, const cv::Mat & mask)
{
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
@@ -1444,7 +1529,7 @@ std::vector<cv::KeyPoint> SIFT::generateKeypointsImpl(const cv::Mat & image, con
}
if(k < keypoints.size())
{
UDEBUG("keypoints extracted = %d, valid=%d", keypoints.size(), k);
UDEBUG("keypoints extracted = %d, valid=%d", (int)keypoints.size(), (int)k);
keypoints.resize(k);
cudaSiftDescriptors_.resize(k);
}
@@ -1564,7 +1649,7 @@ void ORB::parseParameters(const ParametersMap & parameters)
#if CV_MAJOR_VERSION < 3
#ifdef HAVE_OPENCV_GPU
if(gpu_ && cv::gpu::getCudaEnabledDeviceCount() == 0)
if(gpu_ && cv::gpu::getCudaEnabledDeviceCount() <= 0)
{
UWARN("GPU version of ORB not available! Using CPU version instead...");
gpu_ = false;
@@ -1584,7 +1669,7 @@ void ORB::parseParameters(const ParametersMap & parameters)
gpu_ = false;
}
#endif
if(gpu_ && cv::cuda::getCudaEnabledDeviceCount() == 0)
if(gpu_ && cv::cuda::getCudaEnabledDeviceCount() <= 0)
{
UWARN("GPU version of ORB not available (no GPU found)! Using CPU version instead...");
gpu_ = false;
@@ -1617,6 +1702,15 @@ void ORB::parseParameters(const ParametersMap & parameters)
}
}
bool ORB::isGpuAvailable() const
{
#ifdef HAVE_OPENCV_CUDAFEATURES2D
return cv::cuda::getCudaEnabledDeviceCount() > 0;
#else
return false;
#endif
}
std::vector<cv::KeyPoint> ORB::generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi, const cv::Mat & mask)
{
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
@@ -1811,7 +1905,7 @@ void FAST::parseParameters(const ParametersMap & parameters)
#if CV_MAJOR_VERSION < 3
#ifdef HAVE_OPENCV_GPU
if(gpu_ && cv::gpu::getCudaEnabledDeviceCount() == 0)
if(gpu_ && cv::gpu::getCudaEnabledDeviceCount() <= 0)
{
UWARN("GPU version of FAST not available! Using CPU version instead...");
gpu_ = false;
@@ -1825,7 +1919,7 @@ void FAST::parseParameters(const ParametersMap & parameters)
#endif
#else
#ifdef HAVE_OPENCV_CUDAFEATURES2D
if(gpu_ && cv::cuda::getCudaEnabledDeviceCount() == 0)
if(gpu_ && cv::cuda::getCudaEnabledDeviceCount() <= 0)
{
UWARN("GPU version of FAST not available! Using CPU version instead...");
gpu_ = false;
@@ -1881,6 +1975,12 @@ void FAST::parseParameters(const ParametersMap & parameters)
}
}
bool FAST::isGpuAvailable() const
{
// Not implemented
return false;
}
std::vector<cv::KeyPoint> FAST::generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi, const cv::Mat & mask)
{
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
@@ -2114,7 +2214,7 @@ void GFTT::parseParameters(const ParametersMap & parameters)
#endif
#ifdef HAVE_OPENCV_CUDAIMGPROC
if(_gpu && cv::cuda::getCudaEnabledDeviceCount() == 0)
if(_gpu && cv::cuda::getCudaEnabledDeviceCount() <= 0)
{
UWARN("GPU version of GFTT not available! Using CPU version instead...");
_gpu = false;
@@ -2144,6 +2244,15 @@ void GFTT::parseParameters(const ParametersMap & parameters)
}
}
bool GFTT::isGpuAvailable() const
{
#ifdef HAVE_OPENCV_CUDAIMGPROC
return cv::cuda::getCudaEnabledDeviceCount() > 0;
#else
return false;
#endif
}
std::vector<cv::KeyPoint> GFTT::generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi, const cv::Mat & mask)
{
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
@@ -2172,7 +2281,21 @@ std::vector<cv::KeyPoint> GFTT::generateKeypointsImpl(const cv::Mat & image, con
{
_gftt->detect(imgRoi, keypoints, maskRoi); // Opencv keypoints
}
if(!_useHarrisDetector && _qualityLevel>0.0)
{
std::vector<cv::KeyPoint> bestKeypoints;
bestKeypoints.reserve(keypoints.size());
for(size_t i=0; i<keypoints.size(); ++i)
{
if(keypoints[i].response > _qualityLevel)
{
bestKeypoints.push_back(keypoints[i]);
}
}
return bestKeypoints;
}
return keypoints;
}
@@ -2600,6 +2723,15 @@ SuperPointTorch::~SuperPointTorch()
{
}
bool SuperPointTorch::isGpuAvailable() const
{
#ifdef RTABMAP_TORCH
return torch::cuda::is_available();
#else
return false;
#endif
}
void SuperPointTorch::parseParameters(const ParametersMap & parameters)
{
Feature2D::parseParameters(parameters);
@@ -2634,7 +2766,7 @@ std::vector<cv::KeyPoint> SuperPointTorch::generateKeypointsImpl(const cv::Mat &
{
#ifdef RTABMAP_TORCH
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
if(roi.x!=0 || roi.y !=0)
if(roi.x!=0 || roi.y !=0 || roi.width!=image.cols || roi.height!=image.rows)
{
UERROR("SuperPoint: Not supporting ROI (%d,%d,%d,%d). Make sure %s, %s, %s, %s, %s, %s are all set to default values.",
roi.x, roi.y, roi.width, roi.height,
@@ -2708,6 +2840,15 @@ SuperPointRpautrat::~SuperPointRpautrat()
{
}
bool SuperPointRpautrat::isGpuAvailable() const
{
#if defined(RTABMAP_TORCH) && defined(RTABMAP_PYTHON)
return torch::cuda::is_available();
#else
return false;
#endif
}
void SuperPointRpautrat::parseParameters(const ParametersMap & parameters)
{
Feature2D::parseParameters(parameters);
@@ -2760,7 +2901,7 @@ std::vector<cv::KeyPoint> SuperPointRpautrat::generateKeypointsImpl(const cv::Ma
{
#if defined(RTABMAP_TORCH) && defined(RTABMAP_PYTHON)
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
if(roi.x!=0 || roi.y !=0)
if(roi.x!=0 || roi.y !=0 || roi.width!=image.cols || roi.height!=image.rows)
{
UERROR("SuperPoint Rpautrat: Not supporting ROI (%d,%d,%d,%d). Make sure %s, %s, %s, %s, %s, %s are all set to default values.",
roi.x, roi.y, roi.width, roi.height,