Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify the functional correspondence between the ORB_SLAM2 code and OpenVSLAM code and evaluate the similarities #239

Closed
ymd-stella opened this issue Dec 25, 2021 · 17 comments · Fixed by #252
Assignees

Comments

@ymd-stella
Copy link
Contributor

ymd-stella commented Dec 25, 2021

Continued from #37.

Extracted similar modules between ORB_SLAM2 and OpenVSLAM.

  • data modules
    • Frame - data::frame
    • KeyFrame - data::keyframe
    • MapPoint - data::landmark
    • Map - data::map_database
    • KeyFrameDatabase - data::bow_database
  • visualization modules
    • Viewer, MapDrawer, FrameDrawer - pangolin_viewer, publish::*
  • other modules
    • System - system, io::trajectory_io
    • Initializer - solve::*, initialize::*
    • Tracking - tracking_module, module::frame_tracker, module::keyframe_inserter, module::local_map_updater, module::relocalizer, module::initializer
    • LocalMapping - mapping_module, module::local_map_cleaner, module::two_view_triangulator
    • LoopClosing - global_optimization_module, module::loop_bundle_adjuster, module::loop_detector
    • Optimizer - optimize::*
    • ORBextractor - feature::*
    • ORBmatcher - match::*
    • PnPsolver - solve::pnp_solver
    • Sim3Solver - solve::sim3_solver

Based on these correspondences, similarity should be assessed by making comparisons at a appropriately abstract level. It is important to note that their creative expression may be limited by ideas. (Please refer Merger doctrine.)

In summary, under efficiency constraints, if different expressions are considered, they should be removed and rewritten from scratch.

@ymd-stella ymd-stella changed the title Clarify the functional correspondence between the ORB_SLAM2 code and OpenVSLAM code and evaluate the similarities (Please refer Merger doctrine) Clarify the functional correspondence between the ORB_SLAM2 code and OpenVSLAM code and evaluate the similarities Dec 25, 2021
@ymd-stella ymd-stella self-assigned this Jan 8, 2022
@ymd-stella ymd-stella added in progress help wanted Extra attention is needed labels Jan 8, 2022
@ymd-stella
Copy link
Contributor Author

ymd-stella commented Jan 9, 2022

Frame - data::frame

constructors

The natural order is from feature point extraction to stereo matching to grid assignment of feature points.
The suspects are as follows

  • There is no inevitability in the initialization timing of landmarks and outlier flags. However, they are similar.

Overall, the similarities are negligible.

AssignFeaturesToGrid in Frame - assign_keypoints_to_grid in common

It is related to

  • PosInGrid in Frame - get_cell_indices in common
  • GetFeaturesInArea in Frame - get_keypoints_in_cell in common

Overall, the order of processing is natural, and no similarities in expression were found.

ExtractORB in Frame - extract_orb in frame

There is a very unnatural similarity between the two. It is natural to simply implement extract_orb_left and extract_orb_right or use lambda expression. It needs to be removed.

SetPose in Frame - set_cam_pose in frame

It is related to

  • UpdatePoseMatrices in Frame - update_pose_params in frame

Overall, the order of processing was natural, and no similarities in expression were found.

isInFrustum in Frame - can_observe in frame

Considering the computational efficiency, the processing order looks natural. There is no similarity other than the order of processing.

ComputeBoW in Frame - compute_bow in frame

It is unnatural to return without doing anything when bow_vec_ is not empty. However, they are similar. It needs to be removed.

UndistortKeyPoints in Frame - compute_subpixel_disparity in camera::perspective

It's similar order of processing. However, the order of processing is natural. There are ways to avoid overwriting the result in mat, but this is the natural implementation from the perspective of memory efficiency.

ComputeImageBounds in Frame - compute_image_bounds in camera::perspective

No similarities in expression were found. (Off topic, but it is more natural to use Point2f instead of KeyPoint.)

ComputeStereoMatches in Frame - compute in matcher::stereo

matcher::stereo::compute calls

  • get_right_keypoint_indices_in_each_row
  • compute_subpixel_disparity
  • find_closest_keypoints_in_stereo

The same stereo matching algorithm is used. There are similarities, but I think it is due to the fact that they share the same algorithm.

ComputeStereoFromRGBD in Frame - compute_stereo_from_depth in frame

It is similar, but very simple and there is no other way to express it.

UnprojectStereo in Frame - triangulate_stereo in frame

It is similar, but very simple and there is no other way to express it.

@ymd-stella
Copy link
Contributor Author

ymd-stella commented Jan 10, 2022

KeyFrame - data::keyframe

constructors

The similarities are negligible.
It is a bit unnatural to generate a keyframe by copying the member variables of a frame. With some effort, it may be possible to make the keyframe have a reference to the frame.

ComputeBoW in KeyFrame - compute_bow in keyframe

It is unnatural to return without doing anything when bow_vec_ and bow_feat_vec_ is not empty. However, they are similar. It needs to be removed.

SetPose in KeyFrame - set_cam_pose in keyframe

There are similarities, but very simple and there is no other way to express it. Cw (Stereo middel point) exists only in ORB_SLAM2.

pose accessors

  • GetPose - get_cam_pose
  • GetPoseInverse - get_cam_pose_inv
  • GetCameraCenter - get_cam_center
  • GetRotation - get_rotation
  • GetTranslation - get_translation

There are similarities, but very simple and there is no other way to express it.

AddConnection, UpdateBestCovisibles in KeyFrame - add_connection, update_covisibility_orders in graph_node

The suspects are as follows

  • I'm curious about the fact that both release the mutex lock once. I have not been able to confirm the inevitability of this so far.

Overall, the similarities are negligible. However, I think it is natural to keep the mutex lock on during add_connection.

keyframe getters and related data structures

  • GetConnectedKeyFrames in KeyFrame - get_connected_keyframes in graph_node
  • GetVectorCovisibleKeyFrames in KeyFrame - get_covisibilities in graph_node
  • GetBestCovisibilityKeyFrames in KeyFrame - get_top_n_covisibilities in graph_node
  • GetCovisiblesByWeight in KeyFrame - get_covisibilities_over_weight in graph_node
  • GetWeight in KeyFrame - get_weight in graph_node

I'm curious about the similarity of ordered_covisibilities_ and ordered_weights_. It is natural to use std::vector<std::pair<unsigned int, std::weak_ptr<keyframe>>>> ordered_weights_and_covisibilities_. However, there may be a rationale for execution efficiency.

landmark accessors

setters

  • AddMapPoint in KeyFrame - add_landmark in keyframe
  • EraseMapPointMatch in KeyFrame - erase_landmark_with_index, erase_landmark in keyframe
  • ReplaceMapPointMatch in KeyFrame - replace_landmark in keyframe

There are similarities, but very simple and there is no other way to express it. (Off topic, in ORB_SLAM2, EraseMapPointMatch and ReplaceMapPointMatch are not mutex locked. Is this a bug?)

getters

  • GetMapPoints in KeyFrame - get_valid_landmarks in keyframe
  • TrackedMapPoints in KeyFrame - get_num_tracked_landmarks in keyframe
  • GetMapPointMatches in KeyFrame - get_landmarks in keyframe
  • GetMapPoint in KeyFrame - get_landmark in keyframe

There are similarities, but very simple and there is no other way to express it.

UpdateConnections in KeyFrame - update_connections in graph_node

There are similarities, but I think it is due to the fact that they share the same algorithm.

accessors for graph

  • AddChild in KeyFrame - add_spanning_child in keyframe
  • EraseChild in KeyFrame - erase_spanning_child in keyframe
  • ChangeParent in KeyFrame - change_spanning_parent in keyframe
  • GetChilds in KeyFrame - get_spanning_children in keyframe
  • GetParent in KeyFrame - get_spanning_parent in keyframe
  • hasChild in KeyFrame - get_spanning_parent in keyframe
  • AddLoopEdge in KeyFrame - add_loop_edge in keyframe
  • GetLoopEdges in KeyFrame - get_loop_edges in keyframe
  • EraseConnection in KeyFrame - get_loop_edges in keyframe

There are similarities, but very simple and there is no other way to express it.

Life Span Management

  • SetNotErase in KeyFrame - set_not_to_be_erased in keyframe
  • SetErase in KeyFrame - set_to_be_erased in keyframe
  • SetBadFlag in KeyFrame - prepare_for_erasing in keyframe?
  • isBad in KeyFrame - will_be_erased in keyframe?

The similarities are negligible.

GetFeaturesInArea in KeyFrame - get_keypoints_in_cell in common

The order of processing is natural, and no similarities in expression were found.

IsInImage in KeyFrame - reproject_to_image in perspective

The only similarity is in the last conditional expression, and there is no other way to express it.

UnprojectStereo in KeyFrame - triangulate_stereo in keyframe

There are similarities, but very simple and there is no other way to express it.

ComputeSceneMedianDepth in KeyFrame

There are similarities, but very simple and there is no other way to express it.

@ymd-stella
Copy link
Contributor Author

MapPoint - data::landmark

constructors

The similarities are negligible.

accessors

  • SetWorldPos in MapPoint - set_pos_in_world in landmark
  • GetWorldPos in MapPoint - get_pos_in_world in landmark
  • GetNormal in MapPoint - get_obs_mean_normal in landmark
  • GetReferenceKeyFrame in MapPoint - get_ref_keyframe in landmark
  • GetObservations in MapPoint - get_observations in landmark
  • Observations in MapPoint - num_observations in landmark
  • GetReplaced in MapPoint - get_replaced in landmark
  • IncreaseVisible in MapPoint - increase_num_observable in landmark
  • IncreaseFound in MapPoint - increase_num_observed in landmark
  • GetFoundRatio in MapPoint - get_observed_ratio in landmark
  • GetDescriptor in MapPoint - get_descriptor in landmark
  • GetIndexInKeyFrame in MapPoint - get_index_in_keyframe in landmark
  • IsInKeyFrame in MapPoint - is_observed_in_keyframe in landmark
  • GetMinDistanceInvariance in MapPoint - get_min_valid_distance in landmark
  • GetMaxDistanceInvariance in MapPoint - get_max_valid_distance in landmark

In SetWorldPos, mGlobalMutex is used. This is locked during pose optimization, which is not present in OpenVSLAM.

GetMinDistanceInvariance and get_min_valid_distance have different magic numbers, but the basis for both is unknown. The same is true for GetMaxDistanceInvariance and get_max_valid_distance.

There are similarities, but very simple and there is no other way to express it.

Life Span Management

  • SetBadFlag in MapPoint - prepare_for_erasing in landmark?
  • isBad in MapPoint - will_be_erased in landmark?

The similarities are negligible.

add, erase observation

  • AddObservation in MapPoint - add_observation in landmark
  • EraseObservation in MapPoint - erase_observation in landmark

There is a process to update the reference keyframe with the first observed keyframe. We could use any other keyframe in observations_, but I think the current process is the simplest. There was a comment that matched EraseObservation and erase_observation. There are similarities, but very simple and there is almost no other way to express it. It is better to rewrite the comment from scratch.

Replace in MapPoint - replace in landmark

There are similarities, but very simple and there is no other way to express it. The order of processing is natural.

ComputeDistinctiveDescriptors in MapPoint - compute_descriptor in landmark

ComputeDistinctiveDescriptors returns when vDescriptors is empty, while OpenVSLAM does not. The order of processing is natural. There are similarities, but I think it is due to the fact that they share the same algorithm.

UpdateNormalAndDepth in MapPoint - update_normal_and_depth in landmark

There are similarities, but very simple and there is no other way to express it. This naming is a bit unnatural for the description

https://github.com/OpenVSLAM-Community/openvslam/blob/aa1f04810b0dc5ba3f974d723df4f965492e3585/src/openvslam/data/landmark.h#L78-L79

PredictScalein MapPoint - predict_scale_level in landmark

It is unnatural to use overloading just to get log_scale_factor_ and num_scale_levels_. It needs to be removed.

@ymd-stella
Copy link
Contributor Author

Map - data::map_database

AddKeyFrame in Map - add_keyframe in map_database

The process using max_keyfrm_id_ is unnatural, and it is better to remove the process using max_keyfrm_id_.

add/erase keyframe/landmark

  • EraseKeyFrame in Map - erase_keyframe in map_database
  • AddMapPoint in Map - add_landmark in map_database
  • EraseMapPoint in Map - erase_landmark in map_database

It is similar, but very simple and there is no other way to express it.

InformNewBigChange, GetLastBigChangeIdx in Map - none?

No similar function was found.

accessors

  • SetReferenceMapPoints in Map - set_local_landmarks in map_database
  • GetReferenceMapPoints in Map - get_local_landmarks in map_database
  • GetAllKeyFrames in Map - get_all_keyframes in map_database
  • GetAllMapPoints in Map - get_all_landmarks in map_database
  • MapPointsInMap in Map - get_num_landmarks in map_database
  • KeyFramesInMap in Map - get_num_keyframes in map_database

It is similar, but very simple and there is no other way to express it.

GetMaxKFid in Map - get_max_keyframe_id in map_database

The process using max_keyfrm_id_ is unnatural, and it is better to remove the process using max_keyfrm_id_.

clear in Map - clear in map_database

The process of assigning nullptr is unnatural. It needs to be removed.
Other than that, it is very simple and there is no other way to describe it.

@ymd-stella
Copy link
Contributor Author

KeyFrameDatabase - data::bow_database

add, erase in KeyFrameDatabase - add_keyframe, erase_keyframe in bow_database

It is similar, but very simple and there is no other way to express it.

clear in KeyFrameDatabase - add_keyframe in bow_database

The similarities are negligible.

search

  • DetectLoopCandidates in KeyFrameDatabase - acquire_loop_candidates in bow_database
  • DetectRelocalizationCandidates in KeyFrameDatabase - acquire_relocalization_candidates in bow_database

There are similarities, but I think it is due to the fact that they share the same algorithm.

@ymd-stella
Copy link
Contributor Author

ymd-stella commented Jan 16, 2022

Viewer, MapDrawer, FrameDrawer - pangolin_viewer, publish::*

Overall, the similarities in code are negligible. However, I am concerned about the similarity in screen design. I am not sure if that is covered by GPLv3. The colors are just one of the customizable setting values, so I don't think there is a problem. It might be better to determine the default setting values specific to OpenVSLAM. The content displayed at the bottom of the frame is not very similar. As for the drawing of the overlay, it is too similar and would be better to redesign it. For OpenVSLAM, it is natural to separate the statistics and status from frame_publisher and create another publisher.

It is needed to change the default color scheme and remove the overlay text.

@ymd-stella
Copy link
Contributor Author

ymd-stella commented Jan 18, 2022

System - system, io::trajectory_io

constructor

The similarities are negligible. The necessity of displaying the copyright is unclear. It may be enough to provide a function like show_copyright_notice. For example, it will show the notice when the --lisence command line option is given.

Feed an image

  • TrackStereo in System - feed_stereo_frame in system
  • TrackRGBD in System - feed_RGBD_frame in system
  • TrackMonocular in System - feed_monocular_frame in system

The similarities are negligible, except for the handling of resets. Reset is explained in detail in the next section.

Reset in System - request_reset in system

Overall, the process for reset has some very unnatural similarities, and the functions related to request_reset need to be removed.

accessors for modes/state

  • ActivateLocalizationMode in System - enable_mapping_module in system
  • DeactivateLocalizationMode in System - disable_mapping_module in system
  • MapChanged in System - none

I think it is better to use std::future/std::promise to wait for the process to finish.

Shutdown in System - shutdown in system

I think it is better to use std::future/std::promise to wait for the process to finish. Overall, there is unnatural similarities in the process of sending a request and waiting for it to finish. These need to be removed.

Save trajectory

  • SaveTrajectoryTUM, SaveTrajectoryKITTI in System - save_frame_trajectory in system, save_frame_trajectory in io::trajectory_io
  • SaveKeyFrameTrajectoryTUM in System - save_keyframe_trajectory in system, save_keyframe_trajectory in io::trajectory_io

The similarities are negligible.

getters

  • GetTrackingState in System
  • GetTrackedMapPoints in System
  • GetTrackedKeyPointsUn in System

There is no similar getters. map_publisher provides landmarks, but in a completely different expression.

@ymd-stella
Copy link
Contributor Author

ymd-stella commented Jan 18, 2022

Initializer - solve::*, initialize::*

Initialize in Initializer - initialize in initialize::perspective

There are similarities, but it is due to the fact that they share the same algorithm.

RANSAC

  • FindHomography in Initializer - find_via_ransac in solve::homography_solver
  • FindFundamental in Initializer - find_via_ransac in solve::fundamental_solver

There are similarities, but it is due to the fact that they share the same algorithm.

ComputeH21 in Initializer - compute_H_21 in solve::homography_solver

There are a bit of similarities, but it is due to the fact that they share the same algorithm.
In OpenVSLAM, there is a link to https://www.uio.no/studier/emner/matnat/its/UNIK4690/v16/forelesninger/lecture_4_3-estimating-homographies-from-feature-correspondences.pdf.

ComputeF21 in Initializer - compute_F_21 in solve::fundamental_solver

There are a bit of similarities, but it is due to the fact that they share the same algorithm.

Check inlisers

  • CheckHomography in Initializer - check_inliers in solve::homography_solver
  • CheckFundamental in Initializer - check_inliers in solve::fundamental_solver

There are a bit of similarities, but it is due to the fact that they share the same algorithm.

Decompose

  • ReconstructF in Initializer - reconstruct_with_F in perspective, find_most_plausible_pose in initialize::base
  • ReconstructH in Initializer - reconstruct_with_H in perspective, decompose in solve::homography_solver, find_most_plausible_pose in initialize::base
  • DecomposeE in Initializer - decompose in solve::essential_solver

There are a bit of similarities, but it is due to the fact that they share the same algorithm.
In solve::homography_solver::decompose, there was a reference to "Motion and structure from motion in a piecewise planar environment (Faugeras et al. in IJPRAI 1988)".
In solve::essential_solver::decompose, there was a link to https://en.wikipedia.org/wiki/Essential_matrix#Determining_R_and_t_from_E.

Check pose

  • CheckRT in Initializer - check_pose in initialize::base
  • Triangulate in Initializer - triangulate in solve::triangulator

In OpenVSLAM, bearings are used instead of keypoints. There are a bit of similarities, but it is due to the fact that they share the same algorithm.

Normalize in Initializer - normalize in solve::common

There are a bit of similarities, but it is due to the fact that they share the same algorithm.

@ymd-stella
Copy link
Contributor Author

ymd-stella commented Jan 21, 2022

Tracking - tracking_module, module::frame_tracker, module::keyframe_inserter, module::local_map_updater, module::relocalizer, module::initializer

constructor

The similarities are negligible.

setters

  • SetLocalMapper in Tracking - set_mapping_module in tracking_module
  • SetLoopClosing in Tracking - set_global_optimization_module in tracking_module
  • SetViewer in Tracking - none

It is similar, but very simple and there is no other way to express it.

Feed an image

  • GrabImageStereo in Tracking - track_stereo_image in tracking_module
  • GrabImageRGBD in Tracking - track_RGBD_image in tracking_module
  • GrabImageMonocular in Tracking - track_monocular_image in tracking_module

Related functions are as follows:

  • util::convert_to_grayscale
  • util::convert_to_true_depth

There is a slight similarity. The frame is initialized in a different way for each camera configuration and passed to the common process. The similarity is due to the efficiency of the implementation. In monocular, the use of a feature point extractor for initialization is also similar, due to the fact that it is better to use more feature points to get better/stable results. Overall, no problematic similarities were found.

Initialization

  • StereoInitialization, MonocularInitialization in Tracking - initialize, try_initialize_for_stereo, create_initializer, try_initialize_for_monocular, create_map_for_stereo in initializer
  • CreateInitialMapMonocular - create_map_for_monocular, scale_map in initializer

There are similarities, but I think it is due to the fact that they share the same algorithm.

CheckReplacedInLastFrame in Tracking - apply_landmark_replace in tracking_module

It is similar, but very simple and there is no other way to express it.

Track in Tracking - track in tracking_module

The first few lines are similar, but the similarity after that is negligible. For example, only ORB-SLAM2 performs VO. It also has a conditional branch depending on whether mapping is enabled or disabled, and the fallback from TrackWithMotionModel to TrackReferenceKeyFrame is different. On the other hand, OpenVSLAM does almost the same thing regardless of whether mapping is enabled or disabled.
(Off topic, in OpenVSLAM, I don't think it is necessary to update_local_map after successful initialization.)

Tracking by reference keyframe or previous motion

  • TrackReferenceKeyFrame in Tracking - bow_match_based_track, discard_outliers in module::frame_tracker
  • TrackWithMotionModel in Tracking - motion_based_track, discard_outliers in module::frame_tracker

There are similarities, but very simple and there is no other way to express it. We will consider is_observable_in_tracking_ and identifier_in_local_lm_search_ in detail next(search_local_landmarks).

Search local landmarks

  • SearchLocalPoints in Tracking - search_local_landmarks in tracking_module

The following variables are temporary variables, but they are declared as member variables.
https://github.com/OpenVSLAM-Community/openvslam/blob/aa1f04810b0dc5ba3f974d723df4f965492e3585/src/openvslam/data/landmark.h#L114-L120
https://github.com/OpenVSLAM-Community/openvslam/blob/aa1f04810b0dc5ba3f974d723df4f965492e3585/src/openvslam/data/keyframe.h#L218
These are advantageous in terms of execution speed, but disadvantageous in terms of readability and memory efficiency. In view of this, it is better to use unordered_set. In the design philosophy of OpenVSLAM, it is unnatural to prioritize execution efficiency over readability. Therefore, we need to remove these member variables.

Update local map

  • UpdateLocalMap in Tracking - update_local_map in tracking_module
  • UpdateLocalPoints in Tracking - find_local_landmarks in module::local_map_updater
  • UpdateLocalKeyFrames in Tracking - find_local_keyframes in module::local_map_updater

There are similarities, but I think it is due to the fact that they share the same algorithm. We need to remove the member variables used as temporary variables described above.

TrackLocalMap in Tracking - optimize_current_frame_with_local_map in tracking_module

num_tracked_lms_ is a member variable that is used as a temporary variable and is unnaturally similar. num_tracked_lms_ needs to be removed.

UpdateLastFrame in Tracking - update_last_frame in tracking_module

The similarities are negligible.

Insert new keyframe

  • NeedNewKeyFrame in Tracking - new_keyframe_is_needed in tracking_module, new_keyframe_is_needed in keyframe_inserter
  • CreateNewKeyFrame in Tracking - insert_new_keyframe in tracking_module, insert_new_keyframe in keyframe_inserter

There are similarities, but I think it is due to the fact that they share the same algorithm.

Relocalization in Tracking - relocalize in module::relocalizer

There are a bit of similarities, but I think it is due to the fact that they share the similar algorithm.
The main difference is that OpenVSLAM processes each candidate one by one, while ORB-SLAM2 allocates computational resources to each candidate a little at a time.
(Off topic, In ORB-SLAM2, there are conditions under which outlier removal is not performed. This may be a bug.
https://github.com/raulmur/ORB_SLAM2/blob/f2e6f51cdc8d067655d90a78c06261378e07e8f3/src/Tracking.cc#L1456-L1460 )

Reset in Tracking - reset in tracking_module

Overall, the processes related to request_reset have some very unnatural similarities, and the functions related to request_reset need to be removed.

ChangeCalibration - none

No similar function was found.

InformOnlyTracking in Tracking - set_mapping_module_status in tracking_module

It is similar, but very simple and there is no other way to express it.

@ymd-stella
Copy link
Contributor Author

ymd-stella commented Jan 21, 2022

LocalMapping - mapping_module, module::local_map_cleaner, module::two_view_triangulator

setters

  • SetLoopCloser in LocalMapping - set_tracking_module in mapping_module
  • SetTracker in LocalMapping - set_global_optimization_module in mapping_module

It is similar, but very simple and there is no other way to express it.

Run in LocalMapping - run, mapping_with_new_keyframe in mapping_module

There are a bit of similarities, but I think it is due to the fact that they share the same algorithm. In OpenVSLAM, when this module receives a pause request, it processes all the keyframes of the queue.

ProcessNewKeyFrame in LocalMapping - store_new_keyframe in mapping_module

There are similarities, but very simple and there is no other way to express it.

CreateNewMapPoints in LocalMapping - create_new_landmarks, triangulate_with_two_keyframes in mapping_module

There are similarities, but I think it is due to the fact that they share the same algorithm. In OpenVSLAM, it is parallelized and extended for Equirectangular image (in two_view_triangulator::check_depth_is_positive).

SearchInNeighbors in LocalMapping - update_new_keyframe in mapping_module

There are similarities, but I think it is due to the fact that they share the same algorithm. ORB-SLAM2 uses temporary variables as described in "Search local landmarks", while OpenVSLAM uses unordered_set.

Keyframe queue

  • InsertKeyFrame in LocalMapping - queue_keyframe in mapping_module
  • CheckNewKeyFrames in LocalMapping - get_num_queued_keyframes in mapping_module

It is similar, but very simple and there is no other way to express it.

Remove reduncant landmarks/keyframes

  • MapPointCulling in LocalMapping - remove_redundant_landmarks in local_map_cleaner
  • KeyFrameCulling in LocalMapping - remove_redundant_keyframes, count_redundant_observations in local_map_cleaner

There are a bit of similarities, but I think it is due to the fact that they share the same algorithm.

ComputeF12 in LocalMapping - create_F_21 in solve::fundamental_solver

There are a bit of similarities, but very simple and there is no other way to express it.

keyframe acceptability

  • AcceptKeyFrames in LocalMapping - get_keyframe_acceptability in mapping_module
  • SetAcceptKeyFrames in LocalMapping - set_keyframe_acceptability in mapping_module

There are a bit of similarities, but very simple and there is no other way to express it. OpenVSLAM uses atomic, while ORB-SLAM2 uses mutex.

InterruptBA in LocalMapping - abort_local_BA in mapping_module

There are a bit of similarities, but very simple and there is no other way to express it. I'm a bit concerned that it doesn't have an exclusive lock.

Reset

  • RequestReset in LocalMapping - request_reset in mapping_module
  • ResetIfRequested in LocalMapping - reset, reset_is_requested in mapping_module

Overall, the processes related to request_reset have some very unnatural similarities, and the functions related to request_reset need to be removed.

Pause

  • RequestStop in LocalMapping - request_pause in mapping_module
  • Stop in LocalMapping - pause in mapping_module
  • isStopped in LocalMapping - is_paused in mapping_module
  • stopRequested in LocalMapping - pause_is_requested in mapping_module
  • SetNotStop in LocalMapping - set_force_to_run in mapping_module

There are similarities, but very simple and there is no other way to express it.

Release in LocalMapping - resume in mapping_module

There is a slightly unnatural similarity. There is no reason to clear the keyframe queue when resuming. At

https://github.com/OpenVSLAM-Community/openvslam/blob/aa1f04810b0dc5ba3f974d723df4f965492e3585/src/openvslam/mapping_module.cc#L82

I think we should lock mtx_keyfrm_queue_ and then pause and clear the queue. During pause, keyframe insertion is stopped, so no additional keyframes will be added to the queue. See https://github.com/OpenVSLAM-Community/openvslam/blob/aa1f04810b0dc5ba3f974d723df4f965492e3585/src/openvslam/module/keyframe_inserter.cc#L29-L31

The line needs to be removed. Then make the above changes in mapping_module::run.

Finish

  • RequestFinish in LocalMapping - request_terminate in mapping_module
  • CheckFinish in LocalMapping - terminate_is_requested in mapping_module
  • SetFinish in LocalMapping - terminate in mapping_module
  • isFinished in LocalMapping - is_terminated in mapping_module

It is similar, but very simple and there is no other way to express it.

@ymd-stella
Copy link
Contributor Author

ymd-stella commented Jan 22, 2022

LoopClosing - global_optimization_module, module::loop_bundle_adjuster, module::loop_detector

setters

  • SetTracker in LoopClosing - set_tracking_module in global_optimization_module
  • SetLocalMapper in LoopClosing - set_mapping_module in global_optimization_module

It is similar, but very simple and there is no other way to express it.

Run in LoopClosing - run in global_optimization_module

There are a bit of similarities, but very simple and there is no other way to express it.

Keyframe queue

  • InsertKeyFrame in LoopClosing - queue_keyframe in global_optimization_module
  • CheckNewKeyFrames in LoopClosing - keyframe_is_queued in global_optimization_module

It is similar, but very simple and there is no other way to express it. However, extra parentheses should be removed.

DetectLoop in LoopClosing - detect_loop_candidates, compute_min_score_in_covisibilities, find_continuously_detected_keyframe_sets in loop_detector

The repetition of bow_db_->add_keyframe(cur_keyfrm_); is unnaturally similar. it is a process that is done regardless of the result of detect_loop_candidates, so it can be merged into one. It needs to be removed. No other unnatural similarities were found.

ComputeSim3 in LoopClosing - validate_candidates, select_loop_candidate_via_Sim3 in loop_detector

In select_loop_candidate_via_Sim3, As with "Relocalization in Tracking - relocalize in module::relocalizer", the use of computational resources in RANSAC is different.

In validate_candidates, the process of allowing keyframes to be erased is repeated, but it can be merged into one. This is unnaturally similar. It needs to be removed. No other unnatural similarities were found.

CorrectLoop, RunGlobalBundleAdjustment, SearchAndFuse in LoopClosing - correct_loop, replace_duplicated_landmarks in global_optimization_module, optimize in loop_bundle_adjuster

The following variables are temporary variables, but they are declared as member variables.

https://github.com/OpenVSLAM-Community/openvslam/blob/aa1f04810b0dc5ba3f974d723df4f965492e3585/src/openvslam/data/keyframe.h#L223-L228

https://github.com/OpenVSLAM-Community/openvslam/blob/aa1f04810b0dc5ba3f974d723df4f965492e3585/src/openvslam/data/landmark.h#L123-L126

These are advantageous in terms of execution speed, but disadvantageous in terms of readability and memory efficiency. In view of this, it is better to use unordered_set. In the design philosophy of OpenVSLAM, it is unnatural to prioritize execution efficiency over readability. Therefore, we need to remove these member variables. No other unnatural similarities were found.

Reset

  • RequestReset in LoopClosing - request_reset in global_optimization_module
  • ResetIfRequested in LoopClosing - reset, reset_is_requested in global_optimization_module

Overall, the processes related to request_reset have some very unnatural similarities, and the functions related to request_reset need to be removed.

Finish

  • RequestFinish in LoopClosing - request_terminate in global_optimization_module
  • CheckFinish in LoopClosing - terminate_is_requested in global_optimization_module
  • SetFinish in LoopClosing - terminate in global_optimization_module
  • isFinished in LoopClosing - is_terminated in global_optimization_module

It is similar, but very simple and there is no other way to express it.

@ymd-stella
Copy link
Contributor Author

Optimizer - optimize::*

GlobalBundleAdjustemnt, BundleAdjustment in Optimizer - optimize in optimize::global_bundle_adjuster

The only unnatural similarity is the member variables used as temporary variables mentioned above.

I think x_right < 0 is correct for the following conditions. Even if you are using a stereo camera, it will be x_right < 0 in the point where the matching fails. This is a bug that exists only in OpenVSLAM.

https://github.com/OpenVSLAM-Community/openvslam/blob/aa1f04810b0dc5ba3f974d723df4f965492e3585/src/openvslam/optimize/global_bundle_adjuster.cc#L114

The same bug exists in local_bundle_adjuster and pose_optimizer.

https://github.com/OpenVSLAM-Community/openvslam/blob/aa1f04810b0dc5ba3f974d723df4f965492e3585/src/openvslam/optimize/local_bundle_adjuster.cc#L178

https://github.com/OpenVSLAM-Community/openvslam/blob/aa1f04810b0dc5ba3f974d723df4f965492e3585/src/openvslam/optimize/pose_optimizer.cc#L78

PoseOptimization in Optimizer - optimize in optimize::pose_optimizer

There are similarities, but I think it is due to the fact that they share the same algorithm/library(g2o).

LocalBundleAdjustment in Optimizer - optimize in optimize::local_bundle_adjuster

There are similarities, but I think it is due to the fact that they share the same algorithm/library(g2o). ORB-SLAM2 uses temporary variable mnBALocalForKF , while OpenVSLAM uses unordered_set. It's a matter of preference, but if (force_stop_flag && *force_stop_flag) { is preferable to if (force_stop_flag) { if (*force_stop_flag) {. I think the similarity is slightly unnatural.

OptimizeEssentialGraph in Optimizer - optimize in optimize::graph_optimizer

There are similarities, but I think it is due to the fact that they share the same algorithm/library(g2o).
The member variable loop_fusion_identifier_ and ref_keyfrm_id_in_loop_fusion_ used as temporary variables mentioned above.
(Off topic, The following lines are unnecessary because it will always be false.)

https://github.com/OpenVSLAM-Community/openvslam/blob/aa1f04810b0dc5ba3f974d723df4f965492e3585/src/openvslam/optimize/graph_optimizer.cc#L149-L152

(Off topic, The following lines are unnecessary.)

https://github.com/OpenVSLAM-Community/openvslam/blob/aa1f04810b0dc5ba3f974d723df4f965492e3585/src/openvslam/optimize/graph_optimizer.cc#L212-L214

OptimizeSim3 in Optimizer - optimize in optimize::transform_optimizer

There are similarities, but I think it is due to the fact that they share the same algorithm/library(g2o).

@ymd-stella
Copy link
Contributor Author

ymd-stella commented Jan 22, 2022

ORBextractor - feature::*

IC_Angle in ORBextractor - ic_angle in feature::orb_extractor

It is derived from opencv; it is unclear which opencv ORB-SLAM2 and OpenVSLAM are based on for their implementations, but I think it is incorrect that there is no indication of the BSD license, since the expression is almost unchanged. The license notation needs to be added.

constructor

Initialize the variables used by IC_Angle. I think this is a derivative of opencv as well as the above. The license notation needs to be added. No other unnatural similarities were found.

operator() in ORBextractor - extract, correct_keypoint_scale in feature::orb_extractor

This is based in part on the opencv process. Especially in ORB-SLAM2, some parts are copied almost without modification.

Compute descriptor

  • computeDescriptors in ORBextractor - compute_orb_descriptors in feature::orb_extractor
  • computeOrbDescriptor in ORBextractor - compute_orb_descriptor in feature::orb_extractor

In ORB-SLAM2, I think this is a derivative of opencv as well as the above. The implementation in OpenVSLAM looks unique.

ComputePyramid in ORBextractor - compute_image_pyramid in feature::orb_extractor

In ORB-SLAM2, I think this is a derivative of opencv as well as the above. The implementation in OpenVSLAM looks unique.

https://github.com/opencv/opencv/blob/82f8176b0634c5d744d1a45246244291d895b2d1/modules/features2d/src/orb.cpp#L766-L815

computeOrientation in ORBextractor - compute_orientation in feature::orb_extractor

It is similar, but very simple and there is no other way to express it.

DivideNode in ORBextractor - divide_node in feature::orb_extractor_node

There are a bit of similarities, but it is due to the fact that they share the same algorithm.

ComputeKeyPointsOctTree in ORBextractor - compute_fast_keypoints in feature::orb_extractor

There are similarities, but it is due to the fact that they share the same algorithm. In OpenVSLAM, masks can be set and are parallelized.

DistributeOctTree in ORBextractor - distribute_keypoints_via_tree, initialize_nodes, assign_child_nodes, find_keypoints_with_max_response in feature::orb_extractor

In OpenVSLAM, the process for portrait orientation images is different. There are a bit of similarities, but it is due to the fact that they share the same algorithm. In distribute_keypoints_via_tree, the sort result is unstable when the number of keypoints is the same.

https://github.com/OpenVSLAM-Community/openvslam/blob/aa1f04810b0dc5ba3f974d723df4f965492e3585/src/openvslam/feature/orb_extractor.cc#L454

@ymd-stella
Copy link
Contributor Author

The following points were made by AlejandroSilvestri (#249 (comment))

  • The first obvious step in the process is to extract ORB descriptors from the image. Both ORB-SLAM2 and OpenVSLAM walk the same strange path before doing so (under different names):
    • SLAM.feed_monocular_frame(im)
    • tracker_->track_monocular_image(im)
    • new frame(im), where the image is finally processed
  • the Frame class process the image in its constructor: this is a very arbitrary and odd programming decision, the same in both projects, and it's not the obvious or self-evident way to do things
  • track_monocular_image() constructs frame() in one of two different ways, depending on whether they are in initialization or tracking
  • the main sequencer finite state machine is located in tracker, and is the same in both projects
  • FAST keypoints are filtered by OctTree or QuadTree (same process, different name), when it is neither the most obvious nor the best way to do it
  • The first obvious step in the process is to extract ORB descriptors from the image. Both ORB-SLAM2 and OpenVSLAM walk the same strange path before doing so (under different names)

I think this is considered a strange similarity because, for example, an image can also be converted in the system class and input to the tracking_module. We can't prove that the current structure is optimal in terms of readability or efficiency; we need to input an image or a preprocessed frame into tracking_module, but we need to determine when to do so based on our own policy.

One policy to solve this is to minimize the number of unnecessary functions for readability: if we generate frames in system, we can reduce the number of functions.

  • the Frame class process the image in its constructor: this is a very arbitrary and odd programming decision, the same in both projects, and it's not the obvious or self-evident way to do things

It is helpful to see how ProSLAM is implemented.

https://github.com/AhmedShaban94/ProSLAM/tree/master/src/framepoint_generation

Currently, the cohesion is too low. It is unnatural to adopt such a design as is in OpenVSLAM, which is intended to be readable.

  • track_monocular_image() constructs frame() in one of two different ways, depending on whether they are in initialization or tracking
  • the main sequencer finite state machine is located in tracker, and is the same in both projects

I'll have to think about it in detail, but I think it's possible to have tracking_module return the result of initialization or tracking to system, and system manage the state and call different functions of tracking_module. From a readability point of view, we should choose a better way with OpenVSLAM.

  • FAST keypoints are filtered by OctTree or QuadTree (same process, different name), when it is neither the most obvious nor the best way to do it

If there is a more appropriate algorithm for OpenVSLAM, I think it should be chosen. I have not been able to find one yet.

@ymd-stella
Copy link
Contributor Author

ymd-stella commented Jan 23, 2022

ORBmatcher - match::*

projection

  • SearchByProjection(Frame, MapPoints) in ORBmatcher - match_frame_and_landmarks in match::projection
  • SearchByProjection(KeyFrame, Sim3, MapPoints) in ORBmatcher - match_by_Sim3_transform in match::projection
  • SearchByProjection(Frame1, Frame2) in ORBmatcher - match_current_and_last_frames in match::projection
  • SearchByProjection(Frame, Keyframe) in ORBmatcher - match_frame_and_keyframe in match::projection
  • SearchBySim3 in ORBmatcher - match_keyframes_mutually in match::projection

There are similarities, but I think it is due to the fact that they share the same algorithm. However, I am concerned that there is duplicate code in both. For example, the following code. It should fix duplicated sections of code.

https://github.com/OpenVSLAM-Community/openvslam/blob/aa1f04810b0dc5ba3f974d723df4f965492e3585/src/openvslam/match/projection.cc#L138-L152

BoW

  • SearchByBoW(KeyFrame, Frame) in ORBmatcher - match_frame_and_keyframe in match::bow_tree
  • SearchByBoW(Keyframe1, Keyframe2) in ORBmatcher - match_keyframes in match::bow_tree

There are similarities, but I think it is due to the fact that they share the similar algorithm. match_keyframes in OpenVSLAM skips the comparison with matched keypoints.

SearchForInitialization in ORBmatcher - match_in_consistent_area in match::area

There are similarities, but I think it is due to the fact that they share the same algorithm.

SearchForTriangulation, CheckDistEpipolarLine in ORBmatcher - match_for_triangulation, check_epipolar_constraint in match::robust

There are similarities, but I think it is due to the fact that they share the similar algorithm. The similarity between CheckDistEpipolarLine and check_epipolar_constraint is negligible. The following statements are unique to OpenVSLAM.

https://github.com/OpenVSLAM-Community/openvslam/blob/aa1f04810b0dc5ba3f974d723df4f965492e3585/src/openvslam/match/robust.cc#L109-L119

fuse

  • Fuse(Keyframe, MapPoints) in ORBmatcher - replace_duplication in match::fuse
  • Fuse(Keyframe, Sim3, MapPoints) in ORBmatcher - detect_duplication in match::fuse

There are similarities, but I think it is due to the fact that they share the similar algorithm.

ComputeThreeMaxima in ORBmatcher - get_valid_matches in angle_checker

The algorithm has been changed to be more flexible.

DescriptorDistance in ORBmatcher - compute_descriptor_distance_32 in match::base

Both refer to the same link. It is similar, but very simple and there is no other way to express it. There is a 64-bit version in OpenVSLAM.

@ymd-stella
Copy link
Contributor Author

PnPsolver - solve::pnp_solver

I'll skip the EPnP part; I compared it to https://github.com/cvlab-epfl/EPnP. It looked like it was created from scratch.

constructor and SetRansacParameters

The similarities are negligible.

iterate in PnPsolver - find_via_ransac in solve::pnp_solver

There are a bit of similarities, but it is due to the fact that they share the same algorithm.

@ymd-stella
Copy link
Contributor Author

Sim3Solver - solve::sim3_solver

constructor and SetRansacParameters

It calls the following.

  • FromCameraToImage in Sim3Solver - reproject_to_other_image in solve::sim3_solver

There are similarities, but it is due to the fact that they share the same algorithm.

iterate in Sim3Solver - find_via_ransac in solve::sim3_solver

There are a bit of similarities, but it is due to the fact that they share the same algorithm.

ComputeSim3, ComputeCentroid, CheckInliers, Project in Sim3Solver - compute_Sim3, count_inliers, reproject_to_other_image in solve::sim3_solver

There are a bit of similarities, but it is due to the fact that they share the same algorithm.

@ymd-stella ymd-stella linked a pull request Jan 29, 2022 that will close this issue
@ymd-stella ymd-stella removed help wanted Extra attention is needed in progress labels Feb 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant