merge the newest code from author
parent
43c195710b
commit
feedb9bdd8
|
@ -1,6 +1,6 @@
|
||||||
CMakeLists.txt.user
|
CMakeLists.txt.user
|
||||||
CMakeLists_modified.txt
|
CMakeLists_modified.txt
|
||||||
Examples/
|
|
||||||
Examples/RGB-D/rgbd_tum
|
Examples/RGB-D/rgbd_tum
|
||||||
|
|
||||||
Examples/Monocular/mono_euroc
|
Examples/Monocular/mono_euroc
|
||||||
|
@ -47,7 +47,3 @@ cmake-build-debug/
|
||||||
|
|
||||||
*.pyc
|
*.pyc
|
||||||
*.osa
|
*.osa
|
||||||
|
|
||||||
.vscode/
|
|
||||||
CMakeLists.txt
|
|
||||||
build.sh
|
|
||||||
|
|
|
@ -4,16 +4,16 @@ project(ORB_SLAM3)
|
||||||
IF(NOT CMAKE_BUILD_TYPE)
|
IF(NOT CMAKE_BUILD_TYPE)
|
||||||
SET(CMAKE_BUILD_TYPE Release)
|
SET(CMAKE_BUILD_TYPE Release)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
# set(CMAKE_BUILD_TYPE "Debug")
|
|
||||||
MESSAGE("Build type: " ${CMAKE_BUILD_TYPE})
|
MESSAGE("Build type: " ${CMAKE_BUILD_TYPE})
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O3")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O3")
|
||||||
# set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -march=native")
|
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -march=native")
|
||||||
# set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -march=native")
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -march=native")
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-deprecated -O3 -march=native ")
|
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-deprecated -O3 -march=native ")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-deprecated -O3 -march=native")
|
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-deprecated -O3 -march=native")
|
||||||
|
|
||||||
# Check C++11 or C++0x support
|
# Check C++11 or C++0x support
|
||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
|
@ -33,11 +33,11 @@ endif()
|
||||||
|
|
||||||
LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)
|
LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)
|
||||||
|
|
||||||
find_package(OpenCV 3)
|
find_package(OpenCV 4.0)
|
||||||
if(NOT OpenCV_FOUND)
|
if(NOT OpenCV_FOUND)
|
||||||
find_package(OpenCV 2.4.3 QUIET)
|
find_package(OpenCV 3.0)
|
||||||
if(NOT OpenCV_FOUND)
|
if(NOT OpenCV_FOUND)
|
||||||
message(FATAL_ERROR "OpenCV > 2.4.3 not found.")
|
message(FATAL_ERROR "OpenCV > 3.0 not found.")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@ MESSAGE(${OpenCV_VERSION})
|
||||||
|
|
||||||
find_package(Eigen3 3.1.0 REQUIRED)
|
find_package(Eigen3 3.1.0 REQUIRED)
|
||||||
find_package(Pangolin REQUIRED)
|
find_package(Pangolin REQUIRED)
|
||||||
|
find_package(realsense2)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${PROJECT_SOURCE_DIR}
|
${PROJECT_SOURCE_DIR}
|
||||||
|
@ -72,7 +73,6 @@ src/Atlas.cc
|
||||||
src/Map.cc
|
src/Map.cc
|
||||||
src/MapDrawer.cc
|
src/MapDrawer.cc
|
||||||
src/Optimizer.cc
|
src/Optimizer.cc
|
||||||
src/PnPsolver.cc
|
|
||||||
src/Frame.cc
|
src/Frame.cc
|
||||||
src/KeyFrameDatabase.cc
|
src/KeyFrameDatabase.cc
|
||||||
src/Sim3Solver.cc
|
src/Sim3Solver.cc
|
||||||
|
@ -84,6 +84,7 @@ src/CameraModels/Pinhole.cpp
|
||||||
src/CameraModels/KannalaBrandt8.cpp
|
src/CameraModels/KannalaBrandt8.cpp
|
||||||
src/OptimizableTypes.cpp
|
src/OptimizableTypes.cpp
|
||||||
src/MLPnPsolver.cpp
|
src/MLPnPsolver.cpp
|
||||||
|
src/TwoViewReconstruction.cc
|
||||||
include/System.h
|
include/System.h
|
||||||
include/Tracking.h
|
include/Tracking.h
|
||||||
include/LocalMapping.h
|
include/LocalMapping.h
|
||||||
|
@ -98,7 +99,6 @@ include/Atlas.h
|
||||||
include/Map.h
|
include/Map.h
|
||||||
include/MapDrawer.h
|
include/MapDrawer.h
|
||||||
include/Optimizer.h
|
include/Optimizer.h
|
||||||
include/PnPsolver.h
|
|
||||||
include/Frame.h
|
include/Frame.h
|
||||||
include/KeyFrameDatabase.h
|
include/KeyFrameDatabase.h
|
||||||
include/Sim3Solver.h
|
include/Sim3Solver.h
|
||||||
|
@ -112,7 +112,8 @@ include/CameraModels/KannalaBrandt8.h
|
||||||
include/OptimizableTypes.h
|
include/OptimizableTypes.h
|
||||||
include/MLPnPsolver.h
|
include/MLPnPsolver.h
|
||||||
include/TwoViewReconstruction.h
|
include/TwoViewReconstruction.h
|
||||||
src/TwoViewReconstruction.cc)
|
include/Config.h
|
||||||
|
)
|
||||||
|
|
||||||
add_subdirectory(Thirdparty/g2o)
|
add_subdirectory(Thirdparty/g2o)
|
||||||
|
|
||||||
|
@ -127,14 +128,17 @@ ${PROJECT_SOURCE_DIR}/Thirdparty/g2o/lib/libg2o.so
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# Build examples
|
### Build examples
|
||||||
|
|
||||||
|
# RGB-D examples
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/Examples/RGB-D)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/Examples/RGB-D)
|
||||||
|
|
||||||
add_executable(rgbd_tum
|
add_executable(rgbd_tum
|
||||||
Examples/RGB-D/rgbd_tum.cc)
|
Examples/RGB-D/rgbd_tum.cc)
|
||||||
target_link_libraries(rgbd_tum ${PROJECT_NAME})
|
target_link_libraries(rgbd_tum ${PROJECT_NAME})
|
||||||
|
|
||||||
|
|
||||||
|
# Stereo examples
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/Examples/Stereo)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/Examples/Stereo)
|
||||||
|
|
||||||
add_executable(stereo_kitti
|
add_executable(stereo_kitti
|
||||||
|
@ -149,7 +153,7 @@ add_executable(stereo_tum_vi
|
||||||
Examples/Stereo/stereo_tum_vi.cc)
|
Examples/Stereo/stereo_tum_vi.cc)
|
||||||
target_link_libraries(stereo_tum_vi ${PROJECT_NAME})
|
target_link_libraries(stereo_tum_vi ${PROJECT_NAME})
|
||||||
|
|
||||||
|
# Monocular examples
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/Examples/Monocular)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/Examples/Monocular)
|
||||||
|
|
||||||
add_executable(mono_tum
|
add_executable(mono_tum
|
||||||
|
@ -168,7 +172,7 @@ add_executable(mono_tum_vi
|
||||||
Examples/Monocular/mono_tum_vi.cc)
|
Examples/Monocular/mono_tum_vi.cc)
|
||||||
target_link_libraries(mono_tum_vi ${PROJECT_NAME})
|
target_link_libraries(mono_tum_vi ${PROJECT_NAME})
|
||||||
|
|
||||||
|
# Monocular-Inertial examples
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/Examples/Monocular-Inertial)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/Examples/Monocular-Inertial)
|
||||||
|
|
||||||
add_executable(mono_inertial_euroc
|
add_executable(mono_inertial_euroc
|
||||||
|
@ -179,16 +183,14 @@ add_executable(mono_inertial_tum_vi
|
||||||
Examples/Monocular-Inertial/mono_inertial_tum_vi.cc)
|
Examples/Monocular-Inertial/mono_inertial_tum_vi.cc)
|
||||||
target_link_libraries(mono_inertial_tum_vi ${PROJECT_NAME})
|
target_link_libraries(mono_inertial_tum_vi ${PROJECT_NAME})
|
||||||
|
|
||||||
|
# Stereo-Inertial examples
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/Examples/Stereo-Inertial)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/Examples/Stereo-Inertial)
|
||||||
|
|
||||||
add_executable(stereo_inertial_euroc
|
add_executable(stereo_inertial_euroc
|
||||||
Examples/Stereo-Inertial/stereo_inertial_euroc.cc)
|
Examples/Stereo-Inertial/stereo_inertial_euroc.cc)
|
||||||
target_link_libraries(stereo_inertial_euroc ${PROJECT_NAME})
|
target_link_libraries(stereo_inertial_euroc ${PROJECT_NAME})
|
||||||
|
|
||||||
|
|
||||||
add_executable(stereo_inertial_tum_vi
|
add_executable(stereo_inertial_tum_vi
|
||||||
Examples/Stereo-Inertial/stereo_inertial_tum_vi.cc)
|
Examples/Stereo-Inertial/stereo_inertial_tum_vi.cc)
|
||||||
target_link_libraries(stereo_inertial_tum_vi ${PROJECT_NAME})
|
target_link_libraries(stereo_inertial_tum_vi ${PROJECT_NAME})
|
||||||
|
|
||||||
|
|
||||||
|
|
21
Changelog.md
21
Changelog.md
|
@ -1,15 +1,26 @@
|
||||||
# ORB-SLAM3
|
# ORB-SLAM3
|
||||||
Details of changes between the different versions.
|
Details of changes between the different versions.
|
||||||
|
|
||||||
|
### V0.4: Beta version, 21 April 2021
|
||||||
|
|
||||||
|
- Changed OpenCV dynamic matrices to static matrices to speed up the code.
|
||||||
|
|
||||||
|
- Capability to measure running time of the system threads.
|
||||||
|
|
||||||
|
- Compatibility with OpenCV 4.0 (Requires at least OpenCV 3.0)
|
||||||
|
|
||||||
|
- Fixed minor bugs.
|
||||||
|
|
||||||
|
|
||||||
### V0.3: Beta version, 4 Sep 2020
|
### V0.3: Beta version, 4 Sep 2020
|
||||||
|
|
||||||
- RGB-D compatibility, the RGB-D examples had been adapted to the new version.
|
- RGB-D compatibility, the RGB-D examples have been adapted to the new version.
|
||||||
|
|
||||||
- Kitti and TUM dataset compatibility, these examples had been adapted to the new version.
|
- Kitti and TUM dataset compatibility, these examples have been adapted to the new version.
|
||||||
|
|
||||||
- ROS compatibility, It had been updated the old references in the code to work with this version.
|
- ROS compatibility, updated the old references in the code to work with this version.
|
||||||
|
|
||||||
- Config file parser, the YAML file contains the session configuration, a wrong parametrization may break the execution without any information to solve it. This version parses the file to read all the fields and give a proper answer if one of the fields have been wrong deffined or don't exist.
|
- Config file parser, the YAML file contains the session configuration, a wrong parametrization may break the execution without any information to solve it. This version parses the file to read all the fields and give a proper answer if one of the fields have been wrongly deffined or does not exist.
|
||||||
|
|
||||||
- Fixed minor bugs.
|
- Fixed minor bugs.
|
||||||
|
|
||||||
|
@ -19,7 +30,7 @@ Initial release. It has these capabilities:
|
||||||
|
|
||||||
- Multiple-Maps capabilities, it is able to handle multiple maps in the same session and merge them when a common area is detected with a seamless fussion.
|
- Multiple-Maps capabilities, it is able to handle multiple maps in the same session and merge them when a common area is detected with a seamless fussion.
|
||||||
|
|
||||||
- Inertial sensor, the IMU initialization takes a 2 seconds to achieve a scale error less than 5\% and it is reffined in the next 10 seconds until is around 1\%. Inertial measures are integrated at frame rate to estimate the scale, gravity and velocity in order to improve the visual features detection and make the system robust to temporal occlusions.
|
- Inertial sensor, the IMU initialization takes 2 seconds to achieve a scale error less than 5\% and it is reffined in the next 10 seconds until it is around 1\%. Inertial measures are integrated at frame rate to estimate the scale, gravity and velocity in order to improve the visual features detection and make the system robust to temporal occlusions.
|
||||||
|
|
||||||
- Fisheye sensor, the fisheye sensors are now fully supported in monocular and stereo.
|
- Fisheye sensor, the fisheye sensors are now fully supported in monocular and stereo.
|
||||||
|
|
||||||
|
|
|
@ -116,25 +116,19 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
cout.precision(17);
|
cout.precision(17);
|
||||||
|
|
||||||
/*cout << "Start processing sequence ..." << endl;
|
|
||||||
cout << "Images in the sequence: " << nImages << endl;
|
|
||||||
cout << "IMU data in the sequence: " << nImu << endl << endl;*/
|
|
||||||
|
|
||||||
// Create SLAM system. It initializes all system threads and gets ready to process frames.
|
// Create SLAM system. It initializes all system threads and gets ready to process frames.
|
||||||
ORB_SLAM3::System SLAM(argv[1],argv[2],ORB_SLAM3::System::IMU_MONOCULAR, true);
|
ORB_SLAM3::System SLAM(argv[1],argv[2],ORB_SLAM3::System::IMU_MONOCULAR, true);
|
||||||
|
|
||||||
int proccIm=0;
|
int proccIm=0;
|
||||||
for (seq = 0; seq<num_seq; seq++)
|
for (seq = 0; seq<num_seq; seq++)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Main loop
|
|
||||||
cv::Mat im;
|
cv::Mat im;
|
||||||
vector<ORB_SLAM3::IMU::Point> vImuMeas;
|
vector<ORB_SLAM3::IMU::Point> vImuMeas;
|
||||||
proccIm = 0;
|
proccIm = 0;
|
||||||
for(int ni=0; ni<nImages[seq]; ni++, proccIm++)
|
for(int ni=0; ni<nImages[seq]; ni++, proccIm++)
|
||||||
{
|
{
|
||||||
// Read image from file
|
// Read image from file
|
||||||
im = cv::imread(vstrImageFilenames[seq][ni],CV_LOAD_IMAGE_UNCHANGED);
|
im = cv::imread(vstrImageFilenames[seq][ni],cv::IMREAD_UNCHANGED);
|
||||||
|
|
||||||
double tframe = vTimestampsCam[seq][ni];
|
double tframe = vTimestampsCam[seq][ni];
|
||||||
|
|
||||||
|
@ -150,8 +144,6 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if(ni>0)
|
if(ni>0)
|
||||||
{
|
{
|
||||||
// cout << "t_cam " << tframe << endl;
|
|
||||||
|
|
||||||
while(vTimestampsImu[seq][first_imu[seq]]<=vTimestampsCam[seq][ni])
|
while(vTimestampsImu[seq][first_imu[seq]]<=vTimestampsCam[seq][ni])
|
||||||
{
|
{
|
||||||
vImuMeas.push_back(ORB_SLAM3::IMU::Point(vAcc[seq][first_imu[seq]].x,vAcc[seq][first_imu[seq]].y,vAcc[seq][first_imu[seq]].z,
|
vImuMeas.push_back(ORB_SLAM3::IMU::Point(vAcc[seq][first_imu[seq]].x,vAcc[seq][first_imu[seq]].y,vAcc[seq][first_imu[seq]].z,
|
||||||
|
@ -161,9 +153,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*cout << "first imu: " << first_imu << endl;
|
|
||||||
cout << "first imu time: " << fixed << vTimestampsImu[first_imu] << endl;
|
|
||||||
cout << "size vImu: " << vImuMeas.size() << endl;*/
|
|
||||||
#ifdef COMPILEDWITHC11
|
#ifdef COMPILEDWITHC11
|
||||||
std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
|
std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
|
||||||
#else
|
#else
|
||||||
|
@ -171,8 +161,7 @@ int main(int argc, char *argv[])
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Pass the image to the SLAM system
|
// Pass the image to the SLAM system
|
||||||
// cout << "tframe = " << tframe << endl;
|
SLAM.TrackMonocular(im,tframe,vImuMeas);
|
||||||
SLAM.TrackMonocular(im,tframe,vImuMeas); // TODO change to monocular_inertial
|
|
||||||
|
|
||||||
#ifdef COMPILEDWITHC11
|
#ifdef COMPILEDWITHC11
|
||||||
std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();
|
std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();
|
||||||
|
@ -180,9 +169,13 @@ int main(int argc, char *argv[])
|
||||||
std::chrono::monotonic_clock::time_point t2 = std::chrono::monotonic_clock::now();
|
std::chrono::monotonic_clock::time_point t2 = std::chrono::monotonic_clock::now();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
double t_track = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t2 - t1).count();
|
||||||
|
SLAM.InsertTrackTime(t_track);
|
||||||
|
#endif
|
||||||
|
|
||||||
double ttrack= std::chrono::duration_cast<std::chrono::duration<double> >(t2 - t1).count();
|
double ttrack= std::chrono::duration_cast<std::chrono::duration<double> >(t2 - t1).count();
|
||||||
ttrack_tot += ttrack;
|
ttrack_tot += ttrack;
|
||||||
// std::cout << "ttrack: " << ttrack << std::endl;
|
|
||||||
|
|
||||||
vTimesTrack[ni]=ttrack;
|
vTimesTrack[ni]=ttrack;
|
||||||
|
|
||||||
|
@ -194,7 +187,7 @@ int main(int argc, char *argv[])
|
||||||
T = tframe-vTimestampsCam[seq][ni-1];
|
T = tframe-vTimestampsCam[seq][ni-1];
|
||||||
|
|
||||||
if(ttrack<T)
|
if(ttrack<T)
|
||||||
usleep((T-ttrack)*1e6); // 1e6
|
usleep((T-ttrack)*1e6);
|
||||||
}
|
}
|
||||||
if(seq < num_seq - 1)
|
if(seq < num_seq - 1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -105,7 +105,6 @@ int main(int argc, char **argv)
|
||||||
// Step 3 默认IMU数据早于图像数据记录,找到和第一帧图像时间戳最接近的imu时间戳索引,记录在first_imu[seq]中
|
// Step 3 默认IMU数据早于图像数据记录,找到和第一帧图像时间戳最接近的imu时间戳索引,记录在first_imu[seq]中
|
||||||
while(vTimestampsImu[seq][first_imu[seq]]<=vTimestampsCam[seq][0]){
|
while(vTimestampsImu[seq][first_imu[seq]]<=vTimestampsCam[seq][0]){
|
||||||
first_imu[seq]++;
|
first_imu[seq]++;
|
||||||
cout << "first_imu[seq] = " << first_imu[seq] << endl;
|
|
||||||
}
|
}
|
||||||
// 因为上面退出while循环时IMU时间戳刚刚超过图像时间戳,所以这里需要再减一个索引
|
// 因为上面退出while循环时IMU时间戳刚刚超过图像时间戳,所以这里需要再减一个索引
|
||||||
first_imu[seq]--; // first imu measurement to be considered
|
first_imu[seq]--; // first imu measurement to be considered
|
||||||
|
|
|
@ -91,7 +91,7 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Read image from file
|
// Read image from file
|
||||||
im = cv::imread(vstrImageFilenames[seq][ni],CV_LOAD_IMAGE_UNCHANGED);
|
im = cv::imread(vstrImageFilenames[seq][ni],cv::IMREAD_UNCHANGED);
|
||||||
double tframe = vTimestampsCam[seq][ni];
|
double tframe = vTimestampsCam[seq][ni];
|
||||||
|
|
||||||
if(im.empty())
|
if(im.empty())
|
||||||
|
@ -108,8 +108,7 @@ int main(int argc, char **argv)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Pass the image to the SLAM system
|
// Pass the image to the SLAM system
|
||||||
// cout << "tframe = " << tframe << endl;
|
SLAM.TrackMonocular(im,tframe);
|
||||||
SLAM.TrackMonocular(im,tframe); // TODO change to monocular_inertial
|
|
||||||
|
|
||||||
#ifdef COMPILEDWITHC11
|
#ifdef COMPILEDWITHC11
|
||||||
std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();
|
std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();
|
||||||
|
@ -117,6 +116,11 @@ int main(int argc, char **argv)
|
||||||
std::chrono::monotonic_clock::time_point t2 = std::chrono::monotonic_clock::now();
|
std::chrono::monotonic_clock::time_point t2 = std::chrono::monotonic_clock::now();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
double t_track = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t2 - t1).count();
|
||||||
|
SLAM.InsertTrackTime(t_track);
|
||||||
|
#endif
|
||||||
|
|
||||||
double ttrack= std::chrono::duration_cast<std::chrono::duration<double> >(t2 - t1).count();
|
double ttrack= std::chrono::duration_cast<std::chrono::duration<double> >(t2 - t1).count();
|
||||||
|
|
||||||
vTimesTrack[ni]=ttrack;
|
vTimesTrack[ni]=ttrack;
|
||||||
|
@ -129,7 +133,7 @@ int main(int argc, char **argv)
|
||||||
T = tframe-vTimestampsCam[seq][ni-1];
|
T = tframe-vTimestampsCam[seq][ni-1];
|
||||||
|
|
||||||
if(ttrack<T)
|
if(ttrack<T)
|
||||||
usleep((T-ttrack)*1e6); // 1e6
|
usleep((T-ttrack)*1e6);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(seq < num_seq - 1)
|
if(seq < num_seq - 1)
|
||||||
|
|
|
@ -53,10 +53,6 @@ int main(int argc, char **argv)
|
||||||
vector<float> vTimesTrack;
|
vector<float> vTimesTrack;
|
||||||
vTimesTrack.resize(nImages);
|
vTimesTrack.resize(nImages);
|
||||||
|
|
||||||
cout << endl << "-------" << endl;
|
|
||||||
cout << "Start processing sequence ..." << endl;
|
|
||||||
cout << "Images in the sequence: " << nImages << endl << endl;
|
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
cv::Mat im;
|
cv::Mat im;
|
||||||
for(int ni=0; ni<nImages; ni++)
|
for(int ni=0; ni<nImages; ni++)
|
||||||
|
|
|
@ -55,10 +55,6 @@ int main(int argc, char **argv)
|
||||||
vector<float> vTimesTrack;
|
vector<float> vTimesTrack;
|
||||||
vTimesTrack.resize(nImages);
|
vTimesTrack.resize(nImages);
|
||||||
|
|
||||||
cout << endl << "-------" << endl;
|
|
||||||
cout << "Start processing sequence ..." << endl;
|
|
||||||
cout << "Images in the sequence: " << nImages << endl << endl;
|
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
cv::Mat im;
|
cv::Mat im;
|
||||||
for(int ni=0; ni<nImages; ni++)
|
for(int ni=0; ni<nImages; ni++)
|
||||||
|
|
|
@ -103,7 +103,7 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Read image from file
|
// Read image from file
|
||||||
im = cv::imread(vstrImageFilenames[seq][ni],cv::IMREAD_GRAYSCALE);
|
im = cv::imread(vstrImageFilenames[seq][ni],cv::IMREAD_UNCHANGED);
|
||||||
|
|
||||||
// clahe
|
// clahe
|
||||||
clahe->apply(im,im);
|
clahe->apply(im,im);
|
||||||
|
@ -146,7 +146,7 @@ int main(int argc, char **argv)
|
||||||
T = tframe-vTimestampsCam[seq][ni-1];
|
T = tframe-vTimestampsCam[seq][ni-1];
|
||||||
|
|
||||||
if(ttrack<T)
|
if(ttrack<T)
|
||||||
usleep((T-ttrack)*1e6); // 1e6
|
usleep((T-ttrack)*1e6);
|
||||||
|
|
||||||
}
|
}
|
||||||
if(seq < num_seq - 1)
|
if(seq < num_seq - 1)
|
||||||
|
@ -158,13 +158,9 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// cout << "ttrack_tot = " << ttrack_tot << std::endl;
|
|
||||||
// Stop all threads
|
// Stop all threads
|
||||||
SLAM.Shutdown();
|
SLAM.Shutdown();
|
||||||
|
|
||||||
|
|
||||||
// Tracking time statistics
|
|
||||||
|
|
||||||
// Save camera trajectory
|
// Save camera trajectory
|
||||||
|
|
||||||
if (bFileName)
|
if (bFileName)
|
||||||
|
|
|
@ -65,17 +65,13 @@ int main(int argc, char **argv)
|
||||||
vector<float> vTimesTrack;
|
vector<float> vTimesTrack;
|
||||||
vTimesTrack.resize(nImages);
|
vTimesTrack.resize(nImages);
|
||||||
|
|
||||||
cout << endl << "-------" << endl;
|
|
||||||
cout << "Start processing sequence ..." << endl;
|
|
||||||
cout << "Images in the sequence: " << nImages << endl << endl;
|
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
cv::Mat imRGB, imD;
|
cv::Mat imRGB, imD;
|
||||||
for(int ni=0; ni<nImages; ni++)
|
for(int ni=0; ni<nImages; ni++)
|
||||||
{
|
{
|
||||||
// Read image and depthmap from file
|
// Read image and depthmap from file
|
||||||
imRGB = cv::imread(string(argv[3])+"/"+vstrImageFilenamesRGB[ni],cv::IMREAD_UNCHANGED);
|
imRGB = cv::imread(string(argv[3])+"/"+vstrImageFilenamesRGB[ni],cv::IMREAD_UNCHANGED); //,cv::IMREAD_UNCHANGED);
|
||||||
imD = cv::imread(string(argv[3])+"/"+vstrImageFilenamesD[ni],cv::IMREAD_UNCHANGED);
|
imD = cv::imread(string(argv[3])+"/"+vstrImageFilenamesD[ni],cv::IMREAD_UNCHANGED); //,cv::IMREAD_UNCHANGED);
|
||||||
double tframe = vTimestamps[ni];
|
double tframe = vTimestamps[ni];
|
||||||
|
|
||||||
if(imRGB.empty())
|
if(imRGB.empty())
|
||||||
|
|
|
@ -167,6 +167,7 @@ int main(int argc, char **argv)
|
||||||
// Seq loop
|
// Seq loop
|
||||||
vector<ORB_SLAM3::IMU::Point> vImuMeas;
|
vector<ORB_SLAM3::IMU::Point> vImuMeas;
|
||||||
double t_rect = 0;
|
double t_rect = 0;
|
||||||
|
double t_track = 0;
|
||||||
int num_rect = 0;
|
int num_rect = 0;
|
||||||
int proccIm = 0;
|
int proccIm = 0;
|
||||||
for(int ni=0; ni<nImages[seq]; ni++, proccIm++)
|
for(int ni=0; ni<nImages[seq]; ni++, proccIm++)
|
||||||
|
@ -190,28 +191,32 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
#ifdef COMPILEDWITHC11
|
#ifdef COMPILEDWITHC11
|
||||||
std::chrono::steady_clock::time_point t_Start_Rect = std::chrono::steady_clock::now();
|
std::chrono::steady_clock::time_point t_Start_Rect = std::chrono::steady_clock::now();
|
||||||
#else
|
#else
|
||||||
std::chrono::monotonic_clock::time_point t_Start_Rect = std::chrono::monotonic_clock::now();
|
std::chrono::monotonic_clock::time_point t_Start_Rect = std::chrono::monotonic_clock::now();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
cv::remap(imLeft,imLeftRect,M1l,M2l,cv::INTER_LINEAR);
|
cv::remap(imLeft,imLeftRect,M1l,M2l,cv::INTER_LINEAR);
|
||||||
cv::remap(imRight,imRightRect,M1r,M2r,cv::INTER_LINEAR);
|
cv::remap(imRight,imRightRect,M1r,M2r,cv::INTER_LINEAR);
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
#ifdef COMPILEDWITHC11
|
#ifdef COMPILEDWITHC11
|
||||||
std::chrono::steady_clock::time_point t_End_Rect = std::chrono::steady_clock::now();
|
std::chrono::steady_clock::time_point t_End_Rect = std::chrono::steady_clock::now();
|
||||||
#else
|
#else
|
||||||
std::chrono::monotonic_clock::time_point t_End_Rect = std::chrono::monotonic_clock::now();
|
std::chrono::monotonic_clock::time_point t_End_Rect = std::chrono::monotonic_clock::now();
|
||||||
#endif
|
#endif
|
||||||
|
t_rect = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t_End_Rect - t_Start_Rect).count();
|
||||||
t_rect = std::chrono::duration_cast<std::chrono::duration<double> >(t_End_Rect - t_Start_Rect).count();
|
SLAM.InsertRectTime(t_rect);
|
||||||
|
#endif
|
||||||
double tframe = vTimestampsCam[seq][ni];
|
double tframe = vTimestampsCam[seq][ni];
|
||||||
|
|
||||||
// Load imu measurements from previous frame
|
// Load imu measurements from previous frame
|
||||||
vImuMeas.clear();
|
vImuMeas.clear();
|
||||||
|
|
||||||
if(ni>0)
|
if(ni>0)
|
||||||
while(vTimestampsImu[seq][first_imu[seq]]<=vTimestampsCam[seq][ni]) // while(vTimestampsImu[first_imu]<=vTimestampsCam[ni])
|
while(vTimestampsImu[seq][first_imu[seq]]<=vTimestampsCam[seq][ni])
|
||||||
{
|
{
|
||||||
vImuMeas.push_back(ORB_SLAM3::IMU::Point(vAcc[seq][first_imu[seq]].x,vAcc[seq][first_imu[seq]].y,vAcc[seq][first_imu[seq]].z,
|
vImuMeas.push_back(ORB_SLAM3::IMU::Point(vAcc[seq][first_imu[seq]].x,vAcc[seq][first_imu[seq]].y,vAcc[seq][first_imu[seq]].z,
|
||||||
vGyro[seq][first_imu[seq]].x,vGyro[seq][first_imu[seq]].y,vGyro[seq][first_imu[seq]].z,
|
vGyro[seq][first_imu[seq]].x,vGyro[seq][first_imu[seq]].y,vGyro[seq][first_imu[seq]].z,
|
||||||
|
@ -234,6 +239,11 @@ int main(int argc, char **argv)
|
||||||
std::chrono::monotonic_clock::time_point t2 = std::chrono::monotonic_clock::now();
|
std::chrono::monotonic_clock::time_point t2 = std::chrono::monotonic_clock::now();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
t_track = t_rect + std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t2 - t1).count();
|
||||||
|
SLAM.InsertTrackTime(t_track);
|
||||||
|
#endif
|
||||||
|
|
||||||
double ttrack= std::chrono::duration_cast<std::chrono::duration<double> >(t2 - t1).count();
|
double ttrack= std::chrono::duration_cast<std::chrono::duration<double> >(t2 - t1).count();
|
||||||
|
|
||||||
vTimesTrack[ni]=ttrack;
|
vTimesTrack[ni]=ttrack;
|
||||||
|
|
|
@ -114,10 +114,6 @@ int main(int argc, char **argv)
|
||||||
cout << endl << "-------" << endl;
|
cout << endl << "-------" << endl;
|
||||||
cout.precision(17);
|
cout.precision(17);
|
||||||
|
|
||||||
/*cout << "Start processing sequence ..." << endl;
|
|
||||||
cout << "Images in the sequence: " << nImages << endl;
|
|
||||||
cout << "IMU data in the sequence: " << nImu << endl << endl;*/
|
|
||||||
|
|
||||||
// Create SLAM system. It initializes all system threads and gets ready to process frames.
|
// Create SLAM system. It initializes all system threads and gets ready to process frames.
|
||||||
ORB_SLAM3::System SLAM(argv[1],argv[2],ORB_SLAM3::System::IMU_STEREO, true, 0, file_name);
|
ORB_SLAM3::System SLAM(argv[1],argv[2],ORB_SLAM3::System::IMU_STEREO, true, 0, file_name);
|
||||||
|
|
||||||
|
@ -156,23 +152,16 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
if(ni>0)
|
if(ni>0)
|
||||||
{
|
{
|
||||||
// cout << "t_cam " << tframe << endl;
|
|
||||||
|
|
||||||
while(vTimestampsImu[seq][first_imu[seq]]<=vTimestampsCam[seq][ni])
|
while(vTimestampsImu[seq][first_imu[seq]]<=vTimestampsCam[seq][ni])
|
||||||
{
|
{
|
||||||
// vImuMeas.push_back(ORB_SLAM3::IMU::Point(vAcc[first_imu],vGyro[first_imu],vTimestampsImu[first_imu]));
|
|
||||||
vImuMeas.push_back(ORB_SLAM3::IMU::Point(vAcc[seq][first_imu[seq]].x,vAcc[seq][first_imu[seq]].y,vAcc[seq][first_imu[seq]].z,
|
vImuMeas.push_back(ORB_SLAM3::IMU::Point(vAcc[seq][first_imu[seq]].x,vAcc[seq][first_imu[seq]].y,vAcc[seq][first_imu[seq]].z,
|
||||||
vGyro[seq][first_imu[seq]].x,vGyro[seq][first_imu[seq]].y,vGyro[seq][first_imu[seq]].z,
|
vGyro[seq][first_imu[seq]].x,vGyro[seq][first_imu[seq]].y,vGyro[seq][first_imu[seq]].z,
|
||||||
vTimestampsImu[seq][first_imu[seq]]));
|
vTimestampsImu[seq][first_imu[seq]]));
|
||||||
// cout << "t_imu = " << fixed << vImuMeas.back().t << endl;
|
|
||||||
first_imu[seq]++;
|
first_imu[seq]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*cout << "first imu: " << first_imu[seq] << endl;
|
|
||||||
cout << "first imu time: " << fixed << vTimestampsImu[seq][0] << endl;
|
|
||||||
cout << "size vImu: " << vImuMeas.size() << endl;*/
|
|
||||||
|
|
||||||
#ifdef COMPILEDWITHC11
|
#ifdef COMPILEDWITHC11
|
||||||
std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
|
std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
|
||||||
#else
|
#else
|
||||||
|
@ -190,7 +179,6 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
double ttrack= std::chrono::duration_cast<std::chrono::duration<double> >(t2 - t1).count();
|
double ttrack= std::chrono::duration_cast<std::chrono::duration<double> >(t2 - t1).count();
|
||||||
ttrack_tot += ttrack;
|
ttrack_tot += ttrack;
|
||||||
// std::cout << "ttrack: " << ttrack << std::endl;
|
|
||||||
|
|
||||||
vTimesTrack[ni]=ttrack;
|
vTimesTrack[ni]=ttrack;
|
||||||
|
|
||||||
|
@ -202,7 +190,7 @@ int main(int argc, char **argv)
|
||||||
T = tframe-vTimestampsCam[seq][ni-1];
|
T = tframe-vTimestampsCam[seq][ni-1];
|
||||||
|
|
||||||
if(ttrack<T)
|
if(ttrack<T)
|
||||||
usleep((T-ttrack)*1e6); // 1e6
|
usleep((T-ttrack)*1e6);
|
||||||
}
|
}
|
||||||
if(seq < num_seq - 1)
|
if(seq < num_seq - 1)
|
||||||
{
|
{
|
||||||
|
@ -216,8 +204,6 @@ int main(int argc, char **argv)
|
||||||
// Stop all threads
|
// Stop all threads
|
||||||
SLAM.Shutdown();
|
SLAM.Shutdown();
|
||||||
|
|
||||||
// Tracking time statistics
|
|
||||||
|
|
||||||
// Save camera trajectory
|
// Save camera trajectory
|
||||||
std::chrono::system_clock::time_point scNow = std::chrono::system_clock::now();
|
std::chrono::system_clock::time_point scNow = std::chrono::system_clock::now();
|
||||||
std::time_t now = std::chrono::system_clock::to_time_t(scNow);
|
std::time_t now = std::chrono::system_clock::to_time_t(scNow);
|
||||||
|
|
|
@ -135,6 +135,7 @@ int main(int argc, char **argv)
|
||||||
// Seq loop
|
// Seq loop
|
||||||
|
|
||||||
double t_rect = 0;
|
double t_rect = 0;
|
||||||
|
double t_track = 0;
|
||||||
int num_rect = 0;
|
int num_rect = 0;
|
||||||
int proccIm = 0;
|
int proccIm = 0;
|
||||||
for(int ni=0; ni<nImages[seq]; ni++, proccIm++)
|
for(int ni=0; ni<nImages[seq]; ni++, proccIm++)
|
||||||
|
@ -157,25 +158,26 @@ int main(int argc, char **argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
#ifdef COMPILEDWITHC11
|
#ifdef COMPILEDWITHC11
|
||||||
std::chrono::steady_clock::time_point t_Start_Rect = std::chrono::steady_clock::now();
|
std::chrono::steady_clock::time_point t_Start_Rect = std::chrono::steady_clock::now();
|
||||||
#else
|
#else
|
||||||
std::chrono::monotonic_clock::time_point t_Start_Rect = std::chrono::monotonic_clock::now();
|
std::chrono::monotonic_clock::time_point t_Start_Rect = std::chrono::monotonic_clock::now();
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
cv::remap(imLeft,imLeftRect,M1l,M2l,cv::INTER_LINEAR);
|
cv::remap(imLeft,imLeftRect,M1l,M2l,cv::INTER_LINEAR);
|
||||||
cv::remap(imRight,imRightRect,M1r,M2r,cv::INTER_LINEAR);
|
cv::remap(imRight,imRightRect,M1r,M2r,cv::INTER_LINEAR);
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
#ifdef COMPILEDWITHC11
|
#ifdef COMPILEDWITHC11
|
||||||
std::chrono::steady_clock::time_point t_End_Rect = std::chrono::steady_clock::now();
|
std::chrono::steady_clock::time_point t_End_Rect = std::chrono::steady_clock::now();
|
||||||
#else
|
#else
|
||||||
std::chrono::monotonic_clock::time_point t_End_Rect = std::chrono::monotonic_clock::now();
|
std::chrono::monotonic_clock::time_point t_End_Rect = std::chrono::monotonic_clock::now();
|
||||||
#endif
|
#endif
|
||||||
|
t_rect = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t_End_Rect - t_Start_Rect).count();
|
||||||
t_rect = std::chrono::duration_cast<std::chrono::duration<double> >(t_End_Rect - t_Start_Rect).count();
|
SLAM.InsertRectTime(t_rect);
|
||||||
|
#endif
|
||||||
double tframe = vTimestampsCam[seq][ni];
|
double tframe = vTimestampsCam[seq][ni];
|
||||||
|
|
||||||
|
|
||||||
#ifdef COMPILEDWITHC11
|
#ifdef COMPILEDWITHC11
|
||||||
std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
|
std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
|
||||||
#else
|
#else
|
||||||
|
@ -191,6 +193,11 @@ int main(int argc, char **argv)
|
||||||
std::chrono::monotonic_clock::time_point t2 = std::chrono::monotonic_clock::now();
|
std::chrono::monotonic_clock::time_point t2 = std::chrono::monotonic_clock::now();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
t_track = t_rect + std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t2 - t1).count();
|
||||||
|
SLAM.InsertTrackTime(t_track);
|
||||||
|
#endif
|
||||||
|
|
||||||
double ttrack= std::chrono::duration_cast<std::chrono::duration<double> >(t2 - t1).count();
|
double ttrack= std::chrono::duration_cast<std::chrono::duration<double> >(t2 - t1).count();
|
||||||
|
|
||||||
vTimesTrack[ni]=ttrack;
|
vTimesTrack[ni]=ttrack;
|
||||||
|
@ -203,7 +210,7 @@ int main(int argc, char **argv)
|
||||||
T = tframe-vTimestampsCam[seq][ni-1];
|
T = tframe-vTimestampsCam[seq][ni-1];
|
||||||
|
|
||||||
if(ttrack<T)
|
if(ttrack<T)
|
||||||
usleep((T-ttrack)*1e6); // 1e6
|
usleep((T-ttrack)*1e6);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(seq < num_seq - 1)
|
if(seq < num_seq - 1)
|
||||||
|
|
|
@ -54,10 +54,6 @@ int main(int argc, char **argv)
|
||||||
vector<float> vTimesTrack;
|
vector<float> vTimesTrack;
|
||||||
vTimesTrack.resize(nImages);
|
vTimesTrack.resize(nImages);
|
||||||
|
|
||||||
cout << endl << "-------" << endl;
|
|
||||||
cout << "Start processing sequence ..." << endl;
|
|
||||||
cout << "Images in the sequence: " << nImages << endl << endl;
|
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
cv::Mat imLeft, imRight;
|
cv::Mat imLeft, imRight;
|
||||||
for(int ni=0; ni<nImages; ni++)
|
for(int ni=0; ni<nImages; ni++)
|
||||||
|
|
|
@ -137,7 +137,6 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
double ttrack= std::chrono::duration_cast<std::chrono::duration<double> >(t2 - t1).count();
|
double ttrack= std::chrono::duration_cast<std::chrono::duration<double> >(t2 - t1).count();
|
||||||
ttrack_tot += ttrack;
|
ttrack_tot += ttrack;
|
||||||
// std::cout << "ttrack: " << ttrack << std::endl;
|
|
||||||
|
|
||||||
vTimesTrack[ni]=ttrack;
|
vTimesTrack[ni]=ttrack;
|
||||||
|
|
||||||
|
@ -149,7 +148,7 @@ int main(int argc, char **argv)
|
||||||
T = tframe-vTimestampsCam[seq][ni-1];
|
T = tframe-vTimestampsCam[seq][ni-1];
|
||||||
|
|
||||||
if(ttrack<T)
|
if(ttrack<T)
|
||||||
usleep((T-ttrack)*1e6); // 1e6
|
usleep((T-ttrack)*1e6);
|
||||||
}
|
}
|
||||||
if(seq < num_seq - 1)
|
if(seq < num_seq - 1)
|
||||||
{
|
{
|
||||||
|
@ -163,8 +162,6 @@ int main(int argc, char **argv)
|
||||||
// Stop all threads
|
// Stop all threads
|
||||||
SLAM.Shutdown();
|
SLAM.Shutdown();
|
||||||
|
|
||||||
// Tracking time statistics
|
|
||||||
|
|
||||||
// Save camera trajectory
|
// Save camera trajectory
|
||||||
std::chrono::system_clock::time_point scNow = std::chrono::system_clock::now();
|
std::chrono::system_clock::time_point scNow = std::chrono::system_clock::now();
|
||||||
std::time_t now = std::chrono::system_clock::to_time_t(scNow);
|
std::time_t now = std::chrono::system_clock::to_time_t(scNow);
|
||||||
|
|
|
@ -12,10 +12,10 @@
|
||||||
|
|
||||||
# ORB-SLAM3
|
# ORB-SLAM3
|
||||||
|
|
||||||
### V0.3: Beta version, 4 Sep 2020
|
### V0.4: Beta version, 21 April 2021
|
||||||
**Authors:** Carlos Campos, Richard Elvira, Juan J. Gómez Rodríguez, [José M. M. Montiel](http://webdiis.unizar.es/~josemari/), [Juan D. Tardos](http://webdiis.unizar.es/~jdtardos/).
|
**Authors:** Carlos Campos, Richard Elvira, Juan J. Gómez Rodríguez, [José M. M. Montiel](http://webdiis.unizar.es/~josemari/), [Juan D. Tardos](http://webdiis.unizar.es/~jdtardos/).
|
||||||
|
|
||||||
The [Changelog](https://github.com/UZ-SLAMLab/ORB_SLAM3/Changelog.md) describes the features of each version.
|
The [Changelog](https://github.com/UZ-SLAMLab/ORB_SLAM3/blob/master/Changelog.md) describes the features of each version.
|
||||||
|
|
||||||
ORB-SLAM3 is the first real-time SLAM library able to perform **Visual, Visual-Inertial and Multi-Map SLAM** with **monocular, stereo and RGB-D** cameras, using **pin-hole and fisheye** lens models. In all sensor configurations, ORB-SLAM3 is as robust as the best systems available in the literature, and significantly more accurate.
|
ORB-SLAM3 is the first real-time SLAM library able to perform **Visual, Visual-Inertial and Multi-Map SLAM** with **monocular, stereo and RGB-D** cameras, using **pin-hole and fisheye** lens models. In all sensor configurations, ORB-SLAM3 is as robust as the best systems available in the literature, and significantly more accurate.
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ alt="ORB-SLAM3" width="240" height="180" border="10" /></a>
|
||||||
|
|
||||||
### Related Publications:
|
### Related Publications:
|
||||||
|
|
||||||
[ORB-SLAM3] Carlos Campos, Richard Elvira, Juan J. Gómez Rodríguez, José M. M. Montiel and Juan D. Tardós, **ORB-SLAM3: An Accurate Open-Source Library for Visual, Visual-Inertial and Multi-Map SLAM**, Under review. **[PDF](https://arxiv.org/pdf/2007.11898.pdf)**.
|
[ORB-SLAM3] Carlos Campos, Richard Elvira, Juan J. Gómez Rodríguez, José M. M. Montiel and Juan D. Tardós, **ORB-SLAM3: An Accurate Open-Source Library for Visual, Visual-Inertial and Multi-Map SLAM**, *IEEE Transactions on Robotics, 2021* **[PDF](https://arxiv.org/abs/2007.11898)**.
|
||||||
|
|
||||||
[IMU-Initialization] Carlos Campos, J. M. M. Montiel and Juan D. Tardós, **Inertial-Only Optimization for Visual-Inertial Initialization**, *ICRA 2020*. **[PDF](https://arxiv.org/pdf/2003.05766.pdf)**
|
[IMU-Initialization] Carlos Campos, J. M. M. Montiel and Juan D. Tardós, **Inertial-Only Optimization for Visual-Inertial Initialization**, *ICRA 2020*. **[PDF](https://arxiv.org/pdf/2003.05766.pdf)**
|
||||||
|
|
||||||
|
@ -221,5 +221,6 @@ Once ORB-SLAM3 has loaded the vocabulary, press space in the rosbag tab.
|
||||||
rosrun rosbag fastrebag.py dataset-room1_512_16.bag dataset-room1_512_16_small_chunks.bag
|
rosrun rosbag fastrebag.py dataset-room1_512_16.bag dataset-room1_512_16_small_chunks.bag
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# 7. Time analysis
|
||||||
|
A flag in `include\Config.h` activates time measurements. It is necessary to uncomment the line `#define REGISTER_TIMES` to obtain the time stats of one execution which is shown at the terminal and stored in a text file(`ExecTimeMean.txt`).
|
||||||
|
|
||||||
|
|
|
@ -24,11 +24,11 @@ set(SRCS_DUTILS
|
||||||
DUtils/Random.cpp
|
DUtils/Random.cpp
|
||||||
DUtils/Timestamp.cpp)
|
DUtils/Timestamp.cpp)
|
||||||
|
|
||||||
|
find_package(OpenCV 4.0 QUIET)
|
||||||
|
if(NOT OpenCV_FOUND)
|
||||||
find_package(OpenCV 3.0 QUIET)
|
find_package(OpenCV 3.0 QUIET)
|
||||||
if(NOT OpenCV_FOUND)
|
if(NOT OpenCV_FOUND)
|
||||||
find_package(OpenCV 2.4.3 QUIET)
|
message(FATAL_ERROR "OpenCV > 3.0 not found.")
|
||||||
if(NOT OpenCV_FOUND)
|
|
||||||
message(FATAL_ERROR "OpenCV > 2.4.3 not found.")
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -1333,13 +1333,7 @@ int TemplatedVocabulary<TDescriptor,F>::stopWords(double minWeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
/**
|
|
||||||
* @brief 读取TXT格式的预训练好的ORB字典
|
|
||||||
*
|
|
||||||
* @param[in] filename 文件名
|
|
||||||
* @return true 读取成功
|
|
||||||
* @return false 读取失败
|
|
||||||
*/
|
|
||||||
template<class TDescriptor, class F>
|
template<class TDescriptor, class F>
|
||||||
bool TemplatedVocabulary<TDescriptor,F>::loadFromTextFile(const std::string &filename)
|
bool TemplatedVocabulary<TDescriptor,F>::loadFromTextFile(const std::string &filename)
|
||||||
{
|
{
|
||||||
|
@ -1356,8 +1350,8 @@ bool TemplatedVocabulary<TDescriptor,F>::loadFromTextFile(const std::string &fil
|
||||||
getline(f,s);
|
getline(f,s);
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss << s;
|
ss << s;
|
||||||
ss >> m_k; // 树的分支数目
|
ss >> m_k;
|
||||||
ss >> m_L; // 树的深度
|
ss >> m_L;
|
||||||
int n1, n2;
|
int n1, n2;
|
||||||
ss >> n1;
|
ss >> n1;
|
||||||
ss >> n2;
|
ss >> n2;
|
||||||
|
@ -1368,19 +1362,17 @@ bool TemplatedVocabulary<TDescriptor,F>::loadFromTextFile(const std::string &fil
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_scoring = (ScoringType)n1; // 评分类型
|
m_scoring = (ScoringType)n1;
|
||||||
m_weighting = (WeightingType)n2; // 权重类型
|
m_weighting = (WeightingType)n2;
|
||||||
createScoringObject();
|
createScoringObject();
|
||||||
|
|
||||||
// 总共节点(nodes)数,是一个等比数列求和
|
// nodes
|
||||||
//! bug 没有包含最后叶子节点数,应该改为 ((pow((double)m_k, (double)m_L + 2) - 1)/(m_k - 1))
|
|
||||||
//! 但是没有影响,因为这里只是reserve,实际存储是一步步resize实现
|
|
||||||
int expected_nodes =
|
int expected_nodes =
|
||||||
(int)((pow((double)m_k, (double)m_L + 1) - 1)/(m_k - 1));
|
(int)((pow((double)m_k, (double)m_L + 1) - 1)/(m_k - 1));
|
||||||
m_nodes.reserve(expected_nodes);
|
m_nodes.reserve(expected_nodes);
|
||||||
// 预分配空间给 单词(叶子)数
|
|
||||||
m_words.reserve(pow((double)m_k, (double)m_L + 1));
|
m_words.reserve(pow((double)m_k, (double)m_L + 1));
|
||||||
// 第一个节点是根节点,id设为0
|
|
||||||
m_nodes.resize(1);
|
m_nodes.resize(1);
|
||||||
m_nodes[0].id = 0;
|
m_nodes[0].id = 0;
|
||||||
while(!f.eof())
|
while(!f.eof())
|
||||||
|
@ -1389,25 +1381,19 @@ bool TemplatedVocabulary<TDescriptor,F>::loadFromTextFile(const std::string &fil
|
||||||
getline(f,snode);
|
getline(f,snode);
|
||||||
stringstream ssnode;
|
stringstream ssnode;
|
||||||
ssnode << snode;
|
ssnode << snode;
|
||||||
// nid 表示当前节点id,实际是读取顺序,从0开始
|
|
||||||
int nid = m_nodes.size();
|
int nid = m_nodes.size();
|
||||||
// 节点size 加1
|
|
||||||
m_nodes.resize(m_nodes.size()+1);
|
m_nodes.resize(m_nodes.size()+1);
|
||||||
m_nodes[nid].id = nid;
|
m_nodes[nid].id = nid;
|
||||||
|
|
||||||
// 读每行的第1个数字,表示父节点id
|
|
||||||
int pid ;
|
int pid ;
|
||||||
ssnode >> pid;
|
ssnode >> pid;
|
||||||
// 记录节点id的相互父子关系
|
|
||||||
m_nodes[nid].parent = pid;
|
m_nodes[nid].parent = pid;
|
||||||
m_nodes[pid].children.push_back(nid);
|
m_nodes[pid].children.push_back(nid);
|
||||||
|
|
||||||
// 读取第2个数字,表示是否是叶子(Word)
|
|
||||||
int nIsLeaf;
|
int nIsLeaf;
|
||||||
ssnode >> nIsLeaf;
|
ssnode >> nIsLeaf;
|
||||||
|
|
||||||
// 每个特征点描述子是256 bit,一个字节对应8 bit,所以一个特征点需要32个字节存储。
|
|
||||||
// 这里 F::L=32,也就是读取32个字节,最后以字符串形式存储在ssd
|
|
||||||
stringstream ssd;
|
stringstream ssd;
|
||||||
for(int iD=0;iD<F::L;iD++)
|
for(int iD=0;iD<F::L;iD++)
|
||||||
{
|
{
|
||||||
|
@ -1415,27 +1401,20 @@ bool TemplatedVocabulary<TDescriptor,F>::loadFromTextFile(const std::string &fil
|
||||||
ssnode >> sElement;
|
ssnode >> sElement;
|
||||||
ssd << sElement << " ";
|
ssd << sElement << " ";
|
||||||
}
|
}
|
||||||
// 将ssd存储在该节点的描述子
|
|
||||||
F::fromString(m_nodes[nid].descriptor, ssd.str());
|
F::fromString(m_nodes[nid].descriptor, ssd.str());
|
||||||
|
|
||||||
// 读取最后一个数字:节点的权重(Word才有)
|
|
||||||
ssnode >> m_nodes[nid].weight;
|
ssnode >> m_nodes[nid].weight;
|
||||||
|
|
||||||
if(nIsLeaf>0)
|
if(nIsLeaf>0)
|
||||||
{
|
{
|
||||||
// 如果是叶子(Word),存储到m_words
|
|
||||||
int wid = m_words.size();
|
int wid = m_words.size();
|
||||||
m_words.resize(wid+1);
|
m_words.resize(wid+1);
|
||||||
|
|
||||||
//存储Word的id,具有唯一性
|
|
||||||
m_nodes[nid].word_id = wid;
|
m_nodes[nid].word_id = wid;
|
||||||
|
|
||||||
//构建 vector<Node*> m_words,存储word所在node的指针
|
|
||||||
m_words[wid] = &m_nodes[nid];
|
m_words[wid] = &m_nodes[nid];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//非叶子节点,直接分配 m_k个分支
|
|
||||||
m_nodes[nid].children.reserve(m_k);
|
m_nodes[nid].children.reserve(m_k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
4
build.sh
4
build.sh
|
@ -27,5 +27,5 @@ echo "Configuring and building ORB_SLAM3 ..."
|
||||||
|
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=Debug
|
cmake .. -DCMAKE_BUILD_TYPE=Release
|
||||||
make
|
make -j
|
||||||
|
|
|
@ -43,33 +43,8 @@ class Frame;
|
||||||
class KannalaBrandt8;
|
class KannalaBrandt8;
|
||||||
class Pinhole;
|
class Pinhole;
|
||||||
|
|
||||||
//BOOST_CLASS_EXPORT_GUID(Pinhole, "Pinhole")
|
|
||||||
//BOOST_CLASS_EXPORT_GUID(KannalaBrandt8, "KannalaBrandt8")
|
|
||||||
|
|
||||||
class Atlas
|
class Atlas
|
||||||
{
|
{
|
||||||
friend class boost::serialization::access;
|
|
||||||
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar, const unsigned int version)
|
|
||||||
{
|
|
||||||
//ar.template register_type<Pinhole>();
|
|
||||||
//ar.template register_type<KannalaBrandt8>();
|
|
||||||
|
|
||||||
// Save/load the set of maps, the set is broken in libboost 1.58 for ubuntu 16.04
|
|
||||||
//ar & mspMaps;
|
|
||||||
ar & mvpBackupMaps;
|
|
||||||
ar & mvpCameras;
|
|
||||||
//ar & mvpBackupCamPin;
|
|
||||||
//ar & mvpBackupCamKan;
|
|
||||||
// Need to save/load the static Id from Frame, KeyFrame, MapPoint and Map
|
|
||||||
ar & Map::nNextId;
|
|
||||||
ar & Frame::nNextId;
|
|
||||||
ar & KeyFrame::nNextId;
|
|
||||||
ar & MapPoint::nNextId;
|
|
||||||
ar & GeometricCamera::nNextId;
|
|
||||||
ar & mnLastInitKFidMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Atlas();
|
Atlas();
|
||||||
|
@ -86,8 +61,6 @@ public:
|
||||||
// Method for change components in the current map
|
// Method for change components in the current map
|
||||||
void AddKeyFrame(KeyFrame* pKF);
|
void AddKeyFrame(KeyFrame* pKF);
|
||||||
void AddMapPoint(MapPoint* pMP);
|
void AddMapPoint(MapPoint* pMP);
|
||||||
//void EraseMapPoint(MapPoint* pMP);
|
|
||||||
//void EraseKeyFrame(KeyFrame* pKF);
|
|
||||||
|
|
||||||
void AddCamera(GeometricCamera* pCam);
|
void AddCamera(GeometricCamera* pCam);
|
||||||
|
|
||||||
|
@ -122,10 +95,6 @@ public:
|
||||||
void SetImuInitialized();
|
void SetImuInitialized();
|
||||||
bool isImuInitialized();
|
bool isImuInitialized();
|
||||||
|
|
||||||
// Function for garantee the correction of serialization of this object
|
|
||||||
void PreSave();
|
|
||||||
void PostLoad();
|
|
||||||
|
|
||||||
void SetKeyFrameDababase(KeyFrameDatabase* pKFDB);
|
void SetKeyFrameDababase(KeyFrameDatabase* pKFDB);
|
||||||
KeyFrameDatabase* GetKeyFrameDatabase();
|
KeyFrameDatabase* GetKeyFrameDatabase();
|
||||||
|
|
||||||
|
@ -140,15 +109,12 @@ protected:
|
||||||
|
|
||||||
std::set<Map*> mspMaps;
|
std::set<Map*> mspMaps;
|
||||||
std::set<Map*> mspBadMaps;
|
std::set<Map*> mspBadMaps;
|
||||||
// Its necessary change the container from set to vector because libboost 1.58 and Ubuntu 16.04 have an error with this cointainer
|
|
||||||
std::vector<Map*> mvpBackupMaps;
|
|
||||||
Map* mpCurrentMap;
|
Map* mpCurrentMap;
|
||||||
|
|
||||||
std::vector<GeometricCamera*> mvpCameras;
|
std::vector<GeometricCamera*> mvpCameras;
|
||||||
std::vector<KannalaBrandt8*> mvpBackupCamKan;
|
std::vector<KannalaBrandt8*> mvpBackupCamKan;
|
||||||
std::vector<Pinhole*> mvpBackupCamPin;
|
std::vector<Pinhole*> mvpBackupCamPin;
|
||||||
|
|
||||||
//Pinhole testCam;
|
|
||||||
std::mutex mMutexAtlas;
|
std::mutex mMutexAtlas;
|
||||||
|
|
||||||
unsigned long int mnLastInitKFidMap;
|
unsigned long int mnLastInitKFidMap;
|
||||||
|
|
|
@ -36,23 +36,13 @@
|
||||||
namespace ORB_SLAM3 {
|
namespace ORB_SLAM3 {
|
||||||
class GeometricCamera {
|
class GeometricCamera {
|
||||||
|
|
||||||
friend class boost::serialization::access;
|
|
||||||
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive& ar, const unsigned int version)
|
|
||||||
{
|
|
||||||
ar & mnId;
|
|
||||||
ar & mnType;
|
|
||||||
ar & mvParameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GeometricCamera() {}
|
GeometricCamera() {}
|
||||||
GeometricCamera(const std::vector<float> &_vParameters) : mvParameters(_vParameters) {}
|
GeometricCamera(const std::vector<float> &_vParameters) : mvParameters(_vParameters) {}
|
||||||
~GeometricCamera() {}
|
~GeometricCamera() {}
|
||||||
|
|
||||||
virtual cv::Point2f project(const cv::Point3f &p3D) = 0;
|
virtual cv::Point2f project(const cv::Point3f &p3D) = 0;
|
||||||
|
virtual cv::Point2f project(const cv::Matx31f &m3D) = 0;
|
||||||
virtual cv::Point2f project(const cv::Mat& m3D) = 0;
|
virtual cv::Point2f project(const cv::Mat& m3D) = 0;
|
||||||
virtual Eigen::Vector2d project(const Eigen::Vector3d & v3D) = 0;
|
virtual Eigen::Vector2d project(const Eigen::Vector3d & v3D) = 0;
|
||||||
virtual cv::Mat projectMat(const cv::Point3f& p3D) = 0;
|
virtual cv::Mat projectMat(const cv::Point3f& p3D) = 0;
|
||||||
|
@ -61,6 +51,7 @@ namespace ORB_SLAM3 {
|
||||||
|
|
||||||
virtual cv::Point3f unproject(const cv::Point2f &p2D) = 0;
|
virtual cv::Point3f unproject(const cv::Point2f &p2D) = 0;
|
||||||
virtual cv::Mat unprojectMat(const cv::Point2f &p2D) = 0;
|
virtual cv::Mat unprojectMat(const cv::Point2f &p2D) = 0;
|
||||||
|
virtual cv::Matx31f unprojectMat_(const cv::Point2f &p2D) = 0;
|
||||||
|
|
||||||
virtual cv::Mat projectJac(const cv::Point3f &p3D) = 0;
|
virtual cv::Mat projectJac(const cv::Point3f &p3D) = 0;
|
||||||
virtual Eigen::Matrix<double,2,3> projectJac(const Eigen::Vector3d& v3D) = 0;
|
virtual Eigen::Matrix<double,2,3> projectJac(const Eigen::Vector3d& v3D) = 0;
|
||||||
|
@ -71,8 +62,10 @@ namespace ORB_SLAM3 {
|
||||||
cv::Mat &R21, cv::Mat &t21, std::vector<cv::Point3f> &vP3D, std::vector<bool> &vbTriangulated) = 0;
|
cv::Mat &R21, cv::Mat &t21, std::vector<cv::Point3f> &vP3D, std::vector<bool> &vbTriangulated) = 0;
|
||||||
|
|
||||||
virtual cv::Mat toK() = 0;
|
virtual cv::Mat toK() = 0;
|
||||||
|
virtual cv::Matx33f toK_() = 0;
|
||||||
|
|
||||||
virtual bool epipolarConstrain(GeometricCamera* otherCamera, const cv::KeyPoint& kp1, const cv::KeyPoint& kp2, const cv::Mat& R12, const cv::Mat& t12, const float sigmaLevel, const float unc) = 0;
|
virtual bool epipolarConstrain(GeometricCamera* otherCamera, const cv::KeyPoint& kp1, const cv::KeyPoint& kp2, const cv::Mat& R12, const cv::Mat& t12, const float sigmaLevel, const float unc) = 0;
|
||||||
|
virtual bool epipolarConstrain_(GeometricCamera* otherCamera, const cv::KeyPoint& kp1, const cv::KeyPoint& kp2, const cv::Matx33f& R12, const cv::Matx31f& t12, const float sigmaLevel, const float unc) = 0;
|
||||||
|
|
||||||
float getParameter(const int i){return mvParameters[i];}
|
float getParameter(const int i){return mvParameters[i];}
|
||||||
void setParameter(const float p, const size_t i){mvParameters[i] = p;}
|
void setParameter(const float p, const size_t i){mvParameters[i] = p;}
|
||||||
|
|
|
@ -35,15 +35,6 @@
|
||||||
namespace ORB_SLAM3 {
|
namespace ORB_SLAM3 {
|
||||||
class KannalaBrandt8 final : public GeometricCamera {
|
class KannalaBrandt8 final : public GeometricCamera {
|
||||||
|
|
||||||
friend class boost::serialization::access;
|
|
||||||
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive& ar, const unsigned int version)
|
|
||||||
{
|
|
||||||
ar & boost::serialization::base_object<GeometricCamera>(*this);
|
|
||||||
ar & const_cast<float&>(precision);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
KannalaBrandt8() : precision(1e-6) {
|
KannalaBrandt8() : precision(1e-6) {
|
||||||
mvParameters.resize(8);
|
mvParameters.resize(8);
|
||||||
|
@ -69,6 +60,7 @@ namespace ORB_SLAM3 {
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::Point2f project(const cv::Point3f &p3D);
|
cv::Point2f project(const cv::Point3f &p3D);
|
||||||
|
cv::Point2f project(const cv::Matx31f &m3D);
|
||||||
cv::Point2f project(const cv::Mat& m3D);
|
cv::Point2f project(const cv::Mat& m3D);
|
||||||
Eigen::Vector2d project(const Eigen::Vector3d & v3D);
|
Eigen::Vector2d project(const Eigen::Vector3d & v3D);
|
||||||
cv::Mat projectMat(const cv::Point3f& p3D);
|
cv::Mat projectMat(const cv::Point3f& p3D);
|
||||||
|
@ -77,6 +69,7 @@ namespace ORB_SLAM3 {
|
||||||
|
|
||||||
cv::Point3f unproject(const cv::Point2f &p2D);
|
cv::Point3f unproject(const cv::Point2f &p2D);
|
||||||
cv::Mat unprojectMat(const cv::Point2f &p2D);
|
cv::Mat unprojectMat(const cv::Point2f &p2D);
|
||||||
|
cv::Matx31f unprojectMat_(const cv::Point2f &p2D);
|
||||||
|
|
||||||
cv::Mat projectJac(const cv::Point3f &p3D);
|
cv::Mat projectJac(const cv::Point3f &p3D);
|
||||||
Eigen::Matrix<double,2,3> projectJac(const Eigen::Vector3d& v3D);
|
Eigen::Matrix<double,2,3> projectJac(const Eigen::Vector3d& v3D);
|
||||||
|
@ -87,10 +80,14 @@ namespace ORB_SLAM3 {
|
||||||
cv::Mat &R21, cv::Mat &t21, std::vector<cv::Point3f> &vP3D, std::vector<bool> &vbTriangulated);
|
cv::Mat &R21, cv::Mat &t21, std::vector<cv::Point3f> &vP3D, std::vector<bool> &vbTriangulated);
|
||||||
|
|
||||||
cv::Mat toK();
|
cv::Mat toK();
|
||||||
|
cv::Matx33f toK_();
|
||||||
|
|
||||||
bool epipolarConstrain(GeometricCamera* pCamera2, const cv::KeyPoint& kp1, const cv::KeyPoint& kp2, const cv::Mat& R12, const cv::Mat& t12, const float sigmaLevel, const float unc);
|
bool epipolarConstrain(GeometricCamera* pCamera2, const cv::KeyPoint& kp1, const cv::KeyPoint& kp2, const cv::Mat& R12, const cv::Mat& t12, const float sigmaLevel, const float unc);
|
||||||
|
bool epipolarConstrain_(GeometricCamera* pCamera2, const cv::KeyPoint& kp1, const cv::KeyPoint& kp2, const cv::Matx33f& R12, const cv::Matx31f& t12, const float sigmaLevel, const float unc);
|
||||||
|
|
||||||
|
|
||||||
float TriangulateMatches(GeometricCamera* pCamera2, const cv::KeyPoint& kp1, const cv::KeyPoint& kp2, const cv::Mat& R12, const cv::Mat& t12, const float sigmaLevel, const float unc, cv::Mat& p3D);
|
float TriangulateMatches(GeometricCamera* pCamera2, const cv::KeyPoint& kp1, const cv::KeyPoint& kp2, const cv::Mat& R12, const cv::Mat& t12, const float sigmaLevel, const float unc, cv::Mat& p3D);
|
||||||
|
float TriangulateMatches_(GeometricCamera* pCamera2, const cv::KeyPoint& kp1, const cv::KeyPoint& kp2, const cv::Matx33f& R12, const cv::Matx31f& t12, const float sigmaLevel, const float unc, cv::Matx31f& p3D);
|
||||||
|
|
||||||
std::vector<int> mvLappingArea;
|
std::vector<int> mvLappingArea;
|
||||||
|
|
||||||
|
@ -110,6 +107,7 @@ namespace ORB_SLAM3 {
|
||||||
TwoViewReconstruction* tvr;
|
TwoViewReconstruction* tvr;
|
||||||
|
|
||||||
void Triangulate(const cv::Point2f &p1, const cv::Point2f &p2, const cv::Mat &Tcw1, const cv::Mat &Tcw2,cv::Mat &x3D);
|
void Triangulate(const cv::Point2f &p1, const cv::Point2f &p2, const cv::Mat &Tcw1, const cv::Mat &Tcw2,cv::Mat &x3D);
|
||||||
|
void Triangulate_(const cv::Point2f &p1, const cv::Point2f &p2, const cv::Matx44f &Tcw1, const cv::Matx44f &Tcw2,cv::Matx31f &x3D);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,14 +35,6 @@
|
||||||
namespace ORB_SLAM3 {
|
namespace ORB_SLAM3 {
|
||||||
class Pinhole : public GeometricCamera {
|
class Pinhole : public GeometricCamera {
|
||||||
|
|
||||||
friend class boost::serialization::access;
|
|
||||||
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive& ar, const unsigned int version)
|
|
||||||
{
|
|
||||||
ar & boost::serialization::base_object<GeometricCamera>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Pinhole() {
|
Pinhole() {
|
||||||
mvParameters.resize(4);
|
mvParameters.resize(4);
|
||||||
|
@ -67,6 +59,7 @@ namespace ORB_SLAM3 {
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::Point2f project(const cv::Point3f &p3D);
|
cv::Point2f project(const cv::Point3f &p3D);
|
||||||
|
cv::Point2f project(const cv::Matx31f &m3D);
|
||||||
cv::Point2f project(const cv::Mat &m3D);
|
cv::Point2f project(const cv::Mat &m3D);
|
||||||
Eigen::Vector2d project(const Eigen::Vector3d & v3D);
|
Eigen::Vector2d project(const Eigen::Vector3d & v3D);
|
||||||
cv::Mat projectMat(const cv::Point3f& p3D);
|
cv::Mat projectMat(const cv::Point3f& p3D);
|
||||||
|
@ -75,6 +68,8 @@ namespace ORB_SLAM3 {
|
||||||
|
|
||||||
cv::Point3f unproject(const cv::Point2f &p2D);
|
cv::Point3f unproject(const cv::Point2f &p2D);
|
||||||
cv::Mat unprojectMat(const cv::Point2f &p2D);
|
cv::Mat unprojectMat(const cv::Point2f &p2D);
|
||||||
|
cv::Matx31f unprojectMat_(const cv::Point2f &p2D);
|
||||||
|
|
||||||
|
|
||||||
cv::Mat projectJac(const cv::Point3f &p3D);
|
cv::Mat projectJac(const cv::Point3f &p3D);
|
||||||
Eigen::Matrix<double,2,3> projectJac(const Eigen::Vector3d& v3D);
|
Eigen::Matrix<double,2,3> projectJac(const Eigen::Vector3d& v3D);
|
||||||
|
@ -85,8 +80,10 @@ namespace ORB_SLAM3 {
|
||||||
cv::Mat &R21, cv::Mat &t21, std::vector<cv::Point3f> &vP3D, std::vector<bool> &vbTriangulated);
|
cv::Mat &R21, cv::Mat &t21, std::vector<cv::Point3f> &vP3D, std::vector<bool> &vbTriangulated);
|
||||||
|
|
||||||
cv::Mat toK();
|
cv::Mat toK();
|
||||||
|
cv::Matx33f toK_();
|
||||||
|
|
||||||
bool epipolarConstrain(GeometricCamera* pCamera2, const cv::KeyPoint& kp1, const cv::KeyPoint& kp2, const cv::Mat& R12, const cv::Mat& t12, const float sigmaLevel, const float unc);
|
bool epipolarConstrain(GeometricCamera* pCamera2, const cv::KeyPoint& kp1, const cv::KeyPoint& kp2, const cv::Mat& R12, const cv::Mat& t12, const float sigmaLevel, const float unc);
|
||||||
|
bool epipolarConstrain_(GeometricCamera* pCamera2, const cv::KeyPoint& kp1, const cv::KeyPoint& kp2, const cv::Matx33f& R12, const cv::Matx31f& t12, const float sigmaLevel, const float unc);
|
||||||
|
|
||||||
bool matchAndtriangulate(const cv::KeyPoint& kp1, const cv::KeyPoint& kp2, GeometricCamera* pOther,
|
bool matchAndtriangulate(const cv::KeyPoint& kp1, const cv::KeyPoint& kp2, GeometricCamera* pOther,
|
||||||
cv::Mat& Tcw1, cv::Mat& Tcw2,
|
cv::Mat& Tcw1, cv::Mat& Tcw2,
|
||||||
|
@ -97,6 +94,7 @@ namespace ORB_SLAM3 {
|
||||||
friend std::istream& operator>>(std::istream& os, Pinhole& ph);
|
friend std::istream& operator>>(std::istream& os, Pinhole& ph);
|
||||||
private:
|
private:
|
||||||
cv::Mat SkewSymmetricMatrix(const cv::Mat &v);
|
cv::Mat SkewSymmetricMatrix(const cv::Mat &v);
|
||||||
|
cv::Matx33f SkewSymmetricMatrix_(const cv::Matx31f &v);
|
||||||
|
|
||||||
//Parameters vector corresponds to
|
//Parameters vector corresponds to
|
||||||
// [fx, fy, cx, cy]
|
// [fx, fy, cx, cy]
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
#ifndef FRAME_H
|
#ifndef FRAME_H
|
||||||
#define FRAME_H
|
#define FRAME_H
|
||||||
|
|
||||||
//#define SAVE_TIMES
|
|
||||||
|
|
||||||
#include<vector>
|
#include<vector>
|
||||||
|
|
||||||
#include "Thirdparty/DBoW2/DBoW2/BowVector.h"
|
#include "Thirdparty/DBoW2/DBoW2/BowVector.h"
|
||||||
|
@ -29,6 +27,7 @@
|
||||||
|
|
||||||
#include "ImuTypes.h"
|
#include "ImuTypes.h"
|
||||||
#include "ORBVocabulary.h"
|
#include "ORBVocabulary.h"
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <opencv2/opencv.hpp>
|
#include <opencv2/opencv.hpp>
|
||||||
|
@ -61,9 +60,6 @@ public:
|
||||||
// Constructor for Monocular cameras.
|
// Constructor for Monocular cameras.
|
||||||
Frame(const cv::Mat &imGray, const double &timeStamp, ORBextractor* extractor,ORBVocabulary* voc, GeometricCamera* pCamera, cv::Mat &distCoef, const float &bf, const float &thDepth, Frame* pPrevF = static_cast<Frame*>(NULL), const IMU::Calib &ImuCalib = IMU::Calib());
|
Frame(const cv::Mat &imGray, const double &timeStamp, ORBextractor* extractor,ORBVocabulary* voc, GeometricCamera* pCamera, cv::Mat &distCoef, const float &bf, const float &thDepth, Frame* pPrevF = static_cast<Frame*>(NULL), const IMU::Calib &ImuCalib = IMU::Calib());
|
||||||
|
|
||||||
// Destructor
|
|
||||||
// ~Frame();
|
|
||||||
|
|
||||||
// Extract ORB on the image. 0 for left image and 1 for right image.
|
// Extract ORB on the image. 0 for left image and 1 for right image.
|
||||||
void ExtractORB(int flag, const cv::Mat &im, const int x0, const int x1);
|
void ExtractORB(int flag, const cv::Mat &im, const int x0, const int x1);
|
||||||
|
|
||||||
|
@ -247,9 +243,10 @@ public:
|
||||||
|
|
||||||
int mnDataset;
|
int mnDataset;
|
||||||
|
|
||||||
double mTimeStereoMatch;
|
#ifdef REGISTER_TIMES
|
||||||
double mTimeORB_Ext;
|
double mTimeORB_Ext;
|
||||||
|
double mTimeStereoMatch;
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -269,6 +266,10 @@ private:
|
||||||
cv::Mat mtcw;
|
cv::Mat mtcw;
|
||||||
//==mtwc
|
//==mtwc
|
||||||
|
|
||||||
|
cv::Matx31f mOwx;
|
||||||
|
cv::Matx33f mRcwx;
|
||||||
|
cv::Matx31f mtcwx;
|
||||||
|
|
||||||
bool mbImuPreintegrated;
|
bool mbImuPreintegrated;
|
||||||
|
|
||||||
std::mutex *mpMutexImu;
|
std::mutex *mpMutexImu;
|
||||||
|
@ -295,6 +296,7 @@ public:
|
||||||
std::vector<std::size_t> mGridRight[FRAME_GRID_COLS][FRAME_GRID_ROWS];
|
std::vector<std::size_t> mGridRight[FRAME_GRID_COLS][FRAME_GRID_ROWS];
|
||||||
|
|
||||||
cv::Mat mTlr, mRlr, mtlr, mTrl;
|
cv::Mat mTlr, mRlr, mtlr, mTrl;
|
||||||
|
cv::Matx34f mTrlx, mTlrx;
|
||||||
|
|
||||||
Frame(const cv::Mat &imLeft, const cv::Mat &imRight, const double &timeStamp, ORBextractor* extractorLeft, ORBextractor* extractorRight, ORBVocabulary* voc, cv::Mat &K, cv::Mat &distCoef, const float &bf, const float &thDepth, GeometricCamera* pCamera, GeometricCamera* pCamera2, cv::Mat& Tlr,Frame* pPrevF = static_cast<Frame*>(NULL), const IMU::Calib &ImuCalib = IMU::Calib());
|
Frame(const cv::Mat &imLeft, const cv::Mat &imRight, const double &timeStamp, ORBextractor* extractorLeft, ORBextractor* extractorRight, ORBVocabulary* voc, cv::Mat &K, cv::Mat &distCoef, const float &bf, const float &thDepth, GeometricCamera* pCamera, GeometricCamera* pCamera2, cv::Mat& Tlr,Frame* pPrevF = static_cast<Frame*>(NULL), const IMU::Calib &ImuCalib = IMU::Calib());
|
||||||
|
|
||||||
|
|
|
@ -51,233 +51,6 @@ class GeometricCamera;
|
||||||
class KeyFrame
|
class KeyFrame
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
template<class Archive>
|
|
||||||
void serializeMatrix(Archive& ar, cv::Mat& mat, const unsigned int version)
|
|
||||||
{
|
|
||||||
int cols, rows, type;
|
|
||||||
bool continuous;
|
|
||||||
|
|
||||||
if (Archive::is_saving::value) {
|
|
||||||
cols = mat.cols; rows = mat.rows; type = mat.type();
|
|
||||||
continuous = mat.isContinuous();
|
|
||||||
}
|
|
||||||
|
|
||||||
ar & cols & rows & type & continuous;
|
|
||||||
|
|
||||||
if (Archive::is_loading::value)
|
|
||||||
mat.create(rows, cols, type);
|
|
||||||
|
|
||||||
if (continuous) {
|
|
||||||
const unsigned int data_size = rows * cols * mat.elemSize();
|
|
||||||
ar & boost::serialization::make_array(mat.ptr(), data_size);
|
|
||||||
} else {
|
|
||||||
const unsigned int row_size = cols*mat.elemSize();
|
|
||||||
for (int i = 0; i < rows; i++) {
|
|
||||||
ar & boost::serialization::make_array(mat.ptr(i), row_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Archive>
|
|
||||||
void serializeMatrix(Archive& ar, const cv::Mat& mat, const unsigned int version)
|
|
||||||
{
|
|
||||||
cv::Mat matAux = mat;
|
|
||||||
|
|
||||||
serializeMatrix(ar, matAux,version);
|
|
||||||
|
|
||||||
if (Archive::is_loading::value)
|
|
||||||
{
|
|
||||||
cv::Mat* ptr;
|
|
||||||
ptr = (cv::Mat*)( &mat );
|
|
||||||
*ptr = matAux;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
friend class boost::serialization::access;
|
|
||||||
template<class Archive>
|
|
||||||
void serializeVectorKeyPoints(Archive& ar, const vector<cv::KeyPoint>& vKP, const unsigned int version)
|
|
||||||
{
|
|
||||||
int NumEl;
|
|
||||||
|
|
||||||
if (Archive::is_saving::value) {
|
|
||||||
NumEl = vKP.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
ar & NumEl;
|
|
||||||
|
|
||||||
vector<cv::KeyPoint> vKPaux = vKP;
|
|
||||||
if (Archive::is_loading::value)
|
|
||||||
vKPaux.reserve(NumEl);
|
|
||||||
|
|
||||||
for(int i=0; i < NumEl; ++i)
|
|
||||||
{
|
|
||||||
cv::KeyPoint KPi;
|
|
||||||
|
|
||||||
if (Archive::is_loading::value)
|
|
||||||
KPi = cv::KeyPoint();
|
|
||||||
|
|
||||||
if (Archive::is_saving::value)
|
|
||||||
KPi = vKPaux[i];
|
|
||||||
|
|
||||||
ar & KPi.angle;
|
|
||||||
ar & KPi.response;
|
|
||||||
ar & KPi.size;
|
|
||||||
ar & KPi.pt.x;
|
|
||||||
ar & KPi.pt.y;
|
|
||||||
ar & KPi.class_id;
|
|
||||||
ar & KPi.octave;
|
|
||||||
|
|
||||||
if (Archive::is_loading::value)
|
|
||||||
vKPaux.push_back(KPi);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (Archive::is_loading::value)
|
|
||||||
{
|
|
||||||
vector<cv::KeyPoint> *ptr;
|
|
||||||
ptr = (vector<cv::KeyPoint>*)( &vKP );
|
|
||||||
*ptr = vKPaux;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive& ar, const unsigned int version)
|
|
||||||
{
|
|
||||||
ar & mnId;
|
|
||||||
ar & const_cast<long unsigned int&>(mnFrameId);
|
|
||||||
ar & const_cast<double&>(mTimeStamp);
|
|
||||||
// Grid
|
|
||||||
ar & const_cast<int&>(mnGridCols);
|
|
||||||
ar & const_cast<int&>(mnGridRows);
|
|
||||||
ar & const_cast<float&>(mfGridElementWidthInv);
|
|
||||||
ar & const_cast<float&>(mfGridElementHeightInv);
|
|
||||||
// Variables of tracking
|
|
||||||
ar & mnTrackReferenceForFrame;
|
|
||||||
ar & mnFuseTargetForKF;
|
|
||||||
// Variables of local mapping
|
|
||||||
ar & mnBALocalForKF;
|
|
||||||
ar & mnBAFixedForKF;
|
|
||||||
ar & mnNumberOfOpt;
|
|
||||||
// Variables used by KeyFrameDatabase
|
|
||||||
ar & mnLoopQuery;
|
|
||||||
ar & mnLoopWords;
|
|
||||||
ar & mLoopScore;
|
|
||||||
ar & mnRelocQuery;
|
|
||||||
ar & mnRelocWords;
|
|
||||||
ar & mRelocScore;
|
|
||||||
ar & mnMergeQuery;
|
|
||||||
ar & mnMergeWords;
|
|
||||||
ar & mMergeScore;
|
|
||||||
ar & mnPlaceRecognitionQuery;
|
|
||||||
ar & mnPlaceRecognitionWords;
|
|
||||||
ar & mPlaceRecognitionScore;
|
|
||||||
ar & mbCurrentPlaceRecognition;
|
|
||||||
// Variables of loop closing
|
|
||||||
serializeMatrix(ar,mTcwGBA,version);
|
|
||||||
serializeMatrix(ar,mTcwBefGBA,version);
|
|
||||||
serializeMatrix(ar,mVwbGBA,version);
|
|
||||||
serializeMatrix(ar,mVwbBefGBA,version);
|
|
||||||
ar & mBiasGBA;
|
|
||||||
ar & mnBAGlobalForKF;
|
|
||||||
// Variables of Merging
|
|
||||||
serializeMatrix(ar,mTcwMerge,version);
|
|
||||||
serializeMatrix(ar,mTcwBefMerge,version);
|
|
||||||
serializeMatrix(ar,mTwcBefMerge,version);
|
|
||||||
serializeMatrix(ar,mVwbMerge,version);
|
|
||||||
serializeMatrix(ar,mVwbBefMerge,version);
|
|
||||||
ar & mBiasMerge;
|
|
||||||
ar & mnMergeCorrectedForKF;
|
|
||||||
ar & mnMergeForKF;
|
|
||||||
ar & mfScaleMerge;
|
|
||||||
ar & mnBALocalForMerge;
|
|
||||||
// Scale
|
|
||||||
ar & mfScale;
|
|
||||||
// Calibration parameters
|
|
||||||
ar & const_cast<float&>(fx);
|
|
||||||
ar & const_cast<float&>(fy);
|
|
||||||
ar & const_cast<float&>(invfx);
|
|
||||||
ar & const_cast<float&>(invfy);
|
|
||||||
ar & const_cast<float&>(cx);
|
|
||||||
ar & const_cast<float&>(cy);
|
|
||||||
ar & const_cast<float&>(mbf);
|
|
||||||
ar & const_cast<float&>(mb);
|
|
||||||
ar & const_cast<float&>(mThDepth);
|
|
||||||
serializeMatrix(ar,mDistCoef,version);
|
|
||||||
// Number of Keypoints
|
|
||||||
ar & const_cast<int&>(N);
|
|
||||||
// KeyPoints
|
|
||||||
serializeVectorKeyPoints(ar,mvKeys,version);
|
|
||||||
serializeVectorKeyPoints(ar,mvKeysUn,version);
|
|
||||||
ar & const_cast<vector<float>& >(mvuRight);
|
|
||||||
ar & const_cast<vector<float>& >(mvDepth);
|
|
||||||
serializeMatrix(ar,mDescriptors,version);
|
|
||||||
// BOW
|
|
||||||
ar & mBowVec;
|
|
||||||
ar & mFeatVec;
|
|
||||||
// Pose relative to parent
|
|
||||||
serializeMatrix(ar,mTcp,version);
|
|
||||||
// Scale
|
|
||||||
ar & const_cast<int&>(mnScaleLevels);
|
|
||||||
ar & const_cast<float&>(mfScaleFactor);
|
|
||||||
ar & const_cast<float&>(mfLogScaleFactor);
|
|
||||||
ar & const_cast<vector<float>& >(mvScaleFactors);
|
|
||||||
ar & const_cast<vector<float>& >(mvLevelSigma2);
|
|
||||||
ar & const_cast<vector<float>& >(mvInvLevelSigma2);
|
|
||||||
// Image bounds and calibration
|
|
||||||
ar & const_cast<int&>(mnMinX);
|
|
||||||
ar & const_cast<int&>(mnMinY);
|
|
||||||
ar & const_cast<int&>(mnMaxX);
|
|
||||||
ar & const_cast<int&>(mnMaxY);
|
|
||||||
serializeMatrix(ar,mK,version);
|
|
||||||
// Pose
|
|
||||||
serializeMatrix(ar,Tcw,version);
|
|
||||||
// MapPointsId associated to keypoints
|
|
||||||
ar & mvBackupMapPointsId;
|
|
||||||
// Grid
|
|
||||||
ar & mGrid;
|
|
||||||
// Connected KeyFrameWeight
|
|
||||||
ar & mBackupConnectedKeyFrameIdWeights;
|
|
||||||
// Spanning Tree and Loop Edges
|
|
||||||
ar & mbFirstConnection;
|
|
||||||
ar & mBackupParentId;
|
|
||||||
ar & mvBackupChildrensId;
|
|
||||||
ar & mvBackupLoopEdgesId;
|
|
||||||
ar & mvBackupMergeEdgesId;
|
|
||||||
// Bad flags
|
|
||||||
ar & mbNotErase;
|
|
||||||
ar & mbToBeErased;
|
|
||||||
ar & mbBad;
|
|
||||||
|
|
||||||
ar & mHalfBaseline;
|
|
||||||
|
|
||||||
// Camera variables
|
|
||||||
ar & mnBackupIdCamera;
|
|
||||||
ar & mnBackupIdCamera2;
|
|
||||||
|
|
||||||
// Fisheye variables
|
|
||||||
/*ar & mvLeftToRightMatch;
|
|
||||||
ar & mvRightToLeftMatch;
|
|
||||||
ar & NLeft;
|
|
||||||
ar & NRight;
|
|
||||||
serializeMatrix(ar, mTlr, version);
|
|
||||||
//serializeMatrix(ar, mTrl, version);
|
|
||||||
serializeVectorKeyPoints(ar, mvKeysRight, version);
|
|
||||||
ar & mGridRight;
|
|
||||||
|
|
||||||
// Inertial variables
|
|
||||||
ar & mImuBias;
|
|
||||||
ar & mBackupImuPreintegrated;
|
|
||||||
ar & mImuCalib;
|
|
||||||
ar & mBackupPrevKFId;
|
|
||||||
ar & mBackupNextKFId;
|
|
||||||
ar & bImu;
|
|
||||||
serializeMatrix(ar, Vw, version);
|
|
||||||
serializeMatrix(ar, Owb, version);*/
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
KeyFrame();
|
KeyFrame();
|
||||||
KeyFrame(Frame &F, Map* pMap, KeyFrameDatabase* pKFDB);
|
KeyFrame(Frame &F, Map* pMap, KeyFrameDatabase* pKFDB);
|
||||||
|
@ -297,6 +70,16 @@ public:
|
||||||
cv::Mat GetTranslation();
|
cv::Mat GetTranslation();
|
||||||
cv::Mat GetVelocity();
|
cv::Mat GetVelocity();
|
||||||
|
|
||||||
|
cv::Matx33f GetRotation_();
|
||||||
|
cv::Matx31f GetTranslation_();
|
||||||
|
cv::Matx31f GetCameraCenter_();
|
||||||
|
cv::Matx33f GetRightRotation_();
|
||||||
|
cv::Matx31f GetRightTranslation_();
|
||||||
|
cv::Matx44f GetRightPose_();
|
||||||
|
cv::Matx31f GetRightCameraCenter_();
|
||||||
|
cv::Matx44f GetPose_();
|
||||||
|
|
||||||
|
|
||||||
// Bag of Words Representation
|
// Bag of Words Representation
|
||||||
void ComputeBoW();
|
void ComputeBoW();
|
||||||
|
|
||||||
|
@ -343,6 +126,7 @@ public:
|
||||||
// KeyPoint functions
|
// KeyPoint functions
|
||||||
std::vector<size_t> GetFeaturesInArea(const float &x, const float &y, const float &r, const bool bRight = false) const;
|
std::vector<size_t> GetFeaturesInArea(const float &x, const float &y, const float &r, const bool bRight = false) const;
|
||||||
cv::Mat UnprojectStereo(int i);
|
cv::Mat UnprojectStereo(int i);
|
||||||
|
cv::Matx31f UnprojectStereo_(int i);
|
||||||
|
|
||||||
// Image
|
// Image
|
||||||
bool IsInImage(const float &x, const float &y) const;
|
bool IsInImage(const float &x, const float &y) const;
|
||||||
|
@ -377,10 +161,6 @@ public:
|
||||||
bool ProjectPointDistort(MapPoint* pMP, cv::Point2f &kp, float &u, float &v);
|
bool ProjectPointDistort(MapPoint* pMP, cv::Point2f &kp, float &u, float &v);
|
||||||
bool ProjectPointUnDistort(MapPoint* pMP, cv::Point2f &kp, float &u, float &v);
|
bool ProjectPointUnDistort(MapPoint* pMP, cv::Point2f &kp, float &u, float &v);
|
||||||
|
|
||||||
void PreSave(set<KeyFrame*>& spKF,set<MapPoint*>& spMP, set<GeometricCamera*>& spCam);
|
|
||||||
void PostLoad(map<long unsigned int, KeyFrame*>& mpKFid, map<long unsigned int, MapPoint*>& mpMPid, map<unsigned int, GeometricCamera*>& mpCamId);
|
|
||||||
|
|
||||||
|
|
||||||
void SetORBVocabulary(ORBVocabulary* pORBVoc);
|
void SetORBVocabulary(ORBVocabulary* pORBVoc);
|
||||||
void SetKeyFrameDatabase(KeyFrameDatabase* pKFDB);
|
void SetKeyFrameDatabase(KeyFrameDatabase* pKFDB);
|
||||||
|
|
||||||
|
@ -516,6 +296,9 @@ protected:
|
||||||
cv::Mat Ow;
|
cv::Mat Ow;
|
||||||
cv::Mat Cw; // Stereo middel point. Only for visualization
|
cv::Mat Cw; // Stereo middel point. Only for visualization
|
||||||
|
|
||||||
|
cv::Matx44f Tcw_, Twc_, Tlr_;
|
||||||
|
cv::Matx31f Ow_;
|
||||||
|
|
||||||
// IMU position
|
// IMU position
|
||||||
cv::Mat Owb;
|
cv::Mat Owb;
|
||||||
|
|
||||||
|
@ -527,8 +310,6 @@ protected:
|
||||||
|
|
||||||
// MapPoints associated to keypoints
|
// MapPoints associated to keypoints
|
||||||
std::vector<MapPoint*> mvpMapPoints;
|
std::vector<MapPoint*> mvpMapPoints;
|
||||||
// For save relation without pointer, this is necessary for save/load function
|
|
||||||
std::vector<long long int> mvBackupMapPointsId;
|
|
||||||
|
|
||||||
// BoW
|
// BoW
|
||||||
KeyFrameDatabase* mpKeyFrameDB;
|
KeyFrameDatabase* mpKeyFrameDB;
|
||||||
|
@ -540,8 +321,6 @@ protected:
|
||||||
std::map<KeyFrame*,int> mConnectedKeyFrameWeights;
|
std::map<KeyFrame*,int> mConnectedKeyFrameWeights;
|
||||||
std::vector<KeyFrame*> mvpOrderedConnectedKeyFrames;
|
std::vector<KeyFrame*> mvpOrderedConnectedKeyFrames;
|
||||||
std::vector<int> mvOrderedWeights;
|
std::vector<int> mvOrderedWeights;
|
||||||
// For save relation without pointer, this is necessary for save/load function
|
|
||||||
std::map<long unsigned int, int> mBackupConnectedKeyFrameIdWeights;
|
|
||||||
|
|
||||||
// Spanning Tree and Loop Edges
|
// Spanning Tree and Loop Edges
|
||||||
bool mbFirstConnection;
|
bool mbFirstConnection;
|
||||||
|
@ -549,11 +328,6 @@ protected:
|
||||||
std::set<KeyFrame*> mspChildrens;
|
std::set<KeyFrame*> mspChildrens;
|
||||||
std::set<KeyFrame*> mspLoopEdges;
|
std::set<KeyFrame*> mspLoopEdges;
|
||||||
std::set<KeyFrame*> mspMergeEdges;
|
std::set<KeyFrame*> mspMergeEdges;
|
||||||
// For save relation without pointer, this is necessary for save/load function
|
|
||||||
long long int mBackupParentId;
|
|
||||||
std::vector<long unsigned int> mvBackupChildrensId;
|
|
||||||
std::vector<long unsigned int> mvBackupLoopEdgesId;
|
|
||||||
std::vector<long unsigned int> mvBackupMergeEdgesId;
|
|
||||||
|
|
||||||
// Bad flags
|
// Bad flags
|
||||||
bool mbNotErase;
|
bool mbNotErase;
|
||||||
|
@ -569,14 +343,6 @@ protected:
|
||||||
std::mutex mMutexFeatures;
|
std::mutex mMutexFeatures;
|
||||||
std::mutex mMutexMap;
|
std::mutex mMutexMap;
|
||||||
|
|
||||||
// Backup variables for inertial
|
|
||||||
long long int mBackupPrevKFId;
|
|
||||||
long long int mBackupNextKFId;
|
|
||||||
IMU::Preintegrated mBackupImuPreintegrated;
|
|
||||||
|
|
||||||
// Backup for Cameras
|
|
||||||
unsigned int mnBackupIdCamera, mnBackupIdCamera2;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GeometricCamera* mpCamera, *mpCamera2;
|
GeometricCamera* mpCamera, *mpCamera2;
|
||||||
|
|
||||||
|
@ -601,7 +367,7 @@ public:
|
||||||
cv::Mat GetRightRotation();
|
cv::Mat GetRightRotation();
|
||||||
cv::Mat GetRightTranslation();
|
cv::Mat GetRightTranslation();
|
||||||
|
|
||||||
cv::Mat imgLeft, imgRight; //TODO Backup??
|
cv::Mat imgLeft, imgRight;
|
||||||
|
|
||||||
void PrintPointDistribution(){
|
void PrintPointDistribution(){
|
||||||
int left = 0, right = 0;
|
int left = 0, right = 0;
|
||||||
|
|
|
@ -46,13 +46,6 @@ class Map;
|
||||||
|
|
||||||
class KeyFrameDatabase
|
class KeyFrameDatabase
|
||||||
{
|
{
|
||||||
friend class boost::serialization::access;
|
|
||||||
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive& ar, const unsigned int version)
|
|
||||||
{
|
|
||||||
ar & mvBackupInvertedFileId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -76,8 +69,6 @@ public:
|
||||||
// Relocalization
|
// Relocalization
|
||||||
std::vector<KeyFrame*> DetectRelocalizationCandidates(Frame* F, Map* pMap);
|
std::vector<KeyFrame*> DetectRelocalizationCandidates(Frame* F, Map* pMap);
|
||||||
|
|
||||||
void PreSave();
|
|
||||||
void PostLoad(map<long unsigned int, KeyFrame*> mpKFid);
|
|
||||||
void SetORBVocabulary(ORBVocabulary* pORBVoc);
|
void SetORBVocabulary(ORBVocabulary* pORBVoc);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -88,9 +79,6 @@ protected:
|
||||||
// Inverted file
|
// Inverted file
|
||||||
std::vector<list<KeyFrame*> > mvInvertedFile;
|
std::vector<list<KeyFrame*> > mvInvertedFile;
|
||||||
|
|
||||||
// For save relation without pointer, this is necessary for save/load function
|
|
||||||
std::vector<list<long unsigned int> > mvBackupInvertedFileId;
|
|
||||||
|
|
||||||
// Mutex
|
// Mutex
|
||||||
std::mutex mMutex;
|
std::mutex mMutex;
|
||||||
};
|
};
|
||||||
|
|
|
@ -95,11 +95,6 @@ public:
|
||||||
double mFirstTs;
|
double mFirstTs;
|
||||||
int mnMatchesInliers;
|
int mnMatchesInliers;
|
||||||
|
|
||||||
// For debugging (erase in normal mode)
|
|
||||||
int mInitFr;
|
|
||||||
int mIdxIteration;
|
|
||||||
string strSequence;
|
|
||||||
|
|
||||||
bool mbNotBA1;
|
bool mbNotBA1;
|
||||||
bool mbNotBA2;
|
bool mbNotBA2;
|
||||||
bool mbBadImu;
|
bool mbBadImu;
|
||||||
|
@ -109,6 +104,25 @@ public:
|
||||||
// not consider far points (clouds)
|
// not consider far points (clouds)
|
||||||
bool mbFarPoints;
|
bool mbFarPoints;
|
||||||
float mThFarPoints;
|
float mThFarPoints;
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
vector<double> vdKFInsert_ms;
|
||||||
|
vector<double> vdMPCulling_ms;
|
||||||
|
vector<double> vdMPCreation_ms;
|
||||||
|
vector<double> vdLBA_ms;
|
||||||
|
vector<double> vdKFCulling_ms;
|
||||||
|
vector<double> vdLMTotal_ms;
|
||||||
|
|
||||||
|
|
||||||
|
vector<double> vdLBASync_ms;
|
||||||
|
vector<double> vdKFCullingSync_ms;
|
||||||
|
vector<int> vnLBA_edges;
|
||||||
|
vector<int> vnLBA_KFopt;
|
||||||
|
vector<int> vnLBA_KFfixed;
|
||||||
|
vector<int> vnLBA_MPs;
|
||||||
|
int nLBA_exec;
|
||||||
|
int nLBA_abort;
|
||||||
|
#endif
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
bool CheckNewKeyFrames();
|
bool CheckNewKeyFrames();
|
||||||
|
@ -120,8 +134,10 @@ protected:
|
||||||
void KeyFrameCulling();
|
void KeyFrameCulling();
|
||||||
|
|
||||||
cv::Mat ComputeF12(KeyFrame* &pKF1, KeyFrame* &pKF2);
|
cv::Mat ComputeF12(KeyFrame* &pKF1, KeyFrame* &pKF2);
|
||||||
|
cv::Matx33f ComputeF12_(KeyFrame* &pKF1, KeyFrame* &pKF2);
|
||||||
|
|
||||||
cv::Mat SkewSymmetricMatrix(const cv::Mat &v);
|
cv::Mat SkewSymmetricMatrix(const cv::Mat &v);
|
||||||
|
cv::Matx33f SkewSymmetricMatrix_(const cv::Matx31f &v);
|
||||||
|
|
||||||
System *mpSystem;
|
System *mpSystem;
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "Atlas.h"
|
#include "Atlas.h"
|
||||||
#include "ORBVocabulary.h"
|
#include "ORBVocabulary.h"
|
||||||
#include "Tracking.h"
|
#include "Tracking.h"
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
#include "KeyFrameDatabase.h"
|
#include "KeyFrameDatabase.h"
|
||||||
|
|
||||||
|
@ -48,7 +49,7 @@ public:
|
||||||
|
|
||||||
typedef pair<set<KeyFrame*>,int> ConsistentGroup;
|
typedef pair<set<KeyFrame*>,int> ConsistentGroup;
|
||||||
typedef map<KeyFrame*,g2o::Sim3,std::less<KeyFrame*>,
|
typedef map<KeyFrame*,g2o::Sim3,std::less<KeyFrame*>,
|
||||||
Eigen::aligned_allocator<std::pair<const KeyFrame*, g2o::Sim3> > > KeyFrameAndPose;
|
Eigen::aligned_allocator<std::pair<KeyFrame* const, g2o::Sim3> > > KeyFrameAndPose;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -86,6 +87,26 @@ public:
|
||||||
|
|
||||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
|
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
double timeDetectBoW;
|
||||||
|
|
||||||
|
std::vector<double> vTimeBoW_ms;
|
||||||
|
std::vector<double> vTimeSE3_ms;
|
||||||
|
std::vector<double> vTimePRTotal_ms;
|
||||||
|
|
||||||
|
std::vector<double> vTimeLoopFusion_ms;
|
||||||
|
std::vector<double> vTimeLoopEssent_ms;
|
||||||
|
std::vector<double> vTimeLoopTotal_ms;
|
||||||
|
|
||||||
|
std::vector<double> vTimeMergeFusion_ms;
|
||||||
|
std::vector<double> vTimeMergeBA_ms;
|
||||||
|
std::vector<double> vTimeMergeTotal_ms;
|
||||||
|
|
||||||
|
std::vector<double> vTimeFullGBA_ms;
|
||||||
|
std::vector<double> vTimeMapUpdate_ms;
|
||||||
|
std::vector<double> vTimeGBATotal_ms;
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
bool CheckNewKeyFrames();
|
bool CheckNewKeyFrames();
|
||||||
|
@ -112,9 +133,6 @@ protected:
|
||||||
void MergeLocal();
|
void MergeLocal();
|
||||||
void MergeLocal2();
|
void MergeLocal2();
|
||||||
|
|
||||||
void CheckObservations(set<KeyFrame*> &spKFsMap1, set<KeyFrame*> &spKFsMap2);
|
|
||||||
void printReprojectionError(set<KeyFrame*> &spLocalWindowKFs, KeyFrame* mpCurrentKF, string &name);
|
|
||||||
|
|
||||||
void ResetIfRequested();
|
void ResetIfRequested();
|
||||||
bool mbResetRequested;
|
bool mbResetRequested;
|
||||||
bool mbResetActiveMapRequested;
|
bool mbResetActiveMapRequested;
|
||||||
|
|
|
@ -65,8 +65,6 @@ namespace ORB_SLAM3{
|
||||||
void SetRansacParameters(double probability = 0.99, int minInliers = 8, int maxIterations = 300, int minSet = 6, float epsilon = 0.4,
|
void SetRansacParameters(double probability = 0.99, int minInliers = 8, int maxIterations = 300, int minSet = 6, float epsilon = 0.4,
|
||||||
float th2 = 5.991);
|
float th2 = 5.991);
|
||||||
|
|
||||||
//Find metod is necessary?
|
|
||||||
|
|
||||||
cv::Mat iterate(int nIterations, bool &bNoMore, vector<bool> &vbInliers, int &nInliers);
|
cv::Mat iterate(int nIterations, bool &bNoMore, vector<bool> &vbInliers, int &nInliers);
|
||||||
|
|
||||||
//Type definitions needed by the original code
|
//Type definitions needed by the original code
|
||||||
|
|
|
@ -37,39 +37,10 @@ class MapPoint;
|
||||||
class KeyFrame;
|
class KeyFrame;
|
||||||
class Atlas;
|
class Atlas;
|
||||||
class KeyFrameDatabase;
|
class KeyFrameDatabase;
|
||||||
|
class GeometricCamera;
|
||||||
|
|
||||||
class Map
|
class Map
|
||||||
{
|
{
|
||||||
friend class boost::serialization::access;
|
|
||||||
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive &ar, const unsigned int version)
|
|
||||||
{
|
|
||||||
ar & mnId;
|
|
||||||
ar & mnInitKFid;
|
|
||||||
ar & mnMaxKFid;
|
|
||||||
ar & mnBigChangeIdx;
|
|
||||||
// Set of KeyFrames and MapPoints, in this version the set serializator is not working
|
|
||||||
//ar & mspKeyFrames;
|
|
||||||
//ar & mspMapPoints;
|
|
||||||
|
|
||||||
ar & mvpBackupKeyFrames;
|
|
||||||
ar & mvpBackupMapPoints;
|
|
||||||
|
|
||||||
ar & mvBackupKeyFrameOriginsId;
|
|
||||||
|
|
||||||
ar & mnBackupKFinitialID;
|
|
||||||
ar & mnBackupKFlowerID;
|
|
||||||
|
|
||||||
ar & mbImuInitialized;
|
|
||||||
ar & mbIsInertial;
|
|
||||||
ar & mbIMU_BA1;
|
|
||||||
ar & mbIMU_BA2;
|
|
||||||
|
|
||||||
ar & mnInitKFid;
|
|
||||||
ar & mnMaxKFid;
|
|
||||||
ar & mnLastLoopKFid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Map();
|
Map();
|
||||||
|
@ -134,11 +105,6 @@ public:
|
||||||
|
|
||||||
unsigned int GetLowerKFID();
|
unsigned int GetLowerKFID();
|
||||||
|
|
||||||
void PreSave(std::set<GeometricCamera*> &spCams);
|
|
||||||
void PostLoad(KeyFrameDatabase* pKFDB, ORBVocabulary* pORBVoc, map<long unsigned int, KeyFrame*>& mpKeyFrameId, map<unsigned int, GeometricCamera*> &mpCams);
|
|
||||||
|
|
||||||
void printReprojectionError(list<KeyFrame*> &lpLocalWindowKFs, KeyFrame* mpCurrentKF, string &name, string &name_folder);
|
|
||||||
|
|
||||||
vector<KeyFrame*> mvpKeyFrameOrigins;
|
vector<KeyFrame*> mvpKeyFrameOrigins;
|
||||||
vector<unsigned long int> mvBackupKeyFrameOriginsId;
|
vector<unsigned long int> mvBackupKeyFrameOriginsId;
|
||||||
KeyFrame* mpFirstRegionKF;
|
KeyFrame* mpFirstRegionKF;
|
||||||
|
@ -162,15 +128,9 @@ protected:
|
||||||
std::set<MapPoint*> mspMapPoints;
|
std::set<MapPoint*> mspMapPoints;
|
||||||
std::set<KeyFrame*> mspKeyFrames;
|
std::set<KeyFrame*> mspKeyFrames;
|
||||||
|
|
||||||
std::vector<MapPoint*> mvpBackupMapPoints;
|
|
||||||
std::vector<KeyFrame*> mvpBackupKeyFrames;
|
|
||||||
|
|
||||||
KeyFrame* mpKFinitial;
|
KeyFrame* mpKFinitial;
|
||||||
KeyFrame* mpKFlowerID;
|
KeyFrame* mpKFlowerID;
|
||||||
|
|
||||||
unsigned long int mnBackupKFinitialID;
|
|
||||||
unsigned long int mnBackupKFlowerID;
|
|
||||||
|
|
||||||
std::vector<MapPoint*> mvpReferenceMapPoints;
|
std::vector<MapPoint*> mvpReferenceMapPoints;
|
||||||
|
|
||||||
bool mbImuInitialized;
|
bool mbImuInitialized;
|
||||||
|
@ -193,7 +153,7 @@ protected:
|
||||||
bool mHasTumbnail;
|
bool mHasTumbnail;
|
||||||
bool mbBad = false;
|
bool mbBad = false;
|
||||||
|
|
||||||
bool mbIsInertial; //标记是否有imu
|
bool mbIsInertial;
|
||||||
bool mbIMU_BA1;
|
bool mbIMU_BA1;
|
||||||
bool mbIMU_BA2;
|
bool mbIMU_BA2;
|
||||||
|
|
||||||
|
|
|
@ -40,89 +40,6 @@ class Frame;
|
||||||
|
|
||||||
class MapPoint
|
class MapPoint
|
||||||
{
|
{
|
||||||
template<class Archive>
|
|
||||||
void serializeMatrix(Archive &ar, cv::Mat& mat, const unsigned int version)
|
|
||||||
{
|
|
||||||
int cols, rows, type;
|
|
||||||
bool continuous;
|
|
||||||
|
|
||||||
if (Archive::is_saving::value) {
|
|
||||||
cols = mat.cols; rows = mat.rows; type = mat.type();
|
|
||||||
continuous = mat.isContinuous();
|
|
||||||
}
|
|
||||||
|
|
||||||
ar & cols & rows & type & continuous;
|
|
||||||
if (Archive::is_loading::value)
|
|
||||||
mat.create(rows, cols, type);
|
|
||||||
|
|
||||||
if (continuous) {
|
|
||||||
const unsigned int data_size = rows * cols * mat.elemSize();
|
|
||||||
ar & boost::serialization::make_array(mat.ptr(), data_size);
|
|
||||||
} else {
|
|
||||||
const unsigned int row_size = cols*mat.elemSize();
|
|
||||||
for (int i = 0; i < rows; i++) {
|
|
||||||
ar & boost::serialization::make_array(mat.ptr(i), row_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
friend class boost::serialization::access;
|
|
||||||
template<class Archive>
|
|
||||||
void serialize(Archive & ar, const unsigned int version)
|
|
||||||
{
|
|
||||||
ar & mnId;
|
|
||||||
ar & mnFirstKFid;
|
|
||||||
ar & mnFirstFrame;
|
|
||||||
ar & nObs;
|
|
||||||
// Variables used by the tracking
|
|
||||||
ar & mTrackProjX;
|
|
||||||
ar & mTrackProjY;
|
|
||||||
ar & mTrackDepth;
|
|
||||||
ar & mTrackDepthR;
|
|
||||||
ar & mTrackProjXR;
|
|
||||||
ar & mTrackProjYR;
|
|
||||||
ar & mbTrackInView;
|
|
||||||
ar & mbTrackInViewR;
|
|
||||||
ar & mnTrackScaleLevel;
|
|
||||||
ar & mnTrackScaleLevelR;
|
|
||||||
ar & mTrackViewCos;
|
|
||||||
ar & mTrackViewCosR;
|
|
||||||
ar & mnTrackReferenceForFrame;
|
|
||||||
ar & mnLastFrameSeen;
|
|
||||||
|
|
||||||
// Variables used by local mapping
|
|
||||||
ar & mnBALocalForKF;
|
|
||||||
ar & mnFuseCandidateForKF;
|
|
||||||
|
|
||||||
// Variables used by loop closing and merging
|
|
||||||
ar & mnLoopPointForKF;
|
|
||||||
ar & mnCorrectedByKF;
|
|
||||||
ar & mnCorrectedReference;
|
|
||||||
serializeMatrix(ar,mPosGBA,version);
|
|
||||||
ar & mnBAGlobalForKF;
|
|
||||||
ar & mnBALocalForMerge;
|
|
||||||
serializeMatrix(ar,mPosMerge,version);
|
|
||||||
serializeMatrix(ar,mNormalVectorMerge,version);
|
|
||||||
|
|
||||||
// Protected variables
|
|
||||||
serializeMatrix(ar,mWorldPos,version);
|
|
||||||
//ar & BOOST_SERIALIZATION_NVP(mBackupObservationsId);
|
|
||||||
ar & mBackupObservationsId1;
|
|
||||||
ar & mBackupObservationsId2;
|
|
||||||
serializeMatrix(ar,mNormalVector,version);
|
|
||||||
serializeMatrix(ar,mDescriptor,version);
|
|
||||||
ar & mBackupRefKFId;
|
|
||||||
ar & mnVisible;
|
|
||||||
ar & mnFound;
|
|
||||||
|
|
||||||
ar & mbBad;
|
|
||||||
ar & mBackupReplacedId;
|
|
||||||
|
|
||||||
ar & mfMinDistance;
|
|
||||||
ar & mfMaxDistance;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MapPoint();
|
MapPoint();
|
||||||
|
@ -136,6 +53,11 @@ public:
|
||||||
cv::Mat GetWorldPos();
|
cv::Mat GetWorldPos();
|
||||||
|
|
||||||
cv::Mat GetNormal();
|
cv::Mat GetNormal();
|
||||||
|
|
||||||
|
cv::Matx31f GetWorldPos2();
|
||||||
|
|
||||||
|
cv::Matx31f GetNormal2();
|
||||||
|
|
||||||
KeyFrame* GetReferenceKeyFrame();
|
KeyFrame* GetReferenceKeyFrame();
|
||||||
|
|
||||||
std::map<KeyFrame*,std::tuple<int,int>> GetObservations();
|
std::map<KeyFrame*,std::tuple<int,int>> GetObservations();
|
||||||
|
@ -175,11 +97,6 @@ public:
|
||||||
Map* GetMap();
|
Map* GetMap();
|
||||||
void UpdateMap(Map* pMap);
|
void UpdateMap(Map* pMap);
|
||||||
|
|
||||||
void PrintObservations();
|
|
||||||
|
|
||||||
void PreSave(set<KeyFrame*>& spKF,set<MapPoint*>& spMP);
|
|
||||||
void PostLoad(map<long unsigned int, KeyFrame*>& mpKFid, map<long unsigned int, MapPoint*>& mpMPid);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
long unsigned int mnId;
|
long unsigned int mnId;
|
||||||
static long unsigned int nNextId;
|
static long unsigned int nNextId;
|
||||||
|
@ -231,22 +148,20 @@ protected:
|
||||||
|
|
||||||
// Position in absolute coordinates
|
// Position in absolute coordinates
|
||||||
cv::Mat mWorldPos;
|
cv::Mat mWorldPos;
|
||||||
|
cv::Matx31f mWorldPosx;
|
||||||
|
|
||||||
// Keyframes observing the point and associated index in keyframe
|
// Keyframes observing the point and associated index in keyframe
|
||||||
std::map<KeyFrame*,std::tuple<int,int> > mObservations;
|
std::map<KeyFrame*,std::tuple<int,int> > mObservations;
|
||||||
// For save relation without pointer, this is necessary for save/load function
|
|
||||||
std::map<long unsigned int, int> mBackupObservationsId1;
|
|
||||||
std::map<long unsigned int, int> mBackupObservationsId2;
|
|
||||||
|
|
||||||
// Mean viewing direction
|
// Mean viewing direction
|
||||||
cv::Mat mNormalVector;
|
cv::Mat mNormalVector;
|
||||||
|
cv::Matx31f mNormalVectorx;
|
||||||
|
|
||||||
// Best descriptor to fast matching
|
// Best descriptor to fast matching
|
||||||
cv::Mat mDescriptor;
|
cv::Mat mDescriptor;
|
||||||
|
|
||||||
// Reference KeyFrame
|
// Reference KeyFrame
|
||||||
KeyFrame* mpRefKF;
|
KeyFrame* mpRefKF;
|
||||||
long unsigned int mBackupRefKFId;
|
|
||||||
|
|
||||||
// Tracking counters
|
// Tracking counters
|
||||||
int mnVisible;
|
int mnVisible;
|
||||||
|
@ -255,8 +170,6 @@ protected:
|
||||||
// Bad flag (we do not currently erase MapPoint from memory)
|
// Bad flag (we do not currently erase MapPoint from memory)
|
||||||
bool mbBad;
|
bool mbBad;
|
||||||
MapPoint* mpReplaced;
|
MapPoint* mpReplaced;
|
||||||
// For save relation without pointer, this is necessary for save/load function
|
|
||||||
long long int mBackupReplacedId;
|
|
||||||
|
|
||||||
// Scale invariance distances
|
// Scale invariance distances
|
||||||
float mfMinDistance;
|
float mfMinDistance;
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <opencv/cv.h>
|
#include <opencv2/opencv.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace ORB_SLAM3
|
namespace ORB_SLAM3
|
||||||
|
|
|
@ -74,6 +74,9 @@ public:
|
||||||
int SearchForTriangulation(KeyFrame *pKF1, KeyFrame* pKF2, cv::Mat F12,
|
int SearchForTriangulation(KeyFrame *pKF1, KeyFrame* pKF2, cv::Mat F12,
|
||||||
std::vector<pair<size_t, size_t> > &vMatchedPairs, const bool bOnlyStereo, const bool bCoarse = false);
|
std::vector<pair<size_t, size_t> > &vMatchedPairs, const bool bOnlyStereo, const bool bCoarse = false);
|
||||||
|
|
||||||
|
int SearchForTriangulation_(KeyFrame *pKF1, KeyFrame* pKF2, cv::Matx33f F12,
|
||||||
|
std::vector<pair<size_t, size_t> > &vMatchedPairs, const bool bOnlyStereo, const bool bCoarse = false);
|
||||||
|
|
||||||
int SearchForTriangulation(KeyFrame *pKF1, KeyFrame *pKF2, cv::Mat F12,
|
int SearchForTriangulation(KeyFrame *pKF1, KeyFrame *pKF2, cv::Mat F12,
|
||||||
vector<pair<size_t, size_t> > &vMatchedPairs, const bool bOnlyStereo, vector<cv::Mat> &vMatchedPoints);
|
vector<pair<size_t, size_t> > &vMatchedPairs, const bool bOnlyStereo, vector<cv::Mat> &vMatchedPoints);
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ public:
|
||||||
void static FullInertialBA(Map *pMap, int its, const bool bFixLocal=false, const unsigned long nLoopKF=0, bool *pbStopFlag=NULL, bool bInit=false, float priorG = 1e2, float priorA=1e6, Eigen::VectorXd *vSingVal = NULL, bool *bHess=NULL);
|
void static FullInertialBA(Map *pMap, int its, const bool bFixLocal=false, const unsigned long nLoopKF=0, bool *pbStopFlag=NULL, bool bInit=false, float priorG = 1e2, float priorA=1e6, Eigen::VectorXd *vSingVal = NULL, bool *bHess=NULL);
|
||||||
|
|
||||||
void static LocalBundleAdjustment(KeyFrame* pKF, bool *pbStopFlag, vector<KeyFrame*> &vpNonEnoughOptKFs);
|
void static LocalBundleAdjustment(KeyFrame* pKF, bool *pbStopFlag, vector<KeyFrame*> &vpNonEnoughOptKFs);
|
||||||
void static LocalBundleAdjustment(KeyFrame* pKF, bool *pbStopFlag, Map *pMap, int& num_fixedKF);
|
void static LocalBundleAdjustment(KeyFrame* pKF, bool *pbStopFlag, Map *pMap, int& num_fixedKF, int& num_OptKF, int& num_MPs, int& num_edges);
|
||||||
|
|
||||||
void static MergeBundleAdjustmentVisual(KeyFrame* pCurrentKF, vector<KeyFrame*> vpWeldingKFs, vector<KeyFrame*> vpFixedKFs, bool *pbStopFlag);
|
void static MergeBundleAdjustmentVisual(KeyFrame* pCurrentKF, vector<KeyFrame*> vpWeldingKFs, vector<KeyFrame*> vpFixedKFs, bool *pbStopFlag);
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ public:
|
||||||
|
|
||||||
// For inertial systems
|
// For inertial systems
|
||||||
|
|
||||||
void static LocalInertialBA(KeyFrame* pKF, bool *pbStopFlag, Map *pMap, bool bLarge = false, bool bRecInit = false);
|
void static LocalInertialBA(KeyFrame* pKF, bool *pbStopFlag, Map *pMap, int& num_fixedKF, int& num_OptKF, int& num_MPs, int& num_edges, bool bLarge = false, bool bRecInit = false);
|
||||||
|
|
||||||
void static MergeInertialBA(KeyFrame* pCurrKF, KeyFrame* pMergeKF, bool *pbStopFlag, Map *pMap, LoopClosing::KeyFrameAndPose &corrPoses);
|
void static MergeInertialBA(KeyFrame* pCurrKF, KeyFrame* pMergeKF, bool *pbStopFlag, Map *pMap, LoopClosing::KeyFrameAndPose &corrPoses);
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
#ifndef SYSTEM_H
|
#ifndef SYSTEM_H
|
||||||
#define SYSTEM_H
|
#define SYSTEM_H
|
||||||
|
|
||||||
//#define SAVE_TIMES
|
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include<stdio.h>
|
#include<stdio.h>
|
||||||
#include<stdlib.h>
|
#include<stdlib.h>
|
||||||
|
@ -39,6 +37,7 @@
|
||||||
#include "ORBVocabulary.h"
|
#include "ORBVocabulary.h"
|
||||||
#include "Viewer.h"
|
#include "Viewer.h"
|
||||||
#include "ImuTypes.h"
|
#include "ImuTypes.h"
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
|
|
||||||
namespace ORB_SLAM3
|
namespace ORB_SLAM3
|
||||||
|
@ -162,9 +161,6 @@ public:
|
||||||
void SaveTrajectoryEuRoC(const string &filename);
|
void SaveTrajectoryEuRoC(const string &filename);
|
||||||
void SaveKeyFrameTrajectoryEuRoC(const string &filename);
|
void SaveKeyFrameTrajectoryEuRoC(const string &filename);
|
||||||
|
|
||||||
// Save data used for initialization debug
|
|
||||||
void SaveDebugData(const int &iniIdx);
|
|
||||||
|
|
||||||
// Save camera trajectory in the KITTI dataset format.
|
// Save camera trajectory in the KITTI dataset format.
|
||||||
// Only for stereo and RGB-D. This method does not work for monocular.
|
// Only for stereo and RGB-D. This method does not work for monocular.
|
||||||
// Call first Shutdown()
|
// Call first Shutdown()
|
||||||
|
@ -188,14 +184,14 @@ public:
|
||||||
|
|
||||||
void ChangeDataset();
|
void ChangeDataset();
|
||||||
|
|
||||||
//void SaveAtlas(int type);
|
#ifdef REGISTER_TIMES
|
||||||
|
void InsertRectTime(double& time);
|
||||||
|
|
||||||
|
void InsertTrackTime(double& time);
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//bool LoadAtlas(string filename, int type);
|
|
||||||
|
|
||||||
//string CalculateCheckSum(string filename, int type);
|
|
||||||
|
|
||||||
// Input sensor
|
// Input sensor
|
||||||
eSensor mSensor;
|
eSensor mSensor;
|
||||||
|
|
||||||
|
@ -205,8 +201,7 @@ private:
|
||||||
// KeyFrame database for place recognition (relocalization and loop detection).
|
// KeyFrame database for place recognition (relocalization and loop detection).
|
||||||
KeyFrameDatabase* mpKeyFrameDatabase;
|
KeyFrameDatabase* mpKeyFrameDatabase;
|
||||||
|
|
||||||
// Map structure that stores the pointers to all KeyFrames and MapPoints.
|
// Atlas structure that stores the pointers to all KeyFrames and MapPoints.
|
||||||
//Map* mpMap;
|
|
||||||
Atlas* mpAtlas;
|
Atlas* mpAtlas;
|
||||||
|
|
||||||
// Tracker. It receives a frame and computes the associated camera pose.
|
// Tracker. It receives a frame and computes the associated camera pose.
|
||||||
|
|
|
@ -159,14 +159,30 @@ public:
|
||||||
|
|
||||||
vector<MapPoint*> GetLocalMapMPS();
|
vector<MapPoint*> GetLocalMapMPS();
|
||||||
|
|
||||||
|
|
||||||
//TEST--
|
|
||||||
bool mbNeedRectify;
|
|
||||||
//cv::Mat M1l, M2l;
|
|
||||||
//cv::Mat M1r, M2r;
|
|
||||||
|
|
||||||
bool mbWriteStats;
|
bool mbWriteStats;
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
void LocalMapStats2File();
|
||||||
|
void TrackStats2File();
|
||||||
|
void PrintTimeStats();
|
||||||
|
|
||||||
|
vector<double> vdRectStereo_ms;
|
||||||
|
vector<double> vdORBExtract_ms;
|
||||||
|
vector<double> vdStereoMatch_ms;
|
||||||
|
vector<double> vdIMUInteg_ms;
|
||||||
|
vector<double> vdPosePred_ms;
|
||||||
|
vector<double> vdLMTrack_ms;
|
||||||
|
vector<double> vdNewKF_ms;
|
||||||
|
vector<double> vdTrackTotal_ms;
|
||||||
|
|
||||||
|
vector<double> vdUpdatedLM_ms;
|
||||||
|
vector<double> vdSearchLP_ms;
|
||||||
|
vector<double> vdPoseOpt_ms;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vector<int> vnKeyFramesLM;
|
||||||
|
vector<int> vnMapPointsLM;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Main tracking function. It is independent of the input sensor.
|
// Main tracking function. It is independent of the input sensor.
|
||||||
|
@ -204,7 +220,6 @@ protected:
|
||||||
void PreintegrateIMU();
|
void PreintegrateIMU();
|
||||||
|
|
||||||
// Reset IMU biases and compute frame velocity
|
// Reset IMU biases and compute frame velocity
|
||||||
void ResetFrameIMU();
|
|
||||||
void ComputeGyroBias(const vector<Frame*> &vpFs, float &bwx, float &bwy, float &bwz);
|
void ComputeGyroBias(const vector<Frame*> &vpFs, float &bwx, float &bwy, float &bwz);
|
||||||
void ComputeVelocitiesAccBias(const vector<Frame*> &vpFs, float &bax, float &bay, float &baz);
|
void ComputeVelocitiesAccBias(const vector<Frame*> &vpFs, float &bax, float &bay, float &baz);
|
||||||
|
|
||||||
|
@ -296,6 +311,7 @@ protected:
|
||||||
unsigned int mnLastRelocFrameId;
|
unsigned int mnLastRelocFrameId;
|
||||||
double mTimeStampLost;
|
double mTimeStampLost;
|
||||||
double time_recently_lost;
|
double time_recently_lost;
|
||||||
|
double time_recently_lost_visual;
|
||||||
|
|
||||||
unsigned int mnFirstFrameId;
|
unsigned int mnFirstFrameId;
|
||||||
unsigned int mnInitialFrameId;
|
unsigned int mnInitialFrameId;
|
||||||
|
|
75
src/Atlas.cc
75
src/Atlas.cc
|
@ -260,81 +260,6 @@ bool Atlas::isImuInitialized()
|
||||||
return mpCurrentMap->isImuInitialized();
|
return mpCurrentMap->isImuInitialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Atlas::PreSave()
|
|
||||||
{
|
|
||||||
if(mpCurrentMap){
|
|
||||||
if(!mspMaps.empty() && mnLastInitKFidMap < mpCurrentMap->GetMaxKFid())
|
|
||||||
mnLastInitKFidMap = mpCurrentMap->GetMaxKFid()+1; //The init KF is the next of current maximum
|
|
||||||
}
|
|
||||||
|
|
||||||
struct compFunctor
|
|
||||||
{
|
|
||||||
inline bool operator()(Map* elem1 ,Map* elem2)
|
|
||||||
{
|
|
||||||
return elem1->GetId() < elem2->GetId();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
std::copy(mspMaps.begin(), mspMaps.end(), std::back_inserter(mvpBackupMaps));
|
|
||||||
sort(mvpBackupMaps.begin(), mvpBackupMaps.end(), compFunctor());
|
|
||||||
|
|
||||||
std::set<GeometricCamera*> spCams(mvpCameras.begin(), mvpCameras.end());
|
|
||||||
cout << "There are " << spCams.size() << " cameras in the atlas" << endl;
|
|
||||||
for(Map* pMi : mvpBackupMaps)
|
|
||||||
{
|
|
||||||
cout << "Pre-save of map " << pMi->GetId() << endl;
|
|
||||||
pMi->PreSave(spCams);
|
|
||||||
}
|
|
||||||
cout << "Maps stored" << endl;
|
|
||||||
for(GeometricCamera* pCam : mvpCameras)
|
|
||||||
{
|
|
||||||
cout << "Pre-save of camera " << pCam->GetId() << endl;
|
|
||||||
if(pCam->GetType() == pCam->CAM_PINHOLE)
|
|
||||||
{
|
|
||||||
mvpBackupCamPin.push_back((Pinhole*) pCam);
|
|
||||||
}
|
|
||||||
else if(pCam->GetType() == pCam->CAM_FISHEYE)
|
|
||||||
{
|
|
||||||
mvpBackupCamKan.push_back((KannalaBrandt8*) pCam);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Atlas::PostLoad()
|
|
||||||
{
|
|
||||||
mvpCameras.clear();
|
|
||||||
map<unsigned int,GeometricCamera*> mpCams;
|
|
||||||
for(Pinhole* pCam : mvpBackupCamPin)
|
|
||||||
{
|
|
||||||
//mvpCameras.push_back((GeometricCamera*)pCam);
|
|
||||||
mvpCameras.push_back(pCam);
|
|
||||||
mpCams[pCam->GetId()] = pCam;
|
|
||||||
}
|
|
||||||
for(KannalaBrandt8* pCam : mvpBackupCamKan)
|
|
||||||
{
|
|
||||||
//mvpCameras.push_back((GeometricCamera*)pCam);
|
|
||||||
mvpCameras.push_back(pCam);
|
|
||||||
mpCams[pCam->GetId()] = pCam;
|
|
||||||
}
|
|
||||||
|
|
||||||
mspMaps.clear();
|
|
||||||
unsigned long int numKF = 0, numMP = 0;
|
|
||||||
map<long unsigned int, KeyFrame*> mpAllKeyFrameId;
|
|
||||||
for(Map* pMi : mvpBackupMaps)
|
|
||||||
{
|
|
||||||
cout << "Map id:" << pMi->GetId() << endl;
|
|
||||||
mspMaps.insert(pMi);
|
|
||||||
map<long unsigned int, KeyFrame*> mpKeyFrameId;
|
|
||||||
pMi->PostLoad(mpKeyFrameDB, mpORBVocabulary, mpKeyFrameId, mpCams);
|
|
||||||
mpAllKeyFrameId.insert(mpKeyFrameId.begin(), mpKeyFrameId.end());
|
|
||||||
numKF += pMi->GetAllKeyFrames().size();
|
|
||||||
numMP += pMi->GetAllMapPoints().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
cout << "Number KF:" << numKF << "; number MP:" << numMP << endl;
|
|
||||||
mvpBackupMaps.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Atlas::SetKeyFrameDababase(KeyFrameDatabase* pKFDB)
|
void Atlas::SetKeyFrameDababase(KeyFrameDatabase* pKFDB)
|
||||||
{
|
{
|
||||||
mpKeyFrameDB = pKFDB;
|
mpKeyFrameDB = pKFDB;
|
||||||
|
|
|
@ -20,10 +20,7 @@
|
||||||
|
|
||||||
#include <boost/serialization/export.hpp>
|
#include <boost/serialization/export.hpp>
|
||||||
|
|
||||||
//BOOST_CLASS_EXPORT_IMPLEMENT(ORB_SLAM3::KannalaBrandt8)
|
|
||||||
|
|
||||||
namespace ORB_SLAM3 {
|
namespace ORB_SLAM3 {
|
||||||
//BOOST_CLASS_EXPORT_GUID(KannalaBrandt8, "KannalaBrandt8")
|
|
||||||
|
|
||||||
cv::Point2f KannalaBrandt8::project(const cv::Point3f &p3D) {
|
cv::Point2f KannalaBrandt8::project(const cv::Point3f &p3D) {
|
||||||
const float x2_plus_y2 = p3D.x * p3D.x + p3D.y * p3D.y;
|
const float x2_plus_y2 = p3D.x * p3D.x + p3D.y * p3D.y;
|
||||||
|
@ -43,6 +40,10 @@ namespace ORB_SLAM3 {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cv::Point2f KannalaBrandt8::project(const cv::Matx31f &m3D) {
|
||||||
|
return this->project(cv::Point3f(m3D(0),m3D(1),m3D(2)));
|
||||||
|
}
|
||||||
|
|
||||||
cv::Point2f KannalaBrandt8::project(const cv::Mat &m3D) {
|
cv::Point2f KannalaBrandt8::project(const cv::Mat &m3D) {
|
||||||
const float* p3D = m3D.ptr<float>();
|
const float* p3D = m3D.ptr<float>();
|
||||||
|
|
||||||
|
@ -67,14 +68,6 @@ namespace ORB_SLAM3 {
|
||||||
res[1] = mvParameters[1] * r * sin(psi) + mvParameters[3];
|
res[1] = mvParameters[1] * r * sin(psi) + mvParameters[3];
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
/*cv::Point2f cvres = this->project(cv::Point3f(v3D[0],v3D[1],v3D[2]));
|
|
||||||
|
|
||||||
Eigen::Vector2d res;
|
|
||||||
res[0] = cvres.x;
|
|
||||||
res[1] = cvres.y;
|
|
||||||
|
|
||||||
return res;*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::Mat KannalaBrandt8::projectMat(const cv::Point3f &p3D) {
|
cv::Mat KannalaBrandt8::projectMat(const cv::Point3f &p3D) {
|
||||||
|
@ -85,12 +78,6 @@ namespace ORB_SLAM3 {
|
||||||
|
|
||||||
float KannalaBrandt8::uncertainty2(const Eigen::Matrix<double,2,1> &p2D)
|
float KannalaBrandt8::uncertainty2(const Eigen::Matrix<double,2,1> &p2D)
|
||||||
{
|
{
|
||||||
/*Eigen::Matrix<double,2,1> c;
|
|
||||||
c << mvParameters[2], mvParameters[3];
|
|
||||||
if ((p2D-c).squaredNorm()>57600) // 240*240 (256)
|
|
||||||
return 100.f;
|
|
||||||
else
|
|
||||||
return 1.0f;*/
|
|
||||||
return 1.f;
|
return 1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,6 +87,12 @@ namespace ORB_SLAM3 {
|
||||||
return ret.clone();
|
return ret.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cv::Matx31f KannalaBrandt8::unprojectMat_(const cv::Point2f &p2D) {
|
||||||
|
cv::Point3f ray = this->unproject(p2D);
|
||||||
|
cv::Matx31f r{ray.x, ray.y, ray.z};
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
cv::Point3f KannalaBrandt8::unproject(const cv::Point2f &p2D) {
|
cv::Point3f KannalaBrandt8::unproject(const cv::Point2f &p2D) {
|
||||||
//Use Newthon method to solve for theta with good precision (err ~ e-6)
|
//Use Newthon method to solve for theta with good precision (err ~ e-6)
|
||||||
cv::Point2f pw((p2D.x - mvParameters[2]) / mvParameters[0], (p2D.y - mvParameters[3]) / mvParameters[1]);
|
cv::Point2f pw((p2D.x - mvParameters[2]) / mvParameters[0], (p2D.y - mvParameters[3]) / mvParameters[1]);
|
||||||
|
@ -232,11 +225,22 @@ namespace ORB_SLAM3 {
|
||||||
return K;
|
return K;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cv::Matx33f KannalaBrandt8::toK_() {
|
||||||
|
cv::Matx33f K{mvParameters[0], 0.f, mvParameters[2], 0.f, mvParameters[1], mvParameters[3], 0.f, 0.f, 1.f};
|
||||||
|
|
||||||
|
return K;
|
||||||
|
}
|
||||||
|
|
||||||
bool KannalaBrandt8::epipolarConstrain(GeometricCamera* pCamera2, const cv::KeyPoint &kp1, const cv::KeyPoint &kp2, const cv::Mat &R12, const cv::Mat &t12, const float sigmaLevel, const float unc) {
|
bool KannalaBrandt8::epipolarConstrain(GeometricCamera* pCamera2, const cv::KeyPoint &kp1, const cv::KeyPoint &kp2, const cv::Mat &R12, const cv::Mat &t12, const float sigmaLevel, const float unc) {
|
||||||
cv::Mat p3D;
|
cv::Mat p3D;
|
||||||
return this->TriangulateMatches(pCamera2,kp1,kp2,R12,t12,sigmaLevel,unc,p3D) > 0.0001f;
|
return this->TriangulateMatches(pCamera2,kp1,kp2,R12,t12,sigmaLevel,unc,p3D) > 0.0001f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool KannalaBrandt8::epipolarConstrain_(GeometricCamera* pCamera2, const cv::KeyPoint &kp1, const cv::KeyPoint &kp2, const cv::Matx33f &R12, const cv::Matx31f &t12, const float sigmaLevel, const float unc) {
|
||||||
|
cv::Matx31f p3D;
|
||||||
|
return this->TriangulateMatches_(pCamera2,kp1,kp2,R12,t12,sigmaLevel,unc,p3D) > 0.0001f;
|
||||||
|
}
|
||||||
|
|
||||||
bool KannalaBrandt8::matchAndtriangulate(const cv::KeyPoint& kp1, const cv::KeyPoint& kp2, GeometricCamera* pOther,
|
bool KannalaBrandt8::matchAndtriangulate(const cv::KeyPoint& kp1, const cv::KeyPoint& kp2, GeometricCamera* pOther,
|
||||||
cv::Mat& Tcw1, cv::Mat& Tcw2,
|
cv::Mat& Tcw1, cv::Mat& Tcw2,
|
||||||
const float sigmaLevel1, const float sigmaLevel2,
|
const float sigmaLevel1, const float sigmaLevel2,
|
||||||
|
@ -402,6 +406,79 @@ namespace ORB_SLAM3 {
|
||||||
return z1;
|
return z1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float KannalaBrandt8::TriangulateMatches_(GeometricCamera *pCamera2, const cv::KeyPoint &kp1, const cv::KeyPoint &kp2, const cv::Matx33f &R12, const cv::Matx31f &t12, const float sigmaLevel, const float unc, cv::Matx31f& p3D) {
|
||||||
|
cv::Matx31f r1 = this->unprojectMat_(kp1.pt);
|
||||||
|
cv::Matx31f r2 = pCamera2->unprojectMat_(kp2.pt);
|
||||||
|
|
||||||
|
//Check parallax
|
||||||
|
cv::Matx31f r21 = R12*r2;
|
||||||
|
|
||||||
|
const float cosParallaxRays = r1.dot(r21)/(cv::norm(r1)*cv::norm(r21));
|
||||||
|
|
||||||
|
if(cosParallaxRays > 0.9998){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Parallax is good, so we try to triangulate
|
||||||
|
cv::Point2f p11,p22;
|
||||||
|
|
||||||
|
p11.x = r1(0);
|
||||||
|
p11.y = r1(1);
|
||||||
|
|
||||||
|
p22.x = r2(0);
|
||||||
|
p22.y = r2(1);
|
||||||
|
|
||||||
|
cv::Matx31f x3D;
|
||||||
|
cv::Matx44f Tcw1{1.f,0.f,0.f,0.f,
|
||||||
|
0.f,1.f,0.f,0.f,
|
||||||
|
0.f,0.f,1.f,0.f};
|
||||||
|
|
||||||
|
cv::Matx33f R21 = R12.t();
|
||||||
|
cv::Matx31f t21 = -R21*t12;
|
||||||
|
|
||||||
|
cv::Matx44f Tcw2{R21(0,0),R21(0,1),R21(0,2),t21(0),
|
||||||
|
R21(1,0),R21(1,1),R21(1,2),t21(1),
|
||||||
|
R21(2,0),R21(2,1),R21(2,2),t21(2),
|
||||||
|
0.f,0.f,0.f,1.f};
|
||||||
|
|
||||||
|
Triangulate_(p11,p22,Tcw1,Tcw2,x3D);
|
||||||
|
cv::Matx13f x3Dt = x3D.t();
|
||||||
|
|
||||||
|
float z1 = x3D(2);
|
||||||
|
if(z1 <= 0){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
float z2 = R21.row(2).dot(x3Dt)+t21(2);
|
||||||
|
if(z2<=0){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check reprojection error
|
||||||
|
cv::Point2f uv1 = this->project(x3D);
|
||||||
|
|
||||||
|
float errX1 = uv1.x - kp1.pt.x;
|
||||||
|
float errY1 = uv1.y - kp1.pt.y;
|
||||||
|
|
||||||
|
if((errX1*errX1+errY1*errY1)>5.991 * sigmaLevel){ //Reprojection error is high
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Matx31f x3D2 = R21 * x3D + t21;
|
||||||
|
cv::Point2f uv2 = pCamera2->project(x3D2);
|
||||||
|
|
||||||
|
float errX2 = uv2.x - kp2.pt.x;
|
||||||
|
float errY2 = uv2.y - kp2.pt.y;
|
||||||
|
|
||||||
|
if((errX2*errX2+errY2*errY2)>5.991 * unc){ //Reprojection error is high
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p3D = x3D;
|
||||||
|
|
||||||
|
return z1;
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream & operator<<(std::ostream &os, const KannalaBrandt8 &kb) {
|
std::ostream & operator<<(std::ostream &os, const KannalaBrandt8 &kb) {
|
||||||
os << kb.mvParameters[0] << " " << kb.mvParameters[1] << " " << kb.mvParameters[2] << " " << kb.mvParameters[3] << " "
|
os << kb.mvParameters[0] << " " << kb.mvParameters[1] << " " << kb.mvParameters[2] << " " << kb.mvParameters[3] << " "
|
||||||
<< kb.mvParameters[4] << " " << kb.mvParameters[5] << " " << kb.mvParameters[6] << " " << kb.mvParameters[7];
|
<< kb.mvParameters[4] << " " << kb.mvParameters[5] << " " << kb.mvParameters[6] << " " << kb.mvParameters[7];
|
||||||
|
@ -433,4 +510,27 @@ namespace ORB_SLAM3 {
|
||||||
x3D = vt.row(3).t();
|
x3D = vt.row(3).t();
|
||||||
x3D = x3D.rowRange(0,3)/x3D.at<float>(3);
|
x3D = x3D.rowRange(0,3)/x3D.at<float>(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KannalaBrandt8::Triangulate_(const cv::Point2f &p1, const cv::Point2f &p2, const cv::Matx44f &Tcw1, const cv::Matx44f &Tcw2, cv::Matx31f &x3D)
|
||||||
|
{
|
||||||
|
cv::Matx14f A0, A1, A2, A3;
|
||||||
|
|
||||||
|
|
||||||
|
A0 = p1.x * Tcw1.row(2) - Tcw1.row(0);
|
||||||
|
A1 = p1.y * Tcw1.row(2) - Tcw1.row(1);
|
||||||
|
A2 = p2.x * Tcw2.row(2) - Tcw2.row(0);
|
||||||
|
A3 = p2.y * Tcw2.row(2) - Tcw2.row(1);
|
||||||
|
cv::Matx44f A{A0(0), A0(1), A0(2), A0(3),
|
||||||
|
A1(0), A1(1), A1(2), A1(3),
|
||||||
|
A2(0), A2(1), A2(2), A2(3),
|
||||||
|
A3(0), A3(1), A3(2), A3(3)};
|
||||||
|
|
||||||
|
// cv::Mat u,w,vt;
|
||||||
|
cv::Matx44f u, vt;
|
||||||
|
cv::Matx41f w;
|
||||||
|
|
||||||
|
cv::SVD::compute(A,w,u,vt,cv::SVD::MODIFY_A| cv::SVD::FULL_UV);
|
||||||
|
cv::Matx41f x3D_h = vt.row(3).t();
|
||||||
|
x3D = x3D_h.get_minor<3,1>(0,0) / x3D_h(3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,10 +20,7 @@
|
||||||
|
|
||||||
#include <boost/serialization/export.hpp>
|
#include <boost/serialization/export.hpp>
|
||||||
|
|
||||||
//BOOST_CLASS_EXPORT_IMPLEMENT(ORB_SLAM3::Pinhole)
|
|
||||||
|
|
||||||
namespace ORB_SLAM3 {
|
namespace ORB_SLAM3 {
|
||||||
//BOOST_CLASS_EXPORT_GUID(Pinhole, "Pinhole")
|
|
||||||
|
|
||||||
long unsigned int GeometricCamera::nNextId=0;
|
long unsigned int GeometricCamera::nNextId=0;
|
||||||
|
|
||||||
|
@ -32,6 +29,10 @@ namespace ORB_SLAM3 {
|
||||||
mvParameters[1] * p3D.y / p3D.z + mvParameters[3]);
|
mvParameters[1] * p3D.y / p3D.z + mvParameters[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cv::Point2f Pinhole::project(const cv::Matx31f &m3D) {
|
||||||
|
return this->project(cv::Point3f(m3D(0),m3D(1),m3D(2)));
|
||||||
|
}
|
||||||
|
|
||||||
cv::Point2f Pinhole::project(const cv::Mat &m3D) {
|
cv::Point2f Pinhole::project(const cv::Mat &m3D) {
|
||||||
const float* p3D = m3D.ptr<float>();
|
const float* p3D = m3D.ptr<float>();
|
||||||
|
|
||||||
|
@ -66,6 +67,12 @@ namespace ORB_SLAM3 {
|
||||||
return (cv::Mat_<float>(3,1) << ray.x, ray.y, ray.z);
|
return (cv::Mat_<float>(3,1) << ray.x, ray.y, ray.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cv::Matx31f Pinhole::unprojectMat_(const cv::Point2f &p2D) {
|
||||||
|
cv::Point3f ray = this->unproject(p2D);
|
||||||
|
cv::Matx31f r{ray.x, ray.y, ray.z};
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
cv::Mat Pinhole::projectJac(const cv::Point3f &p3D) {
|
cv::Mat Pinhole::projectJac(const cv::Point3f &p3D) {
|
||||||
cv::Mat Jac(2, 3, CV_32F);
|
cv::Mat Jac(2, 3, CV_32F);
|
||||||
Jac.at<float>(0, 0) = mvParameters[0] / p3D.z;
|
Jac.at<float>(0, 0) = mvParameters[0] / p3D.z;
|
||||||
|
@ -119,6 +126,12 @@ namespace ORB_SLAM3 {
|
||||||
return K;
|
return K;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cv::Matx33f Pinhole::toK_() {
|
||||||
|
cv::Matx33f K{mvParameters[0], 0.f, mvParameters[2], 0.f, mvParameters[1], mvParameters[3], 0.f, 0.f, 1.f};
|
||||||
|
|
||||||
|
return K;
|
||||||
|
}
|
||||||
|
|
||||||
bool Pinhole::epipolarConstrain(GeometricCamera* pCamera2, const cv::KeyPoint &kp1, const cv::KeyPoint &kp2, const cv::Mat &R12, const cv::Mat &t12, const float sigmaLevel, const float unc) {
|
bool Pinhole::epipolarConstrain(GeometricCamera* pCamera2, const cv::KeyPoint &kp1, const cv::KeyPoint &kp2, const cv::Mat &R12, const cv::Mat &t12, const float sigmaLevel, const float unc) {
|
||||||
//Compute Fundamental Matrix
|
//Compute Fundamental Matrix
|
||||||
cv::Mat t12x = SkewSymmetricMatrix(t12);
|
cv::Mat t12x = SkewSymmetricMatrix(t12);
|
||||||
|
@ -143,6 +156,30 @@ namespace ORB_SLAM3 {
|
||||||
return dsqr<3.84*unc;
|
return dsqr<3.84*unc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Pinhole::epipolarConstrain_(GeometricCamera *pCamera2, const cv::KeyPoint &kp1, const cv::KeyPoint &kp2, const cv::Matx33f &R12, const cv::Matx31f &t12, const float sigmaLevel, const float unc) {
|
||||||
|
//Compute Fundamental Matrix
|
||||||
|
auto t12x = SkewSymmetricMatrix_(t12);
|
||||||
|
auto K1 = this->toK_();
|
||||||
|
auto K2 = pCamera2->toK_();
|
||||||
|
cv::Matx33f F12 = K1.t().inv()*t12x*R12*K2.inv();
|
||||||
|
|
||||||
|
// Epipolar line in second image l = x1'F12 = [a b c]
|
||||||
|
const float a = kp1.pt.x*F12(0,0)+kp1.pt.y*F12(1,0)+F12(2,0);
|
||||||
|
const float b = kp1.pt.x*F12(0,1)+kp1.pt.y*F12(1,1)+F12(2,1);
|
||||||
|
const float c = kp1.pt.x*F12(0,2)+kp1.pt.y*F12(1,2)+F12(2,2);
|
||||||
|
|
||||||
|
const float num = a*kp2.pt.x+b*kp2.pt.y+c;
|
||||||
|
|
||||||
|
const float den = a*a+b*b;
|
||||||
|
|
||||||
|
if(den==0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const float dsqr = num*num/den;
|
||||||
|
|
||||||
|
return dsqr<3.84*unc;
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream & operator<<(std::ostream &os, const Pinhole &ph) {
|
std::ostream & operator<<(std::ostream &os, const Pinhole &ph) {
|
||||||
os << ph.mvParameters[0] << " " << ph.mvParameters[1] << " " << ph.mvParameters[2] << " " << ph.mvParameters[3];
|
os << ph.mvParameters[0] << " " << ph.mvParameters[1] << " " << ph.mvParameters[2] << " " << ph.mvParameters[3];
|
||||||
return os;
|
return os;
|
||||||
|
@ -165,4 +202,13 @@ namespace ORB_SLAM3 {
|
||||||
v.at<float>(2), 0,-v.at<float>(0),
|
v.at<float>(2), 0,-v.at<float>(0),
|
||||||
-v.at<float>(1), v.at<float>(0), 0);
|
-v.at<float>(1), v.at<float>(0), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cv::Matx33f Pinhole::SkewSymmetricMatrix_(const cv::Matx31f &v)
|
||||||
|
{
|
||||||
|
cv::Matx33f skew{0.f, -v(2), v(1),
|
||||||
|
v(2), 0.f, -v(0),
|
||||||
|
-v(1), v(0), 0.f};
|
||||||
|
|
||||||
|
return skew;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
162
src/Frame.cc
162
src/Frame.cc
|
@ -49,6 +49,10 @@ cv::BFMatcher Frame::BFmatcher = cv::BFMatcher(cv::NORM_HAMMING);
|
||||||
|
|
||||||
Frame::Frame(): mpcpi(NULL), mpImuPreintegrated(NULL), mpPrevFrame(NULL), mpImuPreintegratedFrame(NULL), mpReferenceKF(static_cast<KeyFrame*>(NULL)), mbImuPreintegrated(false)
|
Frame::Frame(): mpcpi(NULL), mpImuPreintegrated(NULL), mpPrevFrame(NULL), mpImuPreintegratedFrame(NULL), mpReferenceKF(static_cast<KeyFrame*>(NULL)), mbImuPreintegrated(false)
|
||||||
{
|
{
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
mTimeStereoMatch = 0;
|
||||||
|
mTimeORB_Ext = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,7 +73,8 @@ Frame::Frame(const Frame &frame)
|
||||||
mpCamera(frame.mpCamera), mpCamera2(frame.mpCamera2), Nleft(frame.Nleft), Nright(frame.Nright),
|
mpCamera(frame.mpCamera), mpCamera2(frame.mpCamera2), Nleft(frame.Nleft), Nright(frame.Nright),
|
||||||
monoLeft(frame.monoLeft), monoRight(frame.monoRight), mvLeftToRightMatch(frame.mvLeftToRightMatch),
|
monoLeft(frame.monoLeft), monoRight(frame.monoRight), mvLeftToRightMatch(frame.mvLeftToRightMatch),
|
||||||
mvRightToLeftMatch(frame.mvRightToLeftMatch), mvStereo3Dpoints(frame.mvStereo3Dpoints),
|
mvRightToLeftMatch(frame.mvRightToLeftMatch), mvStereo3Dpoints(frame.mvStereo3Dpoints),
|
||||||
mTlr(frame.mTlr.clone()), mRlr(frame.mRlr.clone()), mtlr(frame.mtlr.clone()), mTrl(frame.mTrl.clone()), mTimeStereoMatch(frame.mTimeStereoMatch), mTimeORB_Ext(frame.mTimeORB_Ext)
|
mTlr(frame.mTlr.clone()), mRlr(frame.mRlr.clone()), mtlr(frame.mtlr.clone()), mTrl(frame.mTrl.clone()),
|
||||||
|
mTrlx(frame.mTrlx), mTlrx(frame.mTlrx), mOwx(frame.mOwx), mRcwx(frame.mRcwx), mtcwx(frame.mtcwx)
|
||||||
{
|
{
|
||||||
for(int i=0;i<FRAME_GRID_COLS;i++)
|
for(int i=0;i<FRAME_GRID_COLS;i++)
|
||||||
for(int j=0; j<FRAME_GRID_ROWS; j++){
|
for(int j=0; j<FRAME_GRID_ROWS; j++){
|
||||||
|
@ -87,13 +92,18 @@ Frame::Frame(const Frame &frame)
|
||||||
|
|
||||||
mmProjectPoints = frame.mmProjectPoints;
|
mmProjectPoints = frame.mmProjectPoints;
|
||||||
mmMatchedInImage = frame.mmMatchedInImage;
|
mmMatchedInImage = frame.mmMatchedInImage;
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
mTimeStereoMatch = frame.mTimeStereoMatch;
|
||||||
|
mTimeORB_Ext = frame.mTimeORB_Ext;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Frame::Frame(const cv::Mat &imLeft, const cv::Mat &imRight, const double &timeStamp, ORBextractor* extractorLeft, ORBextractor* extractorRight, ORBVocabulary* voc, cv::Mat &K, cv::Mat &distCoef, const float &bf, const float &thDepth, GeometricCamera* pCamera, Frame* pPrevF, const IMU::Calib &ImuCalib)
|
Frame::Frame(const cv::Mat &imLeft, const cv::Mat &imRight, const double &timeStamp, ORBextractor* extractorLeft, ORBextractor* extractorRight, ORBVocabulary* voc, cv::Mat &K, cv::Mat &distCoef, const float &bf, const float &thDepth, GeometricCamera* pCamera, Frame* pPrevF, const IMU::Calib &ImuCalib)
|
||||||
:mpcpi(NULL), mpORBvocabulary(voc),mpORBextractorLeft(extractorLeft),mpORBextractorRight(extractorRight), mTimeStamp(timeStamp), mK(K.clone()), mDistCoef(distCoef.clone()), mbf(bf), mThDepth(thDepth),
|
:mpcpi(NULL), mpORBvocabulary(voc),mpORBextractorLeft(extractorLeft),mpORBextractorRight(extractorRight), mTimeStamp(timeStamp), mK(K.clone()), mDistCoef(distCoef.clone()), mbf(bf), mThDepth(thDepth),
|
||||||
mImuCalib(ImuCalib), mpImuPreintegrated(NULL), mpPrevFrame(pPrevF),mpImuPreintegratedFrame(NULL), mpReferenceKF(static_cast<KeyFrame*>(NULL)), mbImuPreintegrated(false),
|
mImuCalib(ImuCalib), mpImuPreintegrated(NULL), mpPrevFrame(pPrevF),mpImuPreintegratedFrame(NULL), mpReferenceKF(static_cast<KeyFrame*>(NULL)), mbImuPreintegrated(false),
|
||||||
mpCamera(pCamera) ,mpCamera2(nullptr), mTimeStereoMatch(0), mTimeORB_Ext(0)
|
mpCamera(pCamera) ,mpCamera2(nullptr)
|
||||||
{
|
{
|
||||||
// Step 1 帧的ID 自增
|
// Step 1 帧的ID 自增
|
||||||
mnId=nNextId++;
|
mnId=nNextId++;
|
||||||
|
@ -116,12 +126,20 @@ Frame::Frame(const cv::Mat &imLeft, const cv::Mat &imRight, const double &timeSt
|
||||||
|
|
||||||
// ORB extraction
|
// ORB extraction
|
||||||
// Step 3 对左目右目图像提取ORB特征点, 第一个参数0-左图, 1-右图。为加速计算,同时开了两个线程计算
|
// Step 3 对左目右目图像提取ORB特征点, 第一个参数0-左图, 1-右图。为加速计算,同时开了两个线程计算
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_StartExtORB = std::chrono::steady_clock::now();
|
||||||
|
#endif
|
||||||
thread threadLeft(&Frame::ExtractORB,this,0,imLeft,0,0);
|
thread threadLeft(&Frame::ExtractORB,this,0,imLeft,0,0);
|
||||||
// 对右目图像提取orb特征
|
// 对右目图像提取orb特征
|
||||||
thread threadRight(&Frame::ExtractORB,this,1,imRight,0,0);
|
thread threadRight(&Frame::ExtractORB,this,1,imRight,0,0);
|
||||||
//等待两张图像特征点提取过程完成
|
//等待两张图像特征点提取过程完成
|
||||||
threadLeft.join();
|
threadLeft.join();
|
||||||
threadRight.join();
|
threadRight.join();
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_EndExtORB = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
mTimeORB_Ext = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndExtORB - time_StartExtORB).count();
|
||||||
|
#endif
|
||||||
|
|
||||||
//mvKeys中保存的是左图像中的特征点,这里是获取左侧图像中特征点的个数
|
//mvKeys中保存的是左图像中的特征点,这里是获取左侧图像中特征点的个数
|
||||||
N = mvKeys.size();
|
N = mvKeys.size();
|
||||||
|
@ -133,13 +151,20 @@ Frame::Frame(const cv::Mat &imLeft, const cv::Mat &imRight, const double &timeSt
|
||||||
// Step 4 用OpenCV的矫正函数、内参对提取到的特征点进行矫正
|
// Step 4 用OpenCV的矫正函数、内参对提取到的特征点进行矫正
|
||||||
UndistortKeyPoints();
|
UndistortKeyPoints();
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_StartStereoMatches = std::chrono::steady_clock::now();
|
||||||
|
#endif
|
||||||
// Step 5 计算双目间特征点的匹配,只有匹配成功的特征点会计算其深度,深度存放在 mvDepth
|
// Step 5 计算双目间特征点的匹配,只有匹配成功的特征点会计算其深度,深度存放在 mvDepth
|
||||||
// mvuRight中存储的应该是左图像中的点所匹配的在右图像中的点的横坐标(纵坐标相同)
|
// mvuRight中存储的应该是左图像中的点所匹配的在右图像中的点的横坐标(纵坐标相同)
|
||||||
ComputeStereoMatches();
|
ComputeStereoMatches();
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_EndStereoMatches = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
mTimeStereoMatch = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndStereoMatches - time_StartStereoMatches).count();
|
||||||
|
#endif
|
||||||
|
|
||||||
// 初始化本帧的地图点
|
// 初始化本帧的地图点
|
||||||
mvpMapPoints = vector<MapPoint*>(N,static_cast<MapPoint*>(NULL));
|
mvpMapPoints = vector<MapPoint*>(N,static_cast<MapPoint*>(NULL));
|
||||||
// 记录地图点是否为外点,初始化均为外点false
|
|
||||||
mvbOutlier = vector<bool>(N,false);
|
mvbOutlier = vector<bool>(N,false);
|
||||||
mmProjectPoints.clear();// = map<long unsigned int, cv::Point2f>(N, static_cast<cv::Point2f>(NULL));
|
mmProjectPoints.clear();// = map<long unsigned int, cv::Point2f>(N, static_cast<cv::Point2f>(NULL));
|
||||||
mmMatchedInImage.clear();
|
mmMatchedInImage.clear();
|
||||||
|
@ -204,7 +229,7 @@ Frame::Frame(const cv::Mat &imGray, const cv::Mat &imDepth, const double &timeSt
|
||||||
:mpcpi(NULL),mpORBvocabulary(voc),mpORBextractorLeft(extractor),mpORBextractorRight(static_cast<ORBextractor*>(NULL)),
|
:mpcpi(NULL),mpORBvocabulary(voc),mpORBextractorLeft(extractor),mpORBextractorRight(static_cast<ORBextractor*>(NULL)),
|
||||||
mTimeStamp(timeStamp), mK(K.clone()),mDistCoef(distCoef.clone()), mbf(bf), mThDepth(thDepth),
|
mTimeStamp(timeStamp), mK(K.clone()),mDistCoef(distCoef.clone()), mbf(bf), mThDepth(thDepth),
|
||||||
mImuCalib(ImuCalib), mpImuPreintegrated(NULL), mpPrevFrame(pPrevF), mpImuPreintegratedFrame(NULL), mpReferenceKF(static_cast<KeyFrame*>(NULL)), mbImuPreintegrated(false),
|
mImuCalib(ImuCalib), mpImuPreintegrated(NULL), mpPrevFrame(pPrevF), mpImuPreintegratedFrame(NULL), mpReferenceKF(static_cast<KeyFrame*>(NULL)), mbImuPreintegrated(false),
|
||||||
mpCamera(pCamera),mpCamera2(nullptr), mTimeStereoMatch(0), mTimeORB_Ext(0)
|
mpCamera(pCamera),mpCamera2(nullptr)
|
||||||
{
|
{
|
||||||
// Step 1 帧的ID 自增
|
// Step 1 帧的ID 自增
|
||||||
mnId=nNextId++;
|
mnId=nNextId++;
|
||||||
|
@ -225,11 +250,11 @@ Frame::Frame(const cv::Mat &imGray, const cv::Mat &imDepth, const double &timeSt
|
||||||
mvInvLevelSigma2 = mpORBextractorLeft->GetInverseScaleSigmaSquares();
|
mvInvLevelSigma2 = mpORBextractorLeft->GetInverseScaleSigmaSquares();
|
||||||
|
|
||||||
// ORB extraction
|
// ORB extraction
|
||||||
#ifdef SAVE_TIMES
|
#ifdef REGISTER_TIMES
|
||||||
std::chrono::steady_clock::time_point time_StartExtORB = std::chrono::steady_clock::now();
|
std::chrono::steady_clock::time_point time_StartExtORB = std::chrono::steady_clock::now();
|
||||||
#endif
|
#endif
|
||||||
ExtractORB(0,imGray,0,0);
|
ExtractORB(0,imGray,0,0);
|
||||||
#ifdef SAVE_TIMES
|
#ifdef REGISTER_TIMES
|
||||||
std::chrono::steady_clock::time_point time_EndExtORB = std::chrono::steady_clock::now();
|
std::chrono::steady_clock::time_point time_EndExtORB = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
mTimeORB_Ext = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndExtORB - time_StartExtORB).count();
|
mTimeORB_Ext = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndExtORB - time_StartExtORB).count();
|
||||||
|
@ -305,7 +330,7 @@ Frame::Frame(const cv::Mat &imGray, const double &timeStamp, ORBextractor* extra
|
||||||
:mpcpi(NULL),mpORBvocabulary(voc),mpORBextractorLeft(extractor),mpORBextractorRight(static_cast<ORBextractor*>(NULL)),
|
:mpcpi(NULL),mpORBvocabulary(voc),mpORBextractorLeft(extractor),mpORBextractorRight(static_cast<ORBextractor*>(NULL)),
|
||||||
mTimeStamp(timeStamp), mK(static_cast<Pinhole*>(pCamera)->toK()), mDistCoef(distCoef.clone()), mbf(bf), mThDepth(thDepth),
|
mTimeStamp(timeStamp), mK(static_cast<Pinhole*>(pCamera)->toK()), mDistCoef(distCoef.clone()), mbf(bf), mThDepth(thDepth),
|
||||||
mImuCalib(ImuCalib), mpImuPreintegrated(NULL),mpPrevFrame(pPrevF),mpImuPreintegratedFrame(NULL), mpReferenceKF(static_cast<KeyFrame*>(NULL)), mbImuPreintegrated(false), mpCamera(pCamera),
|
mImuCalib(ImuCalib), mpImuPreintegrated(NULL),mpPrevFrame(pPrevF),mpImuPreintegratedFrame(NULL), mpReferenceKF(static_cast<KeyFrame*>(NULL)), mbImuPreintegrated(false), mpCamera(pCamera),
|
||||||
mpCamera2(nullptr), mTimeStereoMatch(0), mTimeORB_Ext(0)
|
mpCamera2(nullptr)
|
||||||
{
|
{
|
||||||
// Frame ID
|
// Frame ID
|
||||||
// Step 1 帧的ID 自增
|
// Step 1 帧的ID 自增
|
||||||
|
@ -329,12 +354,12 @@ Frame::Frame(const cv::Mat &imGray, const double &timeStamp, ORBextractor* extra
|
||||||
mvInvLevelSigma2 = mpORBextractorLeft->GetInverseScaleSigmaSquares();
|
mvInvLevelSigma2 = mpORBextractorLeft->GetInverseScaleSigmaSquares();
|
||||||
|
|
||||||
// ORB extraction
|
// ORB extraction
|
||||||
#ifdef SAVE_TIMES
|
#ifdef REGISTER_TIMES
|
||||||
std::chrono::steady_clock::time_point time_StartExtORB = std::chrono::steady_clock::now();
|
std::chrono::steady_clock::time_point time_StartExtORB = std::chrono::steady_clock::now();
|
||||||
#endif
|
#endif
|
||||||
// Step 3 对这个单目图像进行提取特征点, 第一个参数0-左图, 1-右图
|
// Step 3 对这个单目图像进行提取特征点, 第一个参数0-左图, 1-右图
|
||||||
ExtractORB(0,imGray,0,1000);
|
ExtractORB(0,imGray,0,1000);
|
||||||
#ifdef SAVE_TIMES
|
#ifdef REGISTER_TIMES
|
||||||
std::chrono::steady_clock::time_point time_EndExtORB = std::chrono::steady_clock::now();
|
std::chrono::steady_clock::time_point time_EndExtORB = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
mTimeORB_Ext = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndExtORB - time_StartExtORB).count();
|
mTimeORB_Ext = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndExtORB - time_StartExtORB).count();
|
||||||
|
@ -532,6 +557,14 @@ void Frame::UpdatePoseMatrices()
|
||||||
|
|
||||||
// mTcw 求逆后是当前相机坐标系变换到世界坐标系下,对应的光心变换到世界坐标系下就是 mTcw的逆 中对应的平移向量
|
// mTcw 求逆后是当前相机坐标系变换到世界坐标系下,对应的光心变换到世界坐标系下就是 mTcw的逆 中对应的平移向量
|
||||||
mOw = -mRcw.t()*mtcw;
|
mOw = -mRcw.t()*mtcw;
|
||||||
|
|
||||||
|
// Static matrix
|
||||||
|
mOwx = cv::Matx31f(mOw.at<float>(0), mOw.at<float>(1), mOw.at<float>(2));
|
||||||
|
mRcwx = cv::Matx33f(mRcw.at<float>(0,0), mRcw.at<float>(0,1), mRcw.at<float>(0,2),
|
||||||
|
mRcw.at<float>(1,0), mRcw.at<float>(1,1), mRcw.at<float>(1,2),
|
||||||
|
mRcw.at<float>(2,0), mRcw.at<float>(2,1), mRcw.at<float>(2,2));
|
||||||
|
mtcwx = cv::Matx31f(mtcw.at<float>(0), mtcw.at<float>(1), mtcw.at<float>(2));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::Mat Frame::GetImuPosition()
|
cv::Mat Frame::GetImuPosition()
|
||||||
|
@ -579,17 +612,17 @@ bool Frame::isInFrustum(MapPoint *pMP, float viewingCosLimit)
|
||||||
|
|
||||||
// 3D in absolute coordinates
|
// 3D in absolute coordinates
|
||||||
// Step 1 获得这个地图点的世界坐标
|
// Step 1 获得这个地图点的世界坐标
|
||||||
cv::Mat P = pMP->GetWorldPos();
|
cv::Matx31f Px = pMP->GetWorldPos2();
|
||||||
|
|
||||||
// cout << "b";
|
// cout << "b";
|
||||||
|
|
||||||
// 3D in camera coordinates
|
// 3D in camera coordinates
|
||||||
// 根据当前帧(粗糙)位姿转化到当前相机坐标系下的三维点Pc
|
// 根据当前帧(粗糙)位姿转化到当前相机坐标系下的三维点Pc
|
||||||
const cv::Mat Pc = mRcw*P+mtcw;
|
const cv::Matx31f Pc = mRcwx * Px + mtcwx;
|
||||||
const float Pc_dist = cv::norm(Pc);
|
const float Pc_dist = cv::norm(Pc);
|
||||||
|
|
||||||
// Check positive depth
|
// Check positive depth
|
||||||
const float &PcZ = Pc.at<float>(2);
|
const float &PcZ = Pc(2);
|
||||||
const float invz = 1.0f/PcZ;
|
const float invz = 1.0f/PcZ;
|
||||||
// Step 2 关卡一:检查这个地图点在当前帧的相机坐标系下,是否有正的深度.如果是负的,表示出错,直接返回false
|
// Step 2 关卡一:检查这个地图点在当前帧的相机坐标系下,是否有正的深度.如果是负的,表示出错,直接返回false
|
||||||
if(PcZ<0.0f)
|
if(PcZ<0.0f)
|
||||||
|
@ -615,7 +648,7 @@ bool Frame::isInFrustum(MapPoint *pMP, float viewingCosLimit)
|
||||||
const float minDistance = pMP->GetMinDistanceInvariance();
|
const float minDistance = pMP->GetMinDistanceInvariance();
|
||||||
// 得到当前地图点距离当前帧相机光心的距离,注意P,mOw都是在同一坐标系下才可以
|
// 得到当前地图点距离当前帧相机光心的距离,注意P,mOw都是在同一坐标系下才可以
|
||||||
// mOw:当前相机光心在世界坐标系下坐标
|
// mOw:当前相机光心在世界坐标系下坐标
|
||||||
const cv::Mat PO = P-mOw;
|
const cv::Matx31f PO = Px-mOwx;
|
||||||
//取模就得到了距离
|
//取模就得到了距离
|
||||||
const float dist = cv::norm(PO);
|
const float dist = cv::norm(PO);
|
||||||
|
|
||||||
|
@ -627,11 +660,11 @@ bool Frame::isInFrustum(MapPoint *pMP, float viewingCosLimit)
|
||||||
|
|
||||||
// Check viewing angle
|
// Check viewing angle
|
||||||
// Step 5 关卡四:计算当前相机指向地图点向量和地图点的平均观测方向夹角的余弦值, 若小于cos(viewingCosLimit), 即夹角大于viewingCosLimit弧度则返回
|
// Step 5 关卡四:计算当前相机指向地图点向量和地图点的平均观测方向夹角的余弦值, 若小于cos(viewingCosLimit), 即夹角大于viewingCosLimit弧度则返回
|
||||||
cv::Mat Pn = pMP->GetNormal();
|
cv::Matx31f Pnx = pMP->GetNormal2();
|
||||||
|
|
||||||
// cout << "f";
|
// cout << "f";
|
||||||
// 计算当前相机指向地图点向量和地图点的平均观测方向夹角的余弦值,注意平均观测方向为单位向量
|
// 计算当前相机指向地图点向量和地图点的平均观测方向夹角的余弦值,注意平均观测方向为单位向量
|
||||||
const float viewCos = PO.dot(Pn)/dist;
|
const float viewCos = PO.dot(Pnx)/dist;
|
||||||
|
|
||||||
//如果大于给定的阈值 cos(60°)=0.5,认为这个点方向太偏了,重投影不可靠,返回false
|
//如果大于给定的阈值 cos(60°)=0.5,认为这个点方向太偏了,重投影不可靠,返回false
|
||||||
if(viewCos<viewingCosLimit)
|
if(viewCos<viewingCosLimit)
|
||||||
|
@ -1133,11 +1166,7 @@ void Frame::ComputeStereoMatches()
|
||||||
const int w = 5;
|
const int w = 5;
|
||||||
// 提取左图中,以特征点(scaleduL,scaledvL)为中心, 半径为w的图像快patch
|
// 提取左图中,以特征点(scaleduL,scaledvL)为中心, 半径为w的图像快patch
|
||||||
cv::Mat IL = mpORBextractorLeft->mvImagePyramid[kpL.octave].rowRange(scaledvL-w,scaledvL+w+1).colRange(scaleduL-w,scaleduL+w+1);
|
cv::Mat IL = mpORBextractorLeft->mvImagePyramid[kpL.octave].rowRange(scaledvL-w,scaledvL+w+1).colRange(scaleduL-w,scaleduL+w+1);
|
||||||
//IL.convertTo(IL,CV_32F);
|
|
||||||
// 图像块均值归一化,降低亮度变化对相似度计算的影响
|
|
||||||
//IL = IL - IL.at<float>(w,w) *cv::Mat::ones(IL.rows,IL.cols,CV_32F);
|
|
||||||
IL.convertTo(IL,CV_16S);
|
|
||||||
IL = IL - IL.at<short>(w,w);
|
|
||||||
//初始化最佳相似度
|
//初始化最佳相似度
|
||||||
int bestDist = INT_MAX;
|
int bestDist = INT_MAX;
|
||||||
// 通过滑动窗口搜索优化,得到的列坐标偏移量
|
// 通过滑动窗口搜索优化,得到的列坐标偏移量
|
||||||
|
@ -1163,11 +1192,7 @@ void Frame::ComputeStereoMatches()
|
||||||
{
|
{
|
||||||
// 提取左图中,以特征点(scaleduL,scaledvL)为中心, 半径为w的图像快patch
|
// 提取左图中,以特征点(scaleduL,scaledvL)为中心, 半径为w的图像快patch
|
||||||
cv::Mat IR = mpORBextractorRight->mvImagePyramid[kpL.octave].rowRange(scaledvL-w,scaledvL+w+1).colRange(scaleduR0+incR-w,scaleduR0+incR+w+1);
|
cv::Mat IR = mpORBextractorRight->mvImagePyramid[kpL.octave].rowRange(scaledvL-w,scaledvL+w+1).colRange(scaleduR0+incR-w,scaleduR0+incR+w+1);
|
||||||
//IR.convertTo(IR,CV_32F);
|
|
||||||
// 图像块均值归一化,降低亮度变化对相似度计算的影响
|
|
||||||
//IR = IR - IR.at<float>(w,w) *cv::Mat::ones(IR.rows,IR.cols,CV_32F);
|
|
||||||
IR.convertTo(IR,CV_16S);
|
|
||||||
IR = IR - IR.at<short>(w,w);
|
|
||||||
// sad 计算
|
// sad 计算
|
||||||
float dist = cv::norm(IL,IR,cv::NORM_L1);
|
float dist = cv::norm(IL,IR,cv::NORM_L1);
|
||||||
// 统计最小sad和偏移量
|
// 统计最小sad和偏移量
|
||||||
|
@ -1316,10 +1341,8 @@ Frame::Frame(const cv::Mat &imLeft, const cv::Mat &imRight, const double &timeSt
|
||||||
:mpcpi(NULL), mpORBvocabulary(voc),mpORBextractorLeft(extractorLeft),mpORBextractorRight(extractorRight), mTimeStamp(timeStamp), mK(K.clone()), mDistCoef(distCoef.clone()), mbf(bf), mThDepth(thDepth),
|
:mpcpi(NULL), mpORBvocabulary(voc),mpORBextractorLeft(extractorLeft),mpORBextractorRight(extractorRight), mTimeStamp(timeStamp), mK(K.clone()), mDistCoef(distCoef.clone()), mbf(bf), mThDepth(thDepth),
|
||||||
mImuCalib(ImuCalib), mpImuPreintegrated(NULL), mpPrevFrame(pPrevF),mpImuPreintegratedFrame(NULL), mpReferenceKF(static_cast<KeyFrame*>(NULL)), mbImuPreintegrated(false), mpCamera(pCamera), mpCamera2(pCamera2), mTlr(Tlr)
|
mImuCalib(ImuCalib), mpImuPreintegrated(NULL), mpPrevFrame(pPrevF),mpImuPreintegratedFrame(NULL), mpReferenceKF(static_cast<KeyFrame*>(NULL)), mbImuPreintegrated(false), mpCamera(pCamera), mpCamera2(pCamera2), mTlr(Tlr)
|
||||||
{
|
{
|
||||||
std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
|
|
||||||
imgLeft = imLeft.clone();
|
imgLeft = imLeft.clone();
|
||||||
imgRight = imRight.clone();
|
imgRight = imRight.clone();
|
||||||
std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
// Frame ID
|
// Frame ID
|
||||||
mnId=nNextId++;
|
mnId=nNextId++;
|
||||||
|
@ -1334,11 +1357,18 @@ Frame::Frame(const cv::Mat &imLeft, const cv::Mat &imRight, const double &timeSt
|
||||||
mvInvLevelSigma2 = mpORBextractorLeft->GetInverseScaleSigmaSquares();
|
mvInvLevelSigma2 = mpORBextractorLeft->GetInverseScaleSigmaSquares();
|
||||||
|
|
||||||
// ORB extraction
|
// ORB extraction
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_StartExtORB = std::chrono::steady_clock::now();
|
||||||
|
#endif
|
||||||
thread threadLeft(&Frame::ExtractORB,this,0,imLeft,static_cast<KannalaBrandt8*>(mpCamera)->mvLappingArea[0],static_cast<KannalaBrandt8*>(mpCamera)->mvLappingArea[1]);
|
thread threadLeft(&Frame::ExtractORB,this,0,imLeft,static_cast<KannalaBrandt8*>(mpCamera)->mvLappingArea[0],static_cast<KannalaBrandt8*>(mpCamera)->mvLappingArea[1]);
|
||||||
thread threadRight(&Frame::ExtractORB,this,1,imRight,static_cast<KannalaBrandt8*>(mpCamera2)->mvLappingArea[0],static_cast<KannalaBrandt8*>(mpCamera2)->mvLappingArea[1]);
|
thread threadRight(&Frame::ExtractORB,this,1,imRight,static_cast<KannalaBrandt8*>(mpCamera2)->mvLappingArea[0],static_cast<KannalaBrandt8*>(mpCamera2)->mvLappingArea[1]);
|
||||||
threadLeft.join();
|
threadLeft.join();
|
||||||
threadRight.join();
|
threadRight.join();
|
||||||
std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_EndExtORB = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
mTimeORB_Ext = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndExtORB - time_StartExtORB).count();
|
||||||
|
#endif
|
||||||
|
|
||||||
Nleft = mvKeys.size();
|
Nleft = mvKeys.size();
|
||||||
Nright = mvKeysRight.size();
|
Nright = mvKeysRight.size();
|
||||||
|
@ -1375,8 +1405,22 @@ Frame::Frame(const cv::Mat &imLeft, const cv::Mat &imRight, const double &timeSt
|
||||||
|
|
||||||
cv::hconcat(Rrl,trl,mTrl);
|
cv::hconcat(Rrl,trl,mTrl);
|
||||||
|
|
||||||
|
mTrlx = cv::Matx34f(Rrl.at<float>(0,0), Rrl.at<float>(0,1), Rrl.at<float>(0,2), trl.at<float>(0),
|
||||||
|
Rrl.at<float>(1,0), Rrl.at<float>(1,1), Rrl.at<float>(1,2), trl.at<float>(1),
|
||||||
|
Rrl.at<float>(2,0), Rrl.at<float>(2,1), Rrl.at<float>(2,2), trl.at<float>(2));
|
||||||
|
mTlrx = cv::Matx34f(mRlr.at<float>(0,0), mRlr.at<float>(0,1), mRlr.at<float>(0,2), mtlr.at<float>(0),
|
||||||
|
mRlr.at<float>(1,0), mRlr.at<float>(1,1), mRlr.at<float>(1,2), mtlr.at<float>(1),
|
||||||
|
mRlr.at<float>(2,0), mRlr.at<float>(2,1), mRlr.at<float>(2,2), mtlr.at<float>(2));
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_StartStereoMatches = std::chrono::steady_clock::now();
|
||||||
|
#endif
|
||||||
ComputeStereoFishEyeMatches();
|
ComputeStereoFishEyeMatches();
|
||||||
std::chrono::steady_clock::time_point t3 = std::chrono::steady_clock::now();
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_EndStereoMatches = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
mTimeStereoMatch = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndStereoMatches - time_StartStereoMatches).count();
|
||||||
|
#endif
|
||||||
|
|
||||||
//Put all descriptors in the same matrix
|
//Put all descriptors in the same matrix
|
||||||
cv::vconcat(mDescriptors,mDescriptorsRight,mDescriptors);
|
cv::vconcat(mDescriptors,mDescriptorsRight,mDescriptors);
|
||||||
|
@ -1385,25 +1429,10 @@ Frame::Frame(const cv::Mat &imLeft, const cv::Mat &imRight, const double &timeSt
|
||||||
mvbOutlier = vector<bool>(N,false);
|
mvbOutlier = vector<bool>(N,false);
|
||||||
|
|
||||||
AssignFeaturesToGrid();
|
AssignFeaturesToGrid();
|
||||||
std::chrono::steady_clock::time_point t4 = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
mpMutexImu = new std::mutex();
|
mpMutexImu = new std::mutex();
|
||||||
|
|
||||||
UndistortKeyPoints();
|
UndistortKeyPoints();
|
||||||
std::chrono::steady_clock::time_point t5 = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
double t_read = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t1 - t0).count();
|
|
||||||
double t_orbextract = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t2 - t1).count();
|
|
||||||
double t_stereomatches = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t3 - t2).count();
|
|
||||||
double t_assign = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t4 - t3).count();
|
|
||||||
double t_undistort = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t5 - t4).count();
|
|
||||||
|
|
||||||
/*cout << "Reading time: " << t_read << endl;
|
|
||||||
cout << "Extraction time: " << t_orbextract << endl;
|
|
||||||
cout << "Matching time: " << t_stereomatches << endl;
|
|
||||||
cout << "Assignment time: " << t_assign << endl;
|
|
||||||
cout << "Undistortion time: " << t_undistort << endl;*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Frame::ComputeStereoFishEyeMatches() {
|
void Frame::ComputeStereoFishEyeMatches() {
|
||||||
|
@ -1450,26 +1479,33 @@ void Frame::ComputeStereoFishEyeMatches() {
|
||||||
|
|
||||||
bool Frame::isInFrustumChecks(MapPoint *pMP, float viewingCosLimit, bool bRight) {
|
bool Frame::isInFrustumChecks(MapPoint *pMP, float viewingCosLimit, bool bRight) {
|
||||||
// 3D in absolute coordinates
|
// 3D in absolute coordinates
|
||||||
cv::Mat P = pMP->GetWorldPos();
|
cv::Matx31f Px = pMP->GetWorldPos2();
|
||||||
|
|
||||||
|
cv::Matx33f mRx;
|
||||||
|
cv::Matx31f mtx, twcx;
|
||||||
|
|
||||||
|
cv::Matx33f Rcw = mRcwx;
|
||||||
|
cv::Matx33f Rwc = mRcwx.t();
|
||||||
|
cv::Matx31f tcw = mOwx;
|
||||||
|
|
||||||
cv::Mat mR, mt, twc;
|
|
||||||
if(bRight){
|
if(bRight){
|
||||||
cv::Mat Rrl = mTrl.colRange(0,3).rowRange(0,3);
|
cv::Matx33f Rrl = mTrlx.get_minor<3,3>(0,0);
|
||||||
cv::Mat trl = mTrl.col(3);
|
cv::Matx31f trl = mTrlx.get_minor<3,1>(0,3);
|
||||||
mR = Rrl * mRcw;
|
mRx = Rrl * Rcw;
|
||||||
mt = Rrl * mtcw + trl;
|
mtx = Rrl * tcw + trl;
|
||||||
twc = mRwc * mTlr.rowRange(0,3).col(3) + mOw;
|
twcx = Rwc * mTlrx.get_minor<3,1>(0,3) + tcw;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
mR = mRcw;
|
mRx = mRcwx;
|
||||||
mt = mtcw;
|
mtx = mtcwx;
|
||||||
twc = mOw;
|
twcx = mOwx;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3D in camera coordinates
|
// 3D in camera coordinates
|
||||||
cv::Mat Pc = mR*P+mt;
|
|
||||||
const float Pc_dist = cv::norm(Pc);
|
cv::Matx31f Pcx = mRx * Px + mtx;
|
||||||
const float &PcZ = Pc.at<float>(2);
|
const float Pc_dist = cv::norm(Pcx);
|
||||||
|
const float &PcZ = Pcx(2);
|
||||||
|
|
||||||
// Check positive depth
|
// Check positive depth
|
||||||
if(PcZ<0.0f)
|
if(PcZ<0.0f)
|
||||||
|
@ -1477,8 +1513,8 @@ bool Frame::isInFrustumChecks(MapPoint *pMP, float viewingCosLimit, bool bRight)
|
||||||
|
|
||||||
// Project in image and check it is not outside
|
// Project in image and check it is not outside
|
||||||
cv::Point2f uv;
|
cv::Point2f uv;
|
||||||
if(bRight) uv = mpCamera2->project(Pc);
|
if(bRight) uv = mpCamera2->project(Pcx);
|
||||||
else uv = mpCamera->project(Pc);
|
else uv = mpCamera->project(Pcx);
|
||||||
|
|
||||||
if(uv.x<mnMinX || uv.x>mnMaxX)
|
if(uv.x<mnMinX || uv.x>mnMaxX)
|
||||||
return false;
|
return false;
|
||||||
|
@ -1488,16 +1524,16 @@ bool Frame::isInFrustumChecks(MapPoint *pMP, float viewingCosLimit, bool bRight)
|
||||||
// Check distance is in the scale invariance region of the MapPoint
|
// Check distance is in the scale invariance region of the MapPoint
|
||||||
const float maxDistance = pMP->GetMaxDistanceInvariance();
|
const float maxDistance = pMP->GetMaxDistanceInvariance();
|
||||||
const float minDistance = pMP->GetMinDistanceInvariance();
|
const float minDistance = pMP->GetMinDistanceInvariance();
|
||||||
const cv::Mat PO = P-twc;
|
const cv::Matx31f POx = Px - twcx;
|
||||||
const float dist = cv::norm(PO);
|
const float dist = cv::norm(POx);
|
||||||
|
|
||||||
if(dist<minDistance || dist>maxDistance)
|
if(dist<minDistance || dist>maxDistance)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Check viewing angle
|
// Check viewing angle
|
||||||
cv::Mat Pn = pMP->GetNormal();
|
cv::Matx31f Pnx = pMP->GetNormal2();
|
||||||
|
|
||||||
const float viewCos = PO.dot(Pn)/dist;
|
const float viewCos = POx.dot(Pnx)/dist;
|
||||||
|
|
||||||
if(viewCos<viewingCosLimit)
|
if(viewCos<viewingCosLimit)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -38,7 +38,6 @@ FrameDrawer::FrameDrawer(Atlas* pAtlas):both(false),mpAtlas(pAtlas)
|
||||||
|
|
||||||
cv::Mat FrameDrawer::DrawFrame(bool bOldFeatures)
|
cv::Mat FrameDrawer::DrawFrame(bool bOldFeatures)
|
||||||
{
|
{
|
||||||
// std::cout << "0" << std::endl;
|
|
||||||
cv::Mat im;
|
cv::Mat im;
|
||||||
vector<cv::KeyPoint> vIniKeys; // Initialization: KeyPoints in reference frame
|
vector<cv::KeyPoint> vIniKeys; // Initialization: KeyPoints in reference frame
|
||||||
vector<int> vMatches; // Initialization: correspondeces with reference keypoints
|
vector<int> vMatches; // Initialization: correspondeces with reference keypoints
|
||||||
|
@ -47,7 +46,6 @@ cv::Mat FrameDrawer::DrawFrame(bool bOldFeatures)
|
||||||
vector<pair<cv::Point2f, cv::Point2f> > vTracks;
|
vector<pair<cv::Point2f, cv::Point2f> > vTracks;
|
||||||
int state; // Tracking state
|
int state; // Tracking state
|
||||||
|
|
||||||
//
|
|
||||||
Frame currentFrame;
|
Frame currentFrame;
|
||||||
vector<MapPoint*> vpLocalMap;
|
vector<MapPoint*> vpLocalMap;
|
||||||
vector<cv::KeyPoint> vMatchesKeys;
|
vector<cv::KeyPoint> vMatchesKeys;
|
||||||
|
@ -73,7 +71,7 @@ cv::Mat FrameDrawer::DrawFrame(bool bOldFeatures)
|
||||||
vMatches = mvIniMatches;
|
vMatches = mvIniMatches;
|
||||||
vTracks = mvTracks;
|
vTracks = mvTracks;
|
||||||
}
|
}
|
||||||
else if(mState==Tracking::OK /*&& bOldFeatures*/)
|
else if(mState==Tracking::OK)
|
||||||
{
|
{
|
||||||
vCurrentKeys = mvCurrentKeys;
|
vCurrentKeys = mvCurrentKeys;
|
||||||
vbVO = mvbVO;
|
vbVO = mvbVO;
|
||||||
|
@ -96,7 +94,7 @@ cv::Mat FrameDrawer::DrawFrame(bool bOldFeatures)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(im.channels()<3) //this should be always true
|
if(im.channels()<3) //this should be always true
|
||||||
cvtColor(im,im,CV_GRAY2BGR);
|
cvtColor(im,im,cv::COLOR_GRAY2BGR);
|
||||||
|
|
||||||
//Draw
|
//Draw
|
||||||
if(state==Tracking::NOT_INITIALIZED)
|
if(state==Tracking::NOT_INITIALIZED)
|
||||||
|
@ -143,12 +141,8 @@ cv::Mat FrameDrawer::DrawFrame(bool bOldFeatures)
|
||||||
mnTrackedVO++;
|
mnTrackedVO++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*else
|
|
||||||
{
|
|
||||||
cv::circle(im,vCurrentKeys[i].pt,2,cv::Scalar(0,0,255),-1);
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
// std::cout << "2.3" << std::endl;
|
|
||||||
}
|
}
|
||||||
else if(state==Tracking::OK && !bOldFeatures)
|
else if(state==Tracking::OK && !bOldFeatures)
|
||||||
{
|
{
|
||||||
|
@ -157,9 +151,6 @@ cv::Mat FrameDrawer::DrawFrame(bool bOldFeatures)
|
||||||
mnTrackedVO=0;
|
mnTrackedVO=0;
|
||||||
int n = vCurrentKeys.size();
|
int n = vCurrentKeys.size();
|
||||||
|
|
||||||
// cout << "----------------------" << endl;
|
|
||||||
// cout << "Number of matches in old method: " << n << endl;
|
|
||||||
|
|
||||||
for(int i=0; i < n; ++i)
|
for(int i=0; i < n; ++i)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -170,10 +161,6 @@ cv::Mat FrameDrawer::DrawFrame(bool bOldFeatures)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
n = mProjectPoints.size();
|
|
||||||
//cout << "Number of projected points: " << n << endl;
|
|
||||||
n = mMatchedInImage.size();
|
|
||||||
//cout << "Number of matched points: " << n << endl;
|
|
||||||
map<long unsigned int, cv::Point2f>::iterator it_match = mMatchedInImage.begin();
|
map<long unsigned int, cv::Point2f>::iterator it_match = mMatchedInImage.begin();
|
||||||
while(it_match != mMatchedInImage.end())
|
while(it_match != mMatchedInImage.end())
|
||||||
{
|
{
|
||||||
|
@ -193,37 +180,9 @@ cv::Mat FrameDrawer::DrawFrame(bool bOldFeatures)
|
||||||
|
|
||||||
|
|
||||||
it_match++;
|
it_match++;
|
||||||
//it_proj = mProjectPoints.erase(it_proj);
|
|
||||||
}
|
}
|
||||||
//for(int i=0; i < n; ++i)
|
|
||||||
//{
|
|
||||||
/*if(!vpMatchedMPs[i])
|
|
||||||
continue;*/
|
|
||||||
|
|
||||||
//cv::circle(im,vProjectPoints[i],2,cv::Scalar(255,0,0),-1);
|
|
||||||
/*cv::Point2f point3d_proy;
|
|
||||||
float u, v;
|
|
||||||
bool bIsInImage = currentFrame.ProjectPointDistort(vpMatchedMPs[i] , point3d_proy, u, v);
|
|
||||||
if(bIsInImage)
|
|
||||||
{
|
|
||||||
//cout << "-Point is out of the image" << point3d_proy.x << ", " << point3d_proy.y << endl;
|
|
||||||
cv::circle(im,vMatchesKeys[i].pt,2,cv::Scalar(255,0,0),-1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//cout << "+Point CV " << point3d_proy.x << ", " << point3d_proy.y << endl;
|
|
||||||
//cout << "+Point coord " << u << ", " << v << endl;
|
|
||||||
cv::Point2f point_im = vMatchesKeys[i].pt;
|
|
||||||
|
|
||||||
cv::line(im,cv::Point2f(u, v), point_im,cv::Scalar(0, 255, 0), 1);*/
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
/*cout << "Number of tracker in old method: " << mnTracked << endl;
|
|
||||||
cout << "Number of tracker in new method: " << nTracked2 << endl;*/
|
|
||||||
|
|
||||||
n = vOutlierKeys.size();
|
n = vOutlierKeys.size();
|
||||||
//cout << "Number of outliers: " << n << endl;
|
|
||||||
for(int i=0; i < n; ++i)
|
for(int i=0; i < n; ++i)
|
||||||
{
|
{
|
||||||
cv::Point2f point3d_proy;
|
cv::Point2f point3d_proy;
|
||||||
|
@ -235,34 +194,7 @@ cv::Mat FrameDrawer::DrawFrame(bool bOldFeatures)
|
||||||
cv::line(im,cv::Point2f(u, v), point_im,cv::Scalar(0, 0, 255), 1);
|
cv::line(im,cv::Point2f(u, v), point_im,cv::Scalar(0, 0, 255), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for(int i=0;i<n;i++)
|
|
||||||
// {
|
|
||||||
// if(vbVO[i] || vbMap[i])
|
|
||||||
// {
|
|
||||||
// cv::Point2f pt1,pt2;
|
|
||||||
// pt1.x=vCurrentKeys[i].pt.x-r;
|
|
||||||
// pt1.y=vCurrentKeys[i].pt.y-r;
|
|
||||||
// pt2.x=vCurrentKeys[i].pt.x+r;
|
|
||||||
// pt2.y=vCurrentKeys[i].pt.y+r;
|
|
||||||
|
|
||||||
// // This is a match to a MapPoint in the map
|
|
||||||
// if(vbMap[i])
|
|
||||||
// {
|
|
||||||
// cv::rectangle(im,pt1,pt2,cv::Scalar(0,255,0));
|
|
||||||
// cv::circle(im,vCurrentKeys[i].pt,2,cv::Scalar(0,255,0),-1);
|
|
||||||
// mnTracked++;
|
|
||||||
// }
|
|
||||||
// else // This is match to a "visual odometry" MapPoint created in the last frame
|
|
||||||
// {
|
|
||||||
// cv::rectangle(im,pt1,pt2,cv::Scalar(255,0,0));
|
|
||||||
// cv::circle(im,vCurrentKeys[i].pt,2,cv::Scalar(255,0,0),-1);
|
|
||||||
// mnTrackedVO++;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// std::cout << "3" << std::endl;
|
|
||||||
|
|
||||||
cv::Mat imWithInfo;
|
cv::Mat imWithInfo;
|
||||||
DrawTextInfo(im,state, imWithInfo);
|
DrawTextInfo(im,state, imWithInfo);
|
||||||
|
@ -307,7 +239,7 @@ cv::Mat FrameDrawer::DrawRightFrame()
|
||||||
} // destroy scoped mutex -> release mutex
|
} // destroy scoped mutex -> release mutex
|
||||||
|
|
||||||
if(im.channels()<3) //this should be always true
|
if(im.channels()<3) //this should be always true
|
||||||
cvtColor(im,im,CV_GRAY2BGR);
|
cvtColor(im,im,cv::COLOR_GRAY2BGR);
|
||||||
|
|
||||||
//Draw
|
//Draw
|
||||||
if(state==Tracking::NOT_INITIALIZED) //INITIALIZING
|
if(state==Tracking::NOT_INITIALIZED) //INITIALIZING
|
||||||
|
@ -418,8 +350,6 @@ void FrameDrawer::Update(Tracking *pTracker)
|
||||||
N = mvCurrentKeys.size();
|
N = mvCurrentKeys.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
//cout << "Number of matches in frame: " << N << endl;
|
|
||||||
// cout << "Number of matches in frame: " << N << endl;
|
|
||||||
mvbVO = vector<bool>(N,false);
|
mvbVO = vector<bool>(N,false);
|
||||||
mvbMap = vector<bool>(N,false);
|
mvbMap = vector<bool>(N,false);
|
||||||
mbOnlyTracking = pTracker->mbOnlyTracking;
|
mbOnlyTracking = pTracker->mbOnlyTracking;
|
||||||
|
@ -427,7 +357,6 @@ void FrameDrawer::Update(Tracking *pTracker)
|
||||||
//Variables for the new visualization
|
//Variables for the new visualization
|
||||||
mCurrentFrame = pTracker->mCurrentFrame;
|
mCurrentFrame = pTracker->mCurrentFrame;
|
||||||
mmProjectPoints = mCurrentFrame.mmProjectPoints;
|
mmProjectPoints = mCurrentFrame.mmProjectPoints;
|
||||||
//mmMatchedInImage = mCurrentFrame.mmMatchedInImage;
|
|
||||||
mmMatchedInImage.clear();
|
mmMatchedInImage.clear();
|
||||||
|
|
||||||
mvpLocalMap = pTracker->GetLocalMapMPS();
|
mvpLocalMap = pTracker->GetLocalMapMPS();
|
||||||
|
@ -439,8 +368,6 @@ void FrameDrawer::Update(Tracking *pTracker)
|
||||||
mvOutlierKeys.reserve(N);
|
mvOutlierKeys.reserve(N);
|
||||||
mvpOutlierMPs.clear();
|
mvpOutlierMPs.clear();
|
||||||
mvpOutlierMPs.reserve(N);
|
mvpOutlierMPs.reserve(N);
|
||||||
//mvProjectPoints.clear();
|
|
||||||
//mvProjectPoints.reserve(N);
|
|
||||||
|
|
||||||
if(pTracker->mLastProcessedState==Tracking::NOT_INITIALIZED)
|
if(pTracker->mLastProcessedState==Tracking::NOT_INITIALIZED)
|
||||||
{
|
{
|
||||||
|
@ -461,18 +388,8 @@ void FrameDrawer::Update(Tracking *pTracker)
|
||||||
else
|
else
|
||||||
mvbVO[i]=true;
|
mvbVO[i]=true;
|
||||||
|
|
||||||
//mvpMatchedMPs.push_back(pMP);
|
|
||||||
//mvMatchedKeys.push_back(mvCurrentKeys[i]);
|
|
||||||
mmMatchedInImage[pMP->mnId] = mvCurrentKeys[i].pt;
|
mmMatchedInImage[pMP->mnId] = mvCurrentKeys[i].pt;
|
||||||
|
|
||||||
//cv::Point2f point3d_proy;
|
|
||||||
//float u, v;
|
|
||||||
//bool bIsInImage = mCurrentFrame.ProjectPointDistort(pMP, point3d_proy, u, v);
|
|
||||||
//if(bIsInImage)
|
|
||||||
//{
|
|
||||||
//mvMatchedKeys.push_back(mvCurrentKeys[i]);
|
|
||||||
//mvProjectPoints.push_back(cv::Point2f(u, v));
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
203
src/G2oTypes.cc
203
src/G2oTypes.cc
|
@ -424,61 +424,6 @@ void EdgeStereo::linearizeOplus()
|
||||||
y , -x , 0.0, 0.0, 0.0, 1.0;
|
y , -x , 0.0, 0.0, 0.0, 1.0;
|
||||||
|
|
||||||
_jacobianOplusXj = proj_jac * Rcb * SE3deriv;
|
_jacobianOplusXj = proj_jac * Rcb * SE3deriv;
|
||||||
|
|
||||||
|
|
||||||
/*const VertexPose* VPose = static_cast<const VertexPose*>(_vertices[1]);
|
|
||||||
const g2o::VertexSBAPointXYZ* VPoint = static_cast<const g2o::VertexSBAPointXYZ*>(_vertices[0]);
|
|
||||||
|
|
||||||
const Eigen::Matrix3d &Rcw = VPose->estimate().Rcw;
|
|
||||||
const Eigen::Vector3d &tcw = VPose->estimate().tcw;
|
|
||||||
const Eigen::Vector3d Xc = Rcw*VPoint->estimate() + tcw;
|
|
||||||
const double &xc = Xc[0];
|
|
||||||
const double &yc = Xc[1];
|
|
||||||
const double invzc = 1.0/Xc[2];
|
|
||||||
const double invzc2 = invzc*invzc;
|
|
||||||
const double &fx = VPose->estimate().fx;
|
|
||||||
const double &fy = VPose->estimate().fy;
|
|
||||||
const double &bf = VPose->estimate().bf;
|
|
||||||
const Eigen::Matrix3d &Rcb = VPose->estimate().Rcb;
|
|
||||||
|
|
||||||
// Jacobian wrt Point
|
|
||||||
_jacobianOplusXi(0,0) = -fx*invzc*Rcw(0,0)+fx*xc*invzc2*Rcw(2,0);
|
|
||||||
_jacobianOplusXi(0,1) = -fx*invzc*Rcw(0,1)+fx*xc*invzc2*Rcw(2,1);
|
|
||||||
_jacobianOplusXi(0,2) = -fx*invzc*Rcw(0,2)+fx*xc*invzc2*Rcw(2,2);
|
|
||||||
|
|
||||||
_jacobianOplusXi(1,0) = -fy*invzc*Rcw(1,0)+fy*yc*invzc2*Rcw(2,0);
|
|
||||||
_jacobianOplusXi(1,1) = -fy*invzc*Rcw(1,1)+fy*yc*invzc2*Rcw(2,1);
|
|
||||||
_jacobianOplusXi(1,2) = -fy*invzc*Rcw(1,2)+fy*yc*invzc2*Rcw(2,2);
|
|
||||||
|
|
||||||
_jacobianOplusXi(2,0) = _jacobianOplusXi(0,0)-bf*invzc2*Rcw(2,0);
|
|
||||||
_jacobianOplusXi(2,1) = _jacobianOplusXi(0,1)-bf*invzc2*Rcw(2,1);
|
|
||||||
_jacobianOplusXi(2,2) = _jacobianOplusXi(0,2)-bf*invzc2*Rcw(2,2);
|
|
||||||
|
|
||||||
const Eigen::Vector3d Xb = VPose->estimate().Rbc*Xc + VPose->estimate().tbc;
|
|
||||||
const Eigen::Matrix3d RS = VPose->estimate().Rcb*Skew(Xb);
|
|
||||||
|
|
||||||
// Jacobian wrt Imu Pose
|
|
||||||
_jacobianOplusXj(0,0) = -fx*invzc*RS(0,0)+fx*xc*invzc2*RS(2,0);
|
|
||||||
_jacobianOplusXj(0,1) = -fx*invzc*RS(0,1)+fx*xc*invzc2*RS(2,1);
|
|
||||||
_jacobianOplusXj(0,2) = -fx*invzc*RS(0,2)+fx*xc*invzc2*RS(2,2);
|
|
||||||
_jacobianOplusXj(0,3) = fx*invzc*Rcb(0,0)-fx*xc*invzc2*Rcb(2,0);
|
|
||||||
_jacobianOplusXj(0,4) = fx*invzc*Rcb(0,1)-fx*xc*invzc2*Rcb(2,1);
|
|
||||||
_jacobianOplusXj(0,5) = fx*invzc*Rcb(0,2)-fx*xc*invzc2*Rcb(2,2);
|
|
||||||
|
|
||||||
_jacobianOplusXj(1,0) = -fy*invzc*RS(1,0)+fy*yc*invzc2*RS(2,0);
|
|
||||||
_jacobianOplusXj(1,1) = -fy*invzc*RS(1,1)+fy*yc*invzc2*RS(2,1);
|
|
||||||
_jacobianOplusXj(1,2) = -fy*invzc*RS(1,2)+fy*yc*invzc2*RS(2,2);
|
|
||||||
_jacobianOplusXj(1,3) = fy*invzc*Rcb(1,0)-fy*yc*invzc2*Rcb(2,0);
|
|
||||||
_jacobianOplusXj(1,4) = fy*invzc*Rcb(1,1)-fy*yc*invzc2*Rcb(2,1);
|
|
||||||
_jacobianOplusXj(1,5) = fy*invzc*Rcb(1,2)-fy*yc*invzc2*Rcb(2,2);
|
|
||||||
|
|
||||||
_jacobianOplusXj(2,0) = _jacobianOplusXj(0,0) - bf*invzc2*RS(2,0);
|
|
||||||
_jacobianOplusXj(2,1) = _jacobianOplusXj(0,1) - bf*invzc2*RS(2,1);
|
|
||||||
_jacobianOplusXj(2,2) = _jacobianOplusXj(0,2) - bf*invzc2*RS(2,2);
|
|
||||||
_jacobianOplusXj(2,3) = _jacobianOplusXj(0,3) + bf*invzc2*Rcb(2,0);
|
|
||||||
_jacobianOplusXj(2,4) = _jacobianOplusXj(0,4) + bf*invzc2*Rcb(2,1);
|
|
||||||
_jacobianOplusXj(2,5) = _jacobianOplusXj(0,5) + bf*invzc2*Rcb(2,2);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EdgeStereoOnlyPose::linearizeOplus()
|
void EdgeStereoOnlyPose::linearizeOplus()
|
||||||
|
@ -506,156 +451,8 @@ void EdgeStereoOnlyPose::linearizeOplus()
|
||||||
-z , 0.0, x, 0.0, 1.0, 0.0,
|
-z , 0.0, x, 0.0, 1.0, 0.0,
|
||||||
y , -x , 0.0, 0.0, 0.0, 1.0;
|
y , -x , 0.0, 0.0, 0.0, 1.0;
|
||||||
_jacobianOplusXi = proj_jac * Rcb * SE3deriv;
|
_jacobianOplusXi = proj_jac * Rcb * SE3deriv;
|
||||||
|
|
||||||
/*const VertexPose* VPose = static_cast<const VertexPose*>(_vertices[0]);
|
|
||||||
const Eigen::Matrix3d &Rcw = VPose->estimate().Rcw;
|
|
||||||
const Eigen::Vector3d &tcw = VPose->estimate().tcw;
|
|
||||||
const Eigen::Vector3d Xc = Rcw*Xw + tcw;
|
|
||||||
const double &xc = Xc[0];
|
|
||||||
const double &yc = Xc[1];
|
|
||||||
const double invzc = 1.0/Xc[2];
|
|
||||||
const double invzc2 = invzc*invzc;
|
|
||||||
const double &fx = VPose->estimate().fx;
|
|
||||||
const double &fy = VPose->estimate().fy;
|
|
||||||
const double &bf = VPose->estimate().bf;
|
|
||||||
const Eigen::Matrix3d &Rcb = VPose->estimate().Rcb;
|
|
||||||
|
|
||||||
const Eigen::Vector3d Xb = VPose->estimate().Rbc*Xc + VPose->estimate().tbc;
|
|
||||||
const Eigen::Matrix3d RS = VPose->estimate().Rcb*Skew(Xb);
|
|
||||||
|
|
||||||
// Jacobian wrt Imu Pose
|
|
||||||
_jacobianOplusXi(0,0) = -fx*invzc*RS(0,0)+fx*xc*invzc2*RS(2,0);
|
|
||||||
_jacobianOplusXi(0,1) = -fx*invzc*RS(0,1)+fx*xc*invzc2*RS(2,1);
|
|
||||||
_jacobianOplusXi(0,2) = -fx*invzc*RS(0,2)+fx*xc*invzc2*RS(2,2);
|
|
||||||
_jacobianOplusXi(0,3) = fx*invzc*Rcb(0,0)-fx*xc*invzc2*Rcb(2,0);
|
|
||||||
_jacobianOplusXi(0,4) = fx*invzc*Rcb(0,1)-fx*xc*invzc2*Rcb(2,1);
|
|
||||||
_jacobianOplusXi(0,5) = fx*invzc*Rcb(0,2)-fx*xc*invzc2*Rcb(2,2);
|
|
||||||
|
|
||||||
_jacobianOplusXi(1,0) = -fy*invzc*RS(1,0)+fy*yc*invzc2*RS(2,0);
|
|
||||||
_jacobianOplusXi(1,1) = -fy*invzc*RS(1,1)+fy*yc*invzc2*RS(2,1);
|
|
||||||
_jacobianOplusXi(1,2) = -fy*invzc*RS(1,2)+fy*yc*invzc2*RS(2,2);
|
|
||||||
_jacobianOplusXi(1,3) = fy*invzc*Rcb(1,0)-fy*yc*invzc2*Rcb(2,0);
|
|
||||||
_jacobianOplusXi(1,4) = fy*invzc*Rcb(1,1)-fy*yc*invzc2*Rcb(2,1);
|
|
||||||
_jacobianOplusXi(1,5) = fy*invzc*Rcb(1,2)-fy*yc*invzc2*Rcb(2,2);
|
|
||||||
|
|
||||||
_jacobianOplusXi(2,0) = _jacobianOplusXi(0,0) - bf*invzc2*RS(2,0);
|
|
||||||
_jacobianOplusXi(2,1) = _jacobianOplusXi(0,1) - bf*invzc2*RS(2,1);
|
|
||||||
_jacobianOplusXi(2,2) = _jacobianOplusXi(0,2) - bf*invzc2*RS(2,2);
|
|
||||||
_jacobianOplusXi(2,3) = _jacobianOplusXi(0,3) + bf*invzc2*Rcb(2,0);
|
|
||||||
_jacobianOplusXi(2,4) = _jacobianOplusXi(0,4) + bf*invzc2*Rcb(2,1);
|
|
||||||
_jacobianOplusXi(2,5) = _jacobianOplusXi(0,5) + bf*invzc2*Rcb(2,2);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Eigen::Vector2d EdgeMonoInvdepth::cam_project(const Eigen::Vector3d & trans_xyz) const{
|
|
||||||
double invZ = 1./trans_xyz[2];
|
|
||||||
Eigen::Vector2d res;
|
|
||||||
res[0] = invZ*trans_xyz[0]*fx + cx;
|
|
||||||
res[1] = invZ*trans_xyz[1]*fy + cy;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
Eigen::Vector3d EdgeMonoInvdepth::cam_unproject(const double u, const double v, const double invDepth) const{
|
|
||||||
Eigen::Vector3d res;
|
|
||||||
res[2] = 1./invDepth;
|
|
||||||
double z_x=res[2]/fx;
|
|
||||||
double z_y=res[2]/fy;
|
|
||||||
res[0] = (u-cx)*z_x;
|
|
||||||
res[1] = (v-cy)*z_y;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EdgeMonoInvdepth::linearizeOplus()
|
|
||||||
{
|
|
||||||
VertexInvDepth *vPt = static_cast<VertexInvDepth*>(_vertices[0]);
|
|
||||||
g2o::VertexSE3Expmap *vHost = static_cast<g2o::VertexSE3Expmap*>(_vertices[1]);
|
|
||||||
g2o::VertexSE3Expmap *vObs = static_cast<g2o::VertexSE3Expmap*>(_vertices[2]);
|
|
||||||
|
|
||||||
//
|
|
||||||
g2o::SE3Quat Tiw(vObs->estimate());
|
|
||||||
g2o::SE3Quat T0w(vHost->estimate());
|
|
||||||
g2o::SE3Quat Ti0 = Tiw*T0w.inverse();
|
|
||||||
double o_rho_j = vPt->estimate().rho;
|
|
||||||
Eigen::Vector3d o_X_j = cam_unproject(vPt->estimate().u,vPt->estimate().v,o_rho_j);
|
|
||||||
Eigen::Vector3d i_X_j = Ti0.map(o_X_j);
|
|
||||||
double i_rho_j = 1./i_X_j[2];
|
|
||||||
Eigen::Vector2d i_proj_j = cam_project(i_X_j);
|
|
||||||
|
|
||||||
// i_rho_j*C_ij matrix
|
|
||||||
Eigen::Matrix<double,2,3> rhoC_ij;
|
|
||||||
rhoC_ij(0,0) = i_rho_j*fx;
|
|
||||||
rhoC_ij(0,1) = 0.0;
|
|
||||||
rhoC_ij(0,2) = i_rho_j*(cx-i_proj_j[0]);
|
|
||||||
rhoC_ij(1,0) = 0.0;
|
|
||||||
rhoC_ij(1,1) = i_rho_j*fy;
|
|
||||||
rhoC_ij(1,2) = i_rho_j*(cy-i_proj_j[1]);
|
|
||||||
|
|
||||||
// o_rho_j^{-2}*K^{-1}*0_proj_j vector
|
|
||||||
Eigen::Matrix3d Ri0 = Ti0.rotation().toRotationMatrix();
|
|
||||||
Eigen::Matrix<double, 2, 3> tmp;
|
|
||||||
tmp = rhoC_ij*Ri0;
|
|
||||||
|
|
||||||
// Skew matrices
|
|
||||||
Eigen::Matrix3d skew_0_X_j;
|
|
||||||
Eigen::Matrix3d skew_i_X_j;
|
|
||||||
|
|
||||||
skew_0_X_j=Eigen::MatrixXd::Zero(3,3);
|
|
||||||
skew_i_X_j=Eigen::MatrixXd::Zero(3,3);
|
|
||||||
|
|
||||||
skew_0_X_j(0,1) = -o_X_j[2];
|
|
||||||
skew_0_X_j(1,0) = -skew_0_X_j(0,1);
|
|
||||||
skew_0_X_j(0,2) = o_X_j[1];
|
|
||||||
skew_0_X_j(2,0) = -skew_0_X_j(0,2);
|
|
||||||
skew_0_X_j(1,2) = -o_X_j[0];
|
|
||||||
skew_0_X_j(2,1) = -skew_0_X_j(1,2);
|
|
||||||
|
|
||||||
skew_i_X_j(0,1) = -i_X_j[2];
|
|
||||||
skew_i_X_j(1,0) = -skew_i_X_j(0,1);
|
|
||||||
skew_i_X_j(0,2) = i_X_j[1];
|
|
||||||
skew_i_X_j(2,0) = -skew_i_X_j(0,2);
|
|
||||||
skew_i_X_j(1,2) = -i_X_j[0];
|
|
||||||
skew_i_X_j(2,1) = -skew_i_X_j(1,2);
|
|
||||||
|
|
||||||
// Jacobians w.r.t inverse depth in the host frame
|
|
||||||
_jacobianOplus[0].setZero();
|
|
||||||
_jacobianOplus[0] = (1./o_rho_j)*rhoC_ij*Ri0*o_X_j;
|
|
||||||
|
|
||||||
// Jacobians w.r.t pose host frame
|
|
||||||
_jacobianOplus[1].setZero();
|
|
||||||
// Rotation
|
|
||||||
_jacobianOplus[1].block<2,3>(0,0) = -tmp*skew_0_X_j;
|
|
||||||
// translation
|
|
||||||
_jacobianOplus[1].block<2,3>(0,3) = tmp;
|
|
||||||
|
|
||||||
// Jacobians w.r.t pose observer frame
|
|
||||||
_jacobianOplus[2].setZero();
|
|
||||||
// Rotation
|
|
||||||
_jacobianOplus[2].block<2,3>(0,0) = rhoC_ij*skew_i_X_j;
|
|
||||||
// translation
|
|
||||||
_jacobianOplus[2].block<2,3>(0,3) = -rhoC_ij;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Eigen::Vector2d EdgeMonoInvdepthBody::cam_project(const Eigen::Vector3d & trans_xyz) const{
|
|
||||||
double invZ = 1./trans_xyz[2];
|
|
||||||
Eigen::Vector2d res;
|
|
||||||
res[0] = invZ*trans_xyz[0]*fx + cx;
|
|
||||||
res[1] = invZ*trans_xyz[1]*fy + cy;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
Eigen::Vector3d EdgeMonoInvdepthBody::cam_unproject(const double u, const double v, const double invDepth) const{
|
|
||||||
Eigen::Vector3d res;
|
|
||||||
res[2] = 1./invDepth;
|
|
||||||
double z_x=res[2]/fx;
|
|
||||||
double z_y=res[2]/fy;
|
|
||||||
res[0] = (u-cx)*z_x;
|
|
||||||
res[1] = (v-cy)*z_y;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
VertexVelocity::VertexVelocity(KeyFrame* pKF)
|
VertexVelocity::VertexVelocity(KeyFrame* pKF)
|
||||||
{
|
{
|
||||||
setEstimate(Converter::toVector3d(pKF->GetVelocity()));
|
setEstimate(Converter::toVector3d(pKF->GetVelocity()));
|
||||||
|
|
|
@ -31,7 +31,6 @@ cv::Mat NormalizeRotation(const cv::Mat &R)
|
||||||
{
|
{
|
||||||
cv::Mat U,w,Vt;
|
cv::Mat U,w,Vt;
|
||||||
cv::SVDecomp(R,w,U,Vt,cv::SVD::FULL_UV);
|
cv::SVDecomp(R,w,U,Vt,cv::SVD::FULL_UV);
|
||||||
// assert(cv::determinant(U*Vt)>0);
|
|
||||||
return U*Vt;
|
return U*Vt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,10 +398,10 @@ IMU::Bias Preintegrated::GetDeltaBias(const Bias &b_)
|
||||||
cv::Mat Preintegrated::GetDeltaRotation(const Bias &b_)
|
cv::Mat Preintegrated::GetDeltaRotation(const Bias &b_)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(mMutex);
|
std::unique_lock<std::mutex> lock(mMutex);
|
||||||
// ? 计算偏置的变化量
|
// 计算偏置的变化量
|
||||||
cv::Mat dbg = (cv::Mat_<float>(3,1) << b_.bwx-b.bwx,b_.bwy-b.bwy,b_.bwz-b.bwz);
|
cv::Mat dbg = (cv::Mat_<float>(3,1) << b_.bwx-b.bwx,b_.bwy-b.bwy,b_.bwz-b.bwz);
|
||||||
// ? 考虑偏置后,dR对偏置线性化的近似求解,邱笑晨《预积分总结与公式推导》P13~P14
|
// 考虑偏置后,dR对偏置线性化的近似求解,邱笑晨《预积分总结与公式推导》P13~P14
|
||||||
// ? Forster论文公式(44)yP17也有结果(但没有推导),后面两个函数GetDeltaPosition和GetDeltaPosition也是基于此推导的
|
// Forster论文公式(44)yP17也有结果(但没有推导),后面两个函数GetDeltaPosition和GetDeltaPosition也是基于此推导的
|
||||||
return NormalizeRotation(dR*ExpSO3(JRg*dbg));
|
return NormalizeRotation(dR*ExpSO3(JRg*dbg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,7 +410,7 @@ cv::Mat Preintegrated::GetDeltaVelocity(const Bias &b_)
|
||||||
std::unique_lock<std::mutex> lock(mMutex);
|
std::unique_lock<std::mutex> lock(mMutex);
|
||||||
cv::Mat dbg = (cv::Mat_<float>(3,1) << b_.bwx-b.bwx,b_.bwy-b.bwy,b_.bwz-b.bwz);
|
cv::Mat dbg = (cv::Mat_<float>(3,1) << b_.bwx-b.bwx,b_.bwy-b.bwy,b_.bwz-b.bwz);
|
||||||
cv::Mat dba = (cv::Mat_<float>(3,1) << b_.bax-b.bax,b_.bay-b.bay,b_.baz-b.baz);
|
cv::Mat dba = (cv::Mat_<float>(3,1) << b_.bax-b.bax,b_.bay-b.bay,b_.baz-b.baz);
|
||||||
// ? 考虑偏置后,dV对偏置线性化的近似求解,邱笑晨《预积分总结与公式推导》P13,JPg和JPa在预积分处理中更新
|
// 考虑偏置后,dV对偏置线性化的近似求解,邱笑晨《预积分总结与公式推导》P13,JPg和JPa在预积分处理中更新
|
||||||
return dV + JVg*dbg + JVa*dba;
|
return dV + JVg*dbg + JVa*dba;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,7 +419,7 @@ cv::Mat Preintegrated::GetDeltaPosition(const Bias &b_)
|
||||||
std::unique_lock<std::mutex> lock(mMutex);
|
std::unique_lock<std::mutex> lock(mMutex);
|
||||||
cv::Mat dbg = (cv::Mat_<float>(3,1) << b_.bwx-b.bwx,b_.bwy-b.bwy,b_.bwz-b.bwz);
|
cv::Mat dbg = (cv::Mat_<float>(3,1) << b_.bwx-b.bwx,b_.bwy-b.bwy,b_.bwz-b.bwz);
|
||||||
cv::Mat dba = (cv::Mat_<float>(3,1) << b_.bax-b.bax,b_.bay-b.bay,b_.baz-b.baz);
|
cv::Mat dba = (cv::Mat_<float>(3,1) << b_.bax-b.bax,b_.bay-b.bay,b_.baz-b.baz);
|
||||||
// ? 考虑偏置后,dP对偏置线性化的近似求解,邱笑晨《预积分总结与公式推导》P13,JPg和JPa在预积分处理中更新
|
// 考虑偏置后,dP对偏置线性化的近似求解,邱笑晨《预积分总结与公式推导》P13,JPg和JPa在预积分处理中更新
|
||||||
return dP + JPg*dbg + JPa*dba;
|
return dP + JPg*dbg + JPa*dba;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -196,11 +196,11 @@ bool Initializer::Initialize(const Frame &CurrentFrame, const vector<int> &vMatc
|
||||||
//更偏向于平面,此时从单应矩阵恢复,函数ReconstructH返回bool型结果
|
//更偏向于平面,此时从单应矩阵恢复,函数ReconstructH返回bool型结果
|
||||||
return ReconstructH(vbMatchesInliersH, //输入,匹配成功的特征点对Inliers标记
|
return ReconstructH(vbMatchesInliersH, //输入,匹配成功的特征点对Inliers标记
|
||||||
H, //输入,前面RANSAC计算后的单应矩阵
|
H, //输入,前面RANSAC计算后的单应矩阵
|
||||||
mK, //输入,相机的内参数矩阵
|
K, //输入,相机的内参数矩阵
|
||||||
R21,t21, //输出,计算出来的相机从参考帧1到当前帧2所发生的旋转和位移变换
|
R21,t21, //输出,计算出来的相机从参考帧1到当前帧2所发生的旋转和位移变换
|
||||||
vP3D, //特征点对经过三角测量之后的空间坐标,也就是地图点
|
vP3D, //特征点对经过三角测量之后的空间坐标,也就是地图点
|
||||||
vbTriangulated, //特征点对是否成功三角化的标记
|
vbTriangulated, //特征点对是否成功三角化的标记
|
||||||
1.0, //这个对应的形参为minParallax,即认为某对特征点的三角化测量中,认为其测量有效时
|
minParallax, //这个对应的形参为minParallax,即认为某对特征点的三角化测量中,认为其测量有效时
|
||||||
//需要满足的最小视差角(如果视差角过小则会引起非常大的观测误差),单位是角度
|
//需要满足的最小视差角(如果视差角过小则会引起非常大的观测误差),单位是角度
|
||||||
50); //为了进行运动恢复,所需要的最少的三角化测量成功的点个数
|
50); //为了进行运动恢复,所需要的最少的三角化测量成功的点个数
|
||||||
}
|
}
|
||||||
|
|
292
src/KeyFrame.cc
292
src/KeyFrame.cc
|
@ -96,6 +96,12 @@ KeyFrame::KeyFrame(Frame &F, Map *pMap, KeyFrameDatabase *pKFDB):
|
||||||
SetPose(F.mTcw);
|
SetPose(F.mTcw);
|
||||||
|
|
||||||
mnOriginMapId = pMap->GetId();
|
mnOriginMapId = pMap->GetId();
|
||||||
|
|
||||||
|
this->Tlr_ = cv::Matx44f(mTlr.at<float>(0,0),mTlr.at<float>(0,1),mTlr.at<float>(0,2),mTlr.at<float>(0,3),
|
||||||
|
mTlr.at<float>(1,0),mTlr.at<float>(1,1),mTlr.at<float>(1,2),mTlr.at<float>(1,3),
|
||||||
|
mTlr.at<float>(2,0),mTlr.at<float>(2,1),mTlr.at<float>(2,2),mTlr.at<float>(2,3),
|
||||||
|
mTlr.at<float>(3,0),mTlr.at<float>(3,1),mTlr.at<float>(3,2),mTlr.at<float>(3,3));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyFrame::ComputeBoW()
|
void KeyFrame::ComputeBoW()
|
||||||
|
@ -133,6 +139,19 @@ void KeyFrame::SetPose(const cv::Mat &Tcw_)
|
||||||
cv::Mat center = (cv::Mat_<float>(4,1) << mHalfBaseline, 0 , 0, 1);
|
cv::Mat center = (cv::Mat_<float>(4,1) << mHalfBaseline, 0 , 0, 1);
|
||||||
// 世界坐标系下,左目相机中心到立体相机中心的向量,方向由左目相机指向立体相机中心
|
// 世界坐标系下,左目相机中心到立体相机中心的向量,方向由左目相机指向立体相机中心
|
||||||
Cw = Twc*center;
|
Cw = Twc*center;
|
||||||
|
|
||||||
|
//Static matrices
|
||||||
|
this->Tcw_ = cv::Matx44f(Tcw.at<float>(0,0),Tcw.at<float>(0,1),Tcw.at<float>(0,2),Tcw.at<float>(0,3),
|
||||||
|
Tcw.at<float>(1,0),Tcw.at<float>(1,1),Tcw.at<float>(1,2),Tcw.at<float>(1,3),
|
||||||
|
Tcw.at<float>(2,0),Tcw.at<float>(2,1),Tcw.at<float>(2,2),Tcw.at<float>(2,3),
|
||||||
|
Tcw.at<float>(3,0),Tcw.at<float>(3,1),Tcw.at<float>(3,2),Tcw.at<float>(3,3));
|
||||||
|
|
||||||
|
this->Twc_ = cv::Matx44f(Twc.at<float>(0,0),Twc.at<float>(0,1),Twc.at<float>(0,2),Twc.at<float>(0,3),
|
||||||
|
Twc.at<float>(1,0),Twc.at<float>(1,1),Twc.at<float>(1,2),Twc.at<float>(1,3),
|
||||||
|
Twc.at<float>(2,0),Twc.at<float>(2,1),Twc.at<float>(2,2),Twc.at<float>(2,3),
|
||||||
|
Twc.at<float>(3,0),Twc.at<float>(3,1),Twc.at<float>(3,2),Twc.at<float>(3,3));
|
||||||
|
|
||||||
|
this->Ow_ = cv::Matx31f(Ow.at<float>(0),Ow.at<float>(1),Ow.at<float>(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyFrame::SetVelocity(const cv::Mat &Vw_)
|
void KeyFrame::SetVelocity(const cv::Mat &Vw_)
|
||||||
|
@ -247,11 +266,14 @@ void KeyFrame::UpdateBestCovisibles()
|
||||||
list<KeyFrame*> lKFs; // keyframe
|
list<KeyFrame*> lKFs; // keyframe
|
||||||
list<int> lWs; // weight
|
list<int> lWs; // weight
|
||||||
for(size_t i=0, iend=vPairs.size(); i<iend;i++)
|
for(size_t i=0, iend=vPairs.size(); i<iend;i++)
|
||||||
|
{
|
||||||
|
if(!vPairs[i].second->isBad())
|
||||||
{
|
{
|
||||||
// push_front 后变成从大到小
|
// push_front 后变成从大到小
|
||||||
lKFs.push_front(vPairs[i].second);
|
lKFs.push_front(vPairs[i].second);
|
||||||
lWs.push_front(vPairs[i].first);
|
lWs.push_front(vPairs[i].first);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 权重从大到小
|
// 权重从大到小
|
||||||
mvpOrderedConnectedKeyFrames = vector<KeyFrame*>(lKFs.begin(),lKFs.end());
|
mvpOrderedConnectedKeyFrames = vector<KeyFrame*>(lKFs.begin(),lKFs.end());
|
||||||
|
@ -739,11 +761,6 @@ void KeyFrame::SetBadFlag()
|
||||||
mbToBeErased = true;
|
mbToBeErased = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!mpParent)
|
|
||||||
{
|
|
||||||
//cout << "KF.BADFLAG-> There is not parent, but it is not the first KF in the map" << endl;
|
|
||||||
//cout << "KF.BADFLAG-> KF: " << mnId << "; first KF: " << mpMap->GetInitKFid() << endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2 遍历所有和当前关键帧共视的关键帧,删除他们与当前关键帧的联系
|
// Step 2 遍历所有和当前关键帧共视的关键帧,删除他们与当前关键帧的联系
|
||||||
|
@ -830,12 +847,6 @@ void KeyFrame::SetBadFlag()
|
||||||
// 回答:不需要!这里while循环还没退出,会使用更新的sParentCandidates
|
// 回答:不需要!这里while循环还没退出,会使用更新的sParentCandidates
|
||||||
if(bContinue)
|
if(bContinue)
|
||||||
{
|
{
|
||||||
if(pC->mnId == pP->mnId)
|
|
||||||
{
|
|
||||||
/*cout << "ERROR: The parent and son can't be the same KF. ID: " << pC->mnId << endl;
|
|
||||||
cout << "Current KF: " << mnId << endl;
|
|
||||||
cout << "Parent of the map: " << endl;*/
|
|
||||||
}
|
|
||||||
// 因为父节点死了,并且子节点找到了新的父节点,就把它更新为自己的父节点
|
// 因为父节点死了,并且子节点找到了新的父节点,就把它更新为自己的父节点
|
||||||
pC->ChangeParent(pP);
|
pC->ChangeParent(pP);
|
||||||
// 因为子节点找到了新的父节点并更新了父节点,那么该子节点升级,作为其它子节点的备选父节点
|
// 因为子节点找到了新的父节点并更新了父节点,那么该子节点升级,作为其它子节点的备选父节点
|
||||||
|
@ -865,10 +876,6 @@ void KeyFrame::SetBadFlag()
|
||||||
// 如果当前的关键帧要被删除的话就要计算这个,表示原父关键帧到当前关键帧的位姿变换
|
// 如果当前的关键帧要被删除的话就要计算这个,表示原父关键帧到当前关键帧的位姿变换
|
||||||
// 注意在这个删除的过程中,其实并没有将当前关键帧中存储的父关键帧的指针删除掉
|
// 注意在这个删除的过程中,其实并没有将当前关键帧中存储的父关键帧的指针删除掉
|
||||||
mTcp = Tcw*mpParent->GetPoseInverse();
|
mTcp = Tcw*mpParent->GetPoseInverse();
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//cout << "Error: KF haven't got a parent, it is imposible reach this code point without him" << endl;
|
|
||||||
}
|
}
|
||||||
// 标记当前关键帧已经死了
|
// 标记当前关键帧已经死了
|
||||||
mbBad = true;
|
mbBad = true;
|
||||||
|
@ -1062,171 +1069,6 @@ void KeyFrame::UpdateMap(Map* pMap)
|
||||||
mpMap = pMap;
|
mpMap = pMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyFrame::PreSave(set<KeyFrame*>& spKF,set<MapPoint*>& spMP, set<GeometricCamera*>& spCam)
|
|
||||||
{
|
|
||||||
// Save the id of each MapPoint in this KF, there can be null pointer in the vector
|
|
||||||
mvBackupMapPointsId.clear();
|
|
||||||
mvBackupMapPointsId.reserve(N);
|
|
||||||
for(int i = 0; i < N; ++i)
|
|
||||||
{
|
|
||||||
|
|
||||||
if(mvpMapPoints[i] && spMP.find(mvpMapPoints[i]) != spMP.end()) // Checks if the element is not null
|
|
||||||
mvBackupMapPointsId.push_back(mvpMapPoints[i]->mnId);
|
|
||||||
else // If the element is null his value is -1 because all the id are positives
|
|
||||||
mvBackupMapPointsId.push_back(-1);
|
|
||||||
}
|
|
||||||
//cout << "KeyFrame: ID from MapPoints stored" << endl;
|
|
||||||
// Save the id of each connected KF with it weight
|
|
||||||
mBackupConnectedKeyFrameIdWeights.clear();
|
|
||||||
for(std::map<KeyFrame*,int>::const_iterator it = mConnectedKeyFrameWeights.begin(), end = mConnectedKeyFrameWeights.end(); it != end; ++it)
|
|
||||||
{
|
|
||||||
if(spKF.find(it->first) != spKF.end())
|
|
||||||
mBackupConnectedKeyFrameIdWeights[it->first->mnId] = it->second;
|
|
||||||
}
|
|
||||||
//cout << "KeyFrame: ID from connected KFs stored" << endl;
|
|
||||||
// Save the parent id
|
|
||||||
mBackupParentId = -1;
|
|
||||||
if(mpParent && spKF.find(mpParent) != spKF.end())
|
|
||||||
mBackupParentId = mpParent->mnId;
|
|
||||||
//cout << "KeyFrame: ID from Parent KF stored" << endl;
|
|
||||||
// Save the id of the childrens KF
|
|
||||||
mvBackupChildrensId.clear();
|
|
||||||
mvBackupChildrensId.reserve(mspChildrens.size());
|
|
||||||
for(KeyFrame* pKFi : mspChildrens)
|
|
||||||
{
|
|
||||||
if(spKF.find(pKFi) != spKF.end())
|
|
||||||
mvBackupChildrensId.push_back(pKFi->mnId);
|
|
||||||
}
|
|
||||||
//cout << "KeyFrame: ID from Children KFs stored" << endl;
|
|
||||||
// Save the id of the loop edge KF
|
|
||||||
mvBackupLoopEdgesId.clear();
|
|
||||||
mvBackupLoopEdgesId.reserve(mspLoopEdges.size());
|
|
||||||
for(KeyFrame* pKFi : mspLoopEdges)
|
|
||||||
{
|
|
||||||
if(spKF.find(pKFi) != spKF.end())
|
|
||||||
mvBackupLoopEdgesId.push_back(pKFi->mnId);
|
|
||||||
}
|
|
||||||
//cout << "KeyFrame: ID from Loop KFs stored" << endl;
|
|
||||||
// Save the id of the merge edge KF
|
|
||||||
mvBackupMergeEdgesId.clear();
|
|
||||||
mvBackupMergeEdgesId.reserve(mspMergeEdges.size());
|
|
||||||
for(KeyFrame* pKFi : mspMergeEdges)
|
|
||||||
{
|
|
||||||
if(spKF.find(pKFi) != spKF.end())
|
|
||||||
mvBackupMergeEdgesId.push_back(pKFi->mnId);
|
|
||||||
}
|
|
||||||
//cout << "KeyFrame: ID from Merge KFs stored" << endl;
|
|
||||||
|
|
||||||
//Camera data
|
|
||||||
mnBackupIdCamera = -1;
|
|
||||||
if(mpCamera && spCam.find(mpCamera) != spCam.end())
|
|
||||||
mnBackupIdCamera = mpCamera->GetId();
|
|
||||||
//cout << "KeyFrame: ID from Camera1 stored; " << mnBackupIdCamera << endl;
|
|
||||||
|
|
||||||
mnBackupIdCamera2 = -1;
|
|
||||||
if(mpCamera2 && spCam.find(mpCamera2) != spCam.end())
|
|
||||||
mnBackupIdCamera2 = mpCamera2->GetId();
|
|
||||||
//cout << "KeyFrame: ID from Camera2 stored; " << mnBackupIdCamera2 << endl;
|
|
||||||
|
|
||||||
//Inertial data
|
|
||||||
mBackupPrevKFId = -1;
|
|
||||||
if(mPrevKF && spKF.find(mPrevKF) != spKF.end())
|
|
||||||
mBackupPrevKFId = mPrevKF->mnId;
|
|
||||||
//cout << "KeyFrame: ID from Prev KF stored" << endl;
|
|
||||||
mBackupNextKFId = -1;
|
|
||||||
if(mNextKF && spKF.find(mNextKF) != spKF.end())
|
|
||||||
mBackupNextKFId = mNextKF->mnId;
|
|
||||||
//cout << "KeyFrame: ID from NextKF stored" << endl;
|
|
||||||
if(mpImuPreintegrated)
|
|
||||||
mBackupImuPreintegrated.CopyFrom(mpImuPreintegrated);
|
|
||||||
//cout << "KeyFrame: Imu Preintegrated stored" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyFrame::PostLoad(map<long unsigned int, KeyFrame*>& mpKFid, map<long unsigned int, MapPoint*>& mpMPid, map<unsigned int, GeometricCamera*>& mpCamId){
|
|
||||||
// Rebuild the empty variables
|
|
||||||
|
|
||||||
// Pose
|
|
||||||
SetPose(Tcw);
|
|
||||||
|
|
||||||
// Reference reconstruction
|
|
||||||
// Each MapPoint sight from this KeyFrame
|
|
||||||
mvpMapPoints.clear();
|
|
||||||
mvpMapPoints.resize(N);
|
|
||||||
for(int i=0; i<N; ++i)
|
|
||||||
{
|
|
||||||
if(mvBackupMapPointsId[i] != -1)
|
|
||||||
mvpMapPoints[i] = mpMPid[mvBackupMapPointsId[i]];
|
|
||||||
else
|
|
||||||
mvpMapPoints[i] = static_cast<MapPoint*>(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Conected KeyFrames with him weight
|
|
||||||
mConnectedKeyFrameWeights.clear();
|
|
||||||
for(map<long unsigned int, int>::const_iterator it = mBackupConnectedKeyFrameIdWeights.begin(), end = mBackupConnectedKeyFrameIdWeights.end();
|
|
||||||
it != end; ++it)
|
|
||||||
{
|
|
||||||
KeyFrame* pKFi = mpKFid[it->first];
|
|
||||||
mConnectedKeyFrameWeights[pKFi] = it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore parent KeyFrame
|
|
||||||
if(mBackupParentId>=0)
|
|
||||||
mpParent = mpKFid[mBackupParentId];
|
|
||||||
|
|
||||||
// KeyFrame childrens
|
|
||||||
mspChildrens.clear();
|
|
||||||
for(vector<long unsigned int>::const_iterator it = mvBackupChildrensId.begin(), end = mvBackupChildrensId.end(); it!=end; ++it)
|
|
||||||
{
|
|
||||||
mspChildrens.insert(mpKFid[*it]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop edge KeyFrame
|
|
||||||
mspLoopEdges.clear();
|
|
||||||
for(vector<long unsigned int>::const_iterator it = mvBackupLoopEdgesId.begin(), end = mvBackupLoopEdgesId.end(); it != end; ++it)
|
|
||||||
{
|
|
||||||
mspLoopEdges.insert(mpKFid[*it]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Merge edge KeyFrame
|
|
||||||
mspMergeEdges.clear();
|
|
||||||
for(vector<long unsigned int>::const_iterator it = mvBackupMergeEdgesId.begin(), end = mvBackupMergeEdgesId.end(); it != end; ++it)
|
|
||||||
{
|
|
||||||
mspMergeEdges.insert(mpKFid[*it]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Camera data
|
|
||||||
if(mnBackupIdCamera >= 0)
|
|
||||||
{
|
|
||||||
mpCamera = mpCamId[mnBackupIdCamera];
|
|
||||||
}
|
|
||||||
if(mnBackupIdCamera2 >= 0)
|
|
||||||
{
|
|
||||||
mpCamera2 = mpCamId[mnBackupIdCamera2];
|
|
||||||
}
|
|
||||||
|
|
||||||
//Inertial data
|
|
||||||
if(mBackupPrevKFId != -1)
|
|
||||||
{
|
|
||||||
mPrevKF = mpKFid[mBackupPrevKFId];
|
|
||||||
}
|
|
||||||
if(mBackupNextKFId != -1)
|
|
||||||
{
|
|
||||||
mNextKF = mpKFid[mBackupNextKFId];
|
|
||||||
}
|
|
||||||
mpImuPreintegrated = &mBackupImuPreintegrated;
|
|
||||||
|
|
||||||
|
|
||||||
// Remove all backup container
|
|
||||||
mvBackupMapPointsId.clear();
|
|
||||||
mBackupConnectedKeyFrameIdWeights.clear();
|
|
||||||
mvBackupChildrensId.clear();
|
|
||||||
mvBackupLoopEdgesId.clear();
|
|
||||||
|
|
||||||
UpdateBestCovisibles();
|
|
||||||
|
|
||||||
//ComputeSceneMedianDepth();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool KeyFrame::ProjectPointDistort(MapPoint* pMP, cv::Point2f &kp, float &u, float &v)
|
bool KeyFrame::ProjectPointDistort(MapPoint* pMP, cv::Point2f &kp, float &u, float &v)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1427,4 +1269,94 @@ void KeyFrame::SetKeyFrameDatabase(KeyFrameDatabase* pKFDB)
|
||||||
mpKeyFrameDB = pKFDB;
|
mpKeyFrameDB = pKFDB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cv::Matx33f KeyFrame::GetRotation_() {
|
||||||
|
unique_lock<mutex> lock(mMutexPose);
|
||||||
|
return Tcw_.get_minor<3,3>(0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Matx31f KeyFrame::GetTranslation_() {
|
||||||
|
unique_lock<mutex> lock(mMutexPose);
|
||||||
|
return Tcw_.get_minor<3,1>(0,3);
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Matx31f KeyFrame::GetCameraCenter_() {
|
||||||
|
unique_lock<mutex> lock(mMutexPose);
|
||||||
|
return Ow_;
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Matx33f KeyFrame::GetRightRotation_() {
|
||||||
|
unique_lock<mutex> lock(mMutexPose);
|
||||||
|
cv::Matx33f Rrl = Tlr_.get_minor<3,3>(0,0).t();
|
||||||
|
cv::Matx33f Rlw = Tcw_.get_minor<3,3>(0,0);
|
||||||
|
cv::Matx33f Rrw = Rrl * Rlw;
|
||||||
|
|
||||||
|
return Rrw;
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Matx31f KeyFrame::GetRightTranslation_() {
|
||||||
|
unique_lock<mutex> lock(mMutexPose);
|
||||||
|
cv::Matx33f Rrl = Tlr_.get_minor<3,3>(0,0).t();
|
||||||
|
cv::Matx31f tlw = Tcw_.get_minor<3,1>(0,3);
|
||||||
|
cv::Matx31f trl = - Rrl * Tlr_.get_minor<3,1>(0,3);
|
||||||
|
|
||||||
|
cv::Matx31f trw = Rrl * tlw + trl;
|
||||||
|
|
||||||
|
return trw;
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Matx44f KeyFrame::GetRightPose_() {
|
||||||
|
unique_lock<mutex> lock(mMutexPose);
|
||||||
|
|
||||||
|
cv::Matx33f Rrl = Tlr_.get_minor<3,3>(0,0).t();
|
||||||
|
cv::Matx33f Rlw = Tcw_.get_minor<3,3>(0,0);
|
||||||
|
cv::Matx33f Rrw = Rrl * Rlw;
|
||||||
|
|
||||||
|
cv::Matx31f tlw = Tcw_.get_minor<3,1>(0,3);
|
||||||
|
cv::Matx31f trl = - Rrl * Tlr_.get_minor<3,1>(0,3);
|
||||||
|
|
||||||
|
cv::Matx31f trw = Rrl * tlw + trl;
|
||||||
|
|
||||||
|
cv::Matx44f Trw{Rrw(0,0),Rrw(0,1),Rrw(0,2),trw(0),
|
||||||
|
Rrw(1,0),Rrw(1,1),Rrw(1,2),trw(1),
|
||||||
|
Rrw(2,0),Rrw(2,1),Rrw(2,2),trw(2),
|
||||||
|
0.f,0.f,0.f,1.f};
|
||||||
|
|
||||||
|
return Trw;
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Matx31f KeyFrame::GetRightCameraCenter_() {
|
||||||
|
unique_lock<mutex> lock(mMutexPose);
|
||||||
|
cv::Matx33f Rwl = Tcw_.get_minor<3,3>(0,0).t();
|
||||||
|
cv::Matx31f tlr = Tlr_.get_minor<3,1>(0,3);
|
||||||
|
|
||||||
|
cv::Matx31f twr = Rwl * tlr + Ow_;
|
||||||
|
|
||||||
|
return twr;
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Matx31f KeyFrame::UnprojectStereo_(int i) {
|
||||||
|
const float z = mvDepth[i];
|
||||||
|
if(z>0)
|
||||||
|
{
|
||||||
|
const float u = mvKeys[i].pt.x;
|
||||||
|
const float v = mvKeys[i].pt.y;
|
||||||
|
const float x = (u-cx)*z*invfx;
|
||||||
|
const float y = (v-cy)*z*invfy;
|
||||||
|
cv::Matx31f x3Dc(x,y,z);
|
||||||
|
|
||||||
|
unique_lock<mutex> lock(mMutexPose);
|
||||||
|
return Twc_.get_minor<3,3>(0,0) * x3Dc + Twc_.get_minor<3,1>(0,3);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return cv::Matx31f::zeros();
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Matx44f KeyFrame::GetPose_()
|
||||||
|
{
|
||||||
|
unique_lock<mutex> lock(mMutexPose);
|
||||||
|
return Tcw_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} //namespace ORB_SLAM
|
} //namespace ORB_SLAM
|
||||||
|
|
|
@ -934,36 +934,6 @@ vector<KeyFrame*> KeyFrameDatabase::DetectRelocalizationCandidates(Frame *F, Map
|
||||||
return vpRelocCandidates;
|
return vpRelocCandidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyFrameDatabase::PreSave()
|
|
||||||
{
|
|
||||||
//Save the information about the inverted index of KF to node
|
|
||||||
mvBackupInvertedFileId.resize(mvInvertedFile.size());
|
|
||||||
for(int i = 0, numEl = mvInvertedFile.size(); i < numEl; ++i)
|
|
||||||
{
|
|
||||||
for(std::list<KeyFrame*>::const_iterator it = mvInvertedFile[i].begin(), end = mvInvertedFile[i].end(); it != end; ++it)
|
|
||||||
{
|
|
||||||
mvBackupInvertedFileId[i].push_back((*it)->mnId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyFrameDatabase::PostLoad(map<long unsigned int, KeyFrame*> mpKFid)
|
|
||||||
{
|
|
||||||
mvInvertedFile.clear();
|
|
||||||
mvInvertedFile.resize(mpVoc->size());
|
|
||||||
for(unsigned int i = 0; i < mvBackupInvertedFileId.size(); ++i)
|
|
||||||
{
|
|
||||||
for(long unsigned int KFid : mvBackupInvertedFileId[i])
|
|
||||||
{
|
|
||||||
if(mpKFid.find(KFid) != mpKFid.end())
|
|
||||||
{
|
|
||||||
mvInvertedFile[i].push_back(mpKFid[KFid]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyFrameDatabase::SetORBVocabulary(ORBVocabulary* pORBVoc)
|
void KeyFrameDatabase::SetORBVocabulary(ORBVocabulary* pORBVoc)
|
||||||
{
|
{
|
||||||
ORBVocabulary** ptr;
|
ORBVocabulary** ptr;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "ORBmatcher.h"
|
#include "ORBmatcher.h"
|
||||||
#include "Optimizer.h"
|
#include "Optimizer.h"
|
||||||
#include "Converter.h"
|
#include "Converter.h"
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
#include<mutex>
|
#include<mutex>
|
||||||
#include<chrono>
|
#include<chrono>
|
||||||
|
@ -32,7 +33,7 @@ namespace ORB_SLAM3
|
||||||
LocalMapping::LocalMapping(System* pSys, Atlas *pAtlas, const float bMonocular, bool bInertial, const string &_strSeqName):
|
LocalMapping::LocalMapping(System* pSys, Atlas *pAtlas, const float bMonocular, bool bInertial, const string &_strSeqName):
|
||||||
mpSystem(pSys), mbMonocular(bMonocular), mbInertial(bInertial), mbResetRequested(false), mbResetRequestedActiveMap(false), mbFinishRequested(false), mbFinished(true), mpAtlas(pAtlas), bInitializing(false),
|
mpSystem(pSys), mbMonocular(bMonocular), mbInertial(bInertial), mbResetRequested(false), mbResetRequestedActiveMap(false), mbFinishRequested(false), mbFinished(true), mpAtlas(pAtlas), bInitializing(false),
|
||||||
mbAbortBA(false), mbStopped(false), mbStopRequested(false), mbNotStop(false), mbAcceptKeyFrames(true),
|
mbAbortBA(false), mbStopped(false), mbStopRequested(false), mbNotStop(false), mbAcceptKeyFrames(true),
|
||||||
mbNewInit(false), mIdxInit(0), mScale(1.0), mInitSect(0), mbNotBA1(true), mbNotBA2(true), mIdxIteration(0), infoInertial(Eigen::MatrixXd::Zero(9,9))
|
mbNewInit(false), mIdxInit(0), mScale(1.0), mInitSect(0), mbNotBA1(true), mbNotBA2(true), infoInertial(Eigen::MatrixXd::Zero(9,9))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* mbStopRequested: 外部线程调用,为true,表示外部线程请求停止 local mapping
|
* mbStopRequested: 外部线程调用,为true,表示外部线程请求停止 local mapping
|
||||||
|
@ -53,15 +54,11 @@ LocalMapping::LocalMapping(System* pSys, Atlas *pAtlas, const float bMonocular,
|
||||||
mNumLM = 0;
|
mNumLM = 0;
|
||||||
mNumKFCulling=0;
|
mNumKFCulling=0;
|
||||||
|
|
||||||
//DEBUG: times and data from LocalMapping in each frame
|
#ifdef REGISTER_TIMES
|
||||||
|
nLBA_exec = 0;
|
||||||
|
nLBA_abort = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
strSequence = "";//_strSeqName;
|
|
||||||
|
|
||||||
//f_lm.open("localMapping_times" + strSequence + ".txt");
|
|
||||||
/*f_lm.open("localMapping_times.txt");
|
|
||||||
|
|
||||||
f_lm << "# Timestamp KF, Num CovKFs, Num KFs, Num RecentMPs, Num MPs, processKF, MPCulling, CreateMP, SearchNeigh, BA, KFCulling, [numFixKF_LBA]" << endl;
|
|
||||||
f_lm << fixed;*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置回环检测线程句柄
|
// 设置回环检测线程句柄
|
||||||
|
@ -94,31 +91,34 @@ void LocalMapping::Run()
|
||||||
// 等待处理的关键帧列表不为空 并且imu正常
|
// 等待处理的关键帧列表不为空 并且imu正常
|
||||||
if(CheckNewKeyFrames() && !mbBadImu)
|
if(CheckNewKeyFrames() && !mbBadImu)
|
||||||
{
|
{
|
||||||
// std::cout << "LM" << std::endl;
|
|
||||||
std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
double timeLBA_ms = 0;
|
||||||
|
double timeKFCulling_ms = 0;
|
||||||
|
|
||||||
|
std::chrono::steady_clock::time_point time_StartProcessKF = std::chrono::steady_clock::now();
|
||||||
|
#endif
|
||||||
// BoW conversion and insertion in Map
|
// BoW conversion and insertion in Map
|
||||||
// Step 2 处理列表中的关键帧,包括计算BoW、更新观测、描述子、共视图,插入到地图等
|
// Step 2 处理列表中的关键帧,包括计算BoW、更新观测、描述子、共视图,插入到地图等
|
||||||
ProcessNewKeyFrame();
|
ProcessNewKeyFrame();
|
||||||
std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_EndProcessKF = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
double timeProcessKF = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndProcessKF - time_StartProcessKF).count();
|
||||||
|
vdKFInsert_ms.push_back(timeProcessKF);
|
||||||
|
#endif
|
||||||
// Check recent MapPoints
|
// Check recent MapPoints
|
||||||
// Step 3 根据地图点的观测情况剔除质量不好的地图点
|
// Step 3 根据地图点的观测情况剔除质量不好的地图点
|
||||||
MapPointCulling();
|
MapPointCulling();
|
||||||
std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_EndMPCulling = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
double timeMPCulling = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndMPCulling - time_EndProcessKF).count();
|
||||||
|
vdMPCulling_ms.push_back(timeMPCulling);
|
||||||
|
#endif
|
||||||
// Triangulate new MapPoints
|
// Triangulate new MapPoints
|
||||||
// Step 4 当前关键帧与相邻关键帧通过三角化产生新的地图点,使得跟踪更稳
|
// Step 4 当前关键帧与相邻关键帧通过三角化产生新的地图点,使得跟踪更稳
|
||||||
CreateNewMapPoints();
|
CreateNewMapPoints();
|
||||||
std::chrono::steady_clock::time_point t3 = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
// Save here:
|
|
||||||
// # Cov KFs
|
|
||||||
// # tot Kfs
|
|
||||||
// # recent added MPs
|
|
||||||
// # tot MPs
|
|
||||||
// # localMPs in LBA
|
|
||||||
// # fixedKFs in LBA
|
|
||||||
|
|
||||||
mbAbortBA = false;
|
mbAbortBA = false;
|
||||||
// 已经处理完队列中的最后的一个关键帧
|
// 已经处理完队列中的最后的一个关键帧
|
||||||
|
@ -129,19 +129,18 @@ void LocalMapping::Run()
|
||||||
SearchInNeighbors();
|
SearchInNeighbors();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::steady_clock::time_point t4 = std::chrono::steady_clock::now();
|
#ifdef REGISTER_TIMES
|
||||||
std::chrono::steady_clock::time_point t5 = t4, t6 = t4;
|
std::chrono::steady_clock::time_point time_EndMPCreation = std::chrono::steady_clock::now();
|
||||||
// mbAbortBA = false;
|
|
||||||
|
|
||||||
//DEBUG--
|
double timeMPCreation = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndMPCreation - time_EndMPCulling).count();
|
||||||
/*f_lm << setprecision(0);
|
vdMPCreation_ms.push_back(timeMPCreation);
|
||||||
f_lm << mpCurrentKeyFrame->mTimeStamp*1e9 << ",";
|
#endif
|
||||||
f_lm << mpCurrentKeyFrame->GetVectorCovisibleKeyFrames().size() << ",";
|
|
||||||
f_lm << mpCurrentKeyFrame->GetMap()->GetAllKeyFrames().size() << ",";
|
bool b_doneLBA = false;
|
||||||
f_lm << mlpRecentAddedMapPoints.size() << ",";
|
|
||||||
f_lm << mpCurrentKeyFrame->GetMap()->GetAllMapPoints().size() << ",";*/
|
|
||||||
//--
|
|
||||||
int num_FixedKF_BA = 0;
|
int num_FixedKF_BA = 0;
|
||||||
|
int num_OptKF_BA = 0;
|
||||||
|
int num_MPs_BA = 0;
|
||||||
|
int num_edges_BA = 0;
|
||||||
// 已经处理完队列中的最后的一个关键帧,并且闭环检测没有请求停止LocalMapping
|
// 已经处理完队列中的最后的一个关键帧,并且闭环检测没有请求停止LocalMapping
|
||||||
if(!CheckNewKeyFrames() && !stopRequested())
|
if(!CheckNewKeyFrames() && !stopRequested())
|
||||||
{
|
{
|
||||||
|
@ -172,21 +171,39 @@ void LocalMapping::Run()
|
||||||
}
|
}
|
||||||
// 条件---------1.1、跟踪成功的内点数目大于75-----1.2、并且是单目--或--2.1、跟踪成功的内点数目大于100-----2.2、并且不是单目
|
// 条件---------1.1、跟踪成功的内点数目大于75-----1.2、并且是单目--或--2.1、跟踪成功的内点数目大于100-----2.2、并且不是单目
|
||||||
bool bLarge = ((mpTracker->GetMatchesInliers()>75)&&mbMonocular)||((mpTracker->GetMatchesInliers()>100)&&!mbMonocular);
|
bool bLarge = ((mpTracker->GetMatchesInliers()>75)&&mbMonocular)||((mpTracker->GetMatchesInliers()>100)&&!mbMonocular);
|
||||||
// BA优化局部地图IMU
|
Optimizer::LocalInertialBA(mpCurrentKeyFrame, &mbAbortBA, mpCurrentKeyFrame->GetMap(),num_FixedKF_BA,num_OptKF_BA,num_MPs_BA,num_edges_BA, bLarge, !mpCurrentKeyFrame->GetMap()->GetIniertialBA2());
|
||||||
Optimizer::LocalInertialBA(mpCurrentKeyFrame, &mbAbortBA, mpCurrentKeyFrame->GetMap(), bLarge, !mpCurrentKeyFrame->GetMap()->GetIniertialBA2());
|
b_doneLBA = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Step 6.2 不是IMU模式或者当前关键帧所在的地图还未完成IMU初始化
|
// Step 6.2 不是IMU模式或者当前关键帧所在的地图还未完成IMU初始化
|
||||||
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
|
|
||||||
// 局部地图BA,不包括IMU数据
|
// 局部地图BA,不包括IMU数据
|
||||||
// 注意这里的第二个参数是按地址传递的,当这里的 mbAbortBA 状态发生变化时,能够及时执行/停止BA
|
// 注意这里的第二个参数是按地址传递的,当这里的 mbAbortBA 状态发生变化时,能够及时执行/停止BA
|
||||||
Optimizer::LocalBundleAdjustment(mpCurrentKeyFrame,&mbAbortBA, mpCurrentKeyFrame->GetMap(),num_FixedKF_BA);
|
Optimizer::LocalBundleAdjustment(mpCurrentKeyFrame,&mbAbortBA, mpCurrentKeyFrame->GetMap(),num_FixedKF_BA,num_OptKF_BA,num_MPs_BA,num_edges_BA);
|
||||||
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
|
b_doneLBA = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
t5 = std::chrono::steady_clock::now();
|
}
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_EndLBA = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
if(b_doneLBA)
|
||||||
|
{
|
||||||
|
timeLBA_ms = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndLBA - time_EndMPCreation).count();
|
||||||
|
vdLBASync_ms.push_back(timeLBA_ms);
|
||||||
|
|
||||||
|
nLBA_exec += 1;
|
||||||
|
if(mbAbortBA)
|
||||||
|
{
|
||||||
|
nLBA_abort += 1;
|
||||||
|
}
|
||||||
|
vnLBA_edges.push_back(num_edges_BA);
|
||||||
|
vnLBA_KFopt.push_back(num_OptKF_BA);
|
||||||
|
vnLBA_KFfixed.push_back(num_FixedKF_BA);
|
||||||
|
vnLBA_MPs.push_back(num_MPs_BA);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// Initialize IMU here
|
// Initialize IMU here
|
||||||
// Step 7 当前关键帧所在地图的IMU初始化
|
// Step 7 当前关键帧所在地图的IMU初始化
|
||||||
|
@ -204,7 +221,12 @@ void LocalMapping::Run()
|
||||||
// 冗余的判定:该关键帧的90%的地图点可以被其它关键帧观测到
|
// 冗余的判定:该关键帧的90%的地图点可以被其它关键帧观测到
|
||||||
KeyFrameCulling();
|
KeyFrameCulling();
|
||||||
|
|
||||||
t6 = std::chrono::steady_clock::now();
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_EndKFCulling = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
timeKFCulling_ms = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndKFCulling - time_EndLBA).count();
|
||||||
|
vdKFCullingSync_ms.push_back(timeKFCulling_ms);
|
||||||
|
#endif
|
||||||
// Step 9 如果累计时间差小于100s 并且 是IMU模式,进行VIBA
|
// Step 9 如果累计时间差小于100s 并且 是IMU模式,进行VIBA
|
||||||
if ((mTinit<100.0f) && mbInertial)
|
if ((mTinit<100.0f) && mbInertial)
|
||||||
{
|
{
|
||||||
|
@ -262,31 +284,21 @@ void LocalMapping::Run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::chrono::steady_clock::time_point t7 = std::chrono::steady_clock::now();
|
#ifdef REGISTER_TIMES
|
||||||
|
vdLBA_ms.push_back(timeLBA_ms);
|
||||||
|
vdKFCulling_ms.push_back(timeKFCulling_ms);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Step 10 将当前帧加入到闭环检测队列中
|
// Step 10 将当前帧加入到闭环检测队列中
|
||||||
mpLoopCloser->InsertKeyFrame(mpCurrentKeyFrame);
|
mpLoopCloser->InsertKeyFrame(mpCurrentKeyFrame);
|
||||||
std::chrono::steady_clock::time_point t8 = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
double t_procKF = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t1 - t0).count();
|
|
||||||
double t_MPcull = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t2 - t1).count();
|
|
||||||
double t_CheckMP = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t3 - t2).count();
|
|
||||||
double t_searchNeigh = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t4 - t3).count();
|
|
||||||
double t_Opt = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t5 - t4).count();
|
|
||||||
double t_KF_cull = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t6 - t5).count();
|
|
||||||
double t_Insert = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t8 - t7).count();
|
|
||||||
|
|
||||||
//DEBUG--
|
#ifdef REGISTER_TIMES
|
||||||
/*f_lm << setprecision(6);
|
std::chrono::steady_clock::time_point time_EndLocalMap = std::chrono::steady_clock::now();
|
||||||
f_lm << t_procKF << ",";
|
|
||||||
f_lm << t_MPcull << ",";
|
|
||||||
f_lm << t_CheckMP << ",";
|
|
||||||
f_lm << t_searchNeigh << ",";
|
|
||||||
f_lm << t_Opt << ",";
|
|
||||||
f_lm << t_KF_cull << ",";
|
|
||||||
f_lm << setprecision(0) << num_FixedKF_BA << "\n";*/
|
|
||||||
//--
|
|
||||||
|
|
||||||
|
double timeLocalMap = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndLocalMap - time_StartProcessKF).count();
|
||||||
|
vdLMTotal_ms.push_back(timeLocalMap);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if(Stop() && !mbBadImu) // 当要终止当前线程的时候
|
else if(Stop() && !mbBadImu) // 当要终止当前线程的时候
|
||||||
{
|
{
|
||||||
|
@ -493,15 +505,16 @@ void LocalMapping::CreateNewMapPoints()
|
||||||
ORBmatcher matcher(th,false);
|
ORBmatcher matcher(th,false);
|
||||||
|
|
||||||
// 取出当前帧从世界坐标系到相机坐标系的变换矩阵
|
// 取出当前帧从世界坐标系到相机坐标系的变换矩阵
|
||||||
cv::Mat Rcw1 = mpCurrentKeyFrame->GetRotation();
|
auto Rcw1 = mpCurrentKeyFrame->GetRotation_();
|
||||||
cv::Mat Rwc1 = Rcw1.t();
|
auto Rwc1 = Rcw1.t();
|
||||||
cv::Mat tcw1 = mpCurrentKeyFrame->GetTranslation();
|
auto tcw1 = mpCurrentKeyFrame->GetTranslation_();
|
||||||
cv::Mat Tcw1(3,4,CV_32F);
|
cv::Matx44f Tcw1{Rcw1(0,0),Rcw1(0,1),Rcw1(0,2),tcw1(0),
|
||||||
Rcw1.copyTo(Tcw1.colRange(0,3));
|
Rcw1(1,0),Rcw1(1,1),Rcw1(1,2),tcw1(1),
|
||||||
tcw1.copyTo(Tcw1.col(3));
|
Rcw1(2,0),Rcw1(2,1),Rcw1(2,2),tcw1(2),
|
||||||
|
0.f,0.f,0.f,1.f};
|
||||||
|
|
||||||
// 得到当前关键帧(左目)光心在世界坐标系中的坐标、内参
|
// 得到当前关键帧(左目)光心在世界坐标系中的坐标、内参
|
||||||
cv::Mat Ow1 = mpCurrentKeyFrame->GetCameraCenter();
|
auto Ow1 = mpCurrentKeyFrame->GetCameraCenter_();
|
||||||
|
|
||||||
const float &fx1 = mpCurrentKeyFrame->fx;
|
const float &fx1 = mpCurrentKeyFrame->fx;
|
||||||
const float &fy1 = mpCurrentKeyFrame->fy;
|
const float &fy1 = mpCurrentKeyFrame->fy;
|
||||||
|
@ -527,9 +540,9 @@ void LocalMapping::CreateNewMapPoints()
|
||||||
|
|
||||||
// Check first that baseline is not too short
|
// Check first that baseline is not too short
|
||||||
// 邻接的关键帧光心在世界坐标系中的坐标
|
// 邻接的关键帧光心在世界坐标系中的坐标
|
||||||
cv::Mat Ow2 = pKF2->GetCameraCenter();
|
auto Ow2 = pKF2->GetCameraCenter_();
|
||||||
// 基线向量,两个关键帧间的相机位移
|
// 基线向量,两个关键帧间的相机位移
|
||||||
cv::Mat vBaseline = Ow2-Ow1;
|
auto vBaseline = Ow2-Ow1;
|
||||||
// 基线长度
|
// 基线长度
|
||||||
const float baseline = cv::norm(vBaseline);
|
const float baseline = cv::norm(vBaseline);
|
||||||
|
|
||||||
|
@ -555,7 +568,7 @@ void LocalMapping::CreateNewMapPoints()
|
||||||
|
|
||||||
// Compute Fundamental Matrix
|
// Compute Fundamental Matrix
|
||||||
// Step 4:根据两个关键帧的位姿计算它们之间的基础矩阵
|
// Step 4:根据两个关键帧的位姿计算它们之间的基础矩阵
|
||||||
cv::Mat F12 = ComputeF12(mpCurrentKeyFrame,pKF2);
|
auto F12 = ComputeF12_(mpCurrentKeyFrame,pKF2);
|
||||||
|
|
||||||
// Search matches that fullfil epipolar constraint
|
// Search matches that fullfil epipolar constraint
|
||||||
// Step 5:通过BoW对两关键帧的未匹配的特征点快速匹配,用极线约束抑制离群点,生成新的匹配点对
|
// Step 5:通过BoW对两关键帧的未匹配的特征点快速匹配,用极线约束抑制离群点,生成新的匹配点对
|
||||||
|
@ -563,14 +576,16 @@ void LocalMapping::CreateNewMapPoints()
|
||||||
bool bCoarse = mbInertial &&
|
bool bCoarse = mbInertial &&
|
||||||
((!mpCurrentKeyFrame->GetMap()->GetIniertialBA2() && mpCurrentKeyFrame->GetMap()->GetIniertialBA1())||
|
((!mpCurrentKeyFrame->GetMap()->GetIniertialBA2() && mpCurrentKeyFrame->GetMap()->GetIniertialBA1())||
|
||||||
mpTracker->mState==Tracking::RECENTLY_LOST);
|
mpTracker->mState==Tracking::RECENTLY_LOST);
|
||||||
matcher.SearchForTriangulation(mpCurrentKeyFrame,pKF2,F12,vMatchedIndices,false,bCoarse);
|
|
||||||
|
|
||||||
cv::Mat Rcw2 = pKF2->GetRotation();
|
matcher.SearchForTriangulation_(mpCurrentKeyFrame,pKF2,F12,vMatchedIndices,false,bCoarse);
|
||||||
cv::Mat Rwc2 = Rcw2.t();
|
|
||||||
cv::Mat tcw2 = pKF2->GetTranslation();
|
auto Rcw2 = pKF2->GetRotation_();
|
||||||
cv::Mat Tcw2(3,4,CV_32F);
|
auto Rwc2 = Rcw2.t();
|
||||||
Rcw2.copyTo(Tcw2.colRange(0,3));
|
auto tcw2 = pKF2->GetTranslation_();
|
||||||
tcw2.copyTo(Tcw2.col(3));
|
cv::Matx44f Tcw2{Rcw2(0,0),Rcw2(0,1),Rcw2(0,2),tcw2(0),
|
||||||
|
Rcw2(1,0),Rcw2(1,1),Rcw2(1,2),tcw2(1),
|
||||||
|
Rcw2(2,0),Rcw2(2,1),Rcw2(2,2),tcw2(2),
|
||||||
|
0.f,0.f,0.f,1.f};
|
||||||
|
|
||||||
const float &fx2 = pKF2->fx;
|
const float &fx2 = pKF2->fx;
|
||||||
const float &fy2 = pKF2->fy;
|
const float &fy2 = pKF2->fy;
|
||||||
|
@ -612,65 +627,65 @@ void LocalMapping::CreateNewMapPoints()
|
||||||
|
|
||||||
if(mpCurrentKeyFrame->mpCamera2 && pKF2->mpCamera2){
|
if(mpCurrentKeyFrame->mpCamera2 && pKF2->mpCamera2){
|
||||||
if(bRight1 && bRight2){
|
if(bRight1 && bRight2){
|
||||||
Rcw1 = mpCurrentKeyFrame->GetRightRotation();
|
Rcw1 = mpCurrentKeyFrame->GetRightRotation_();
|
||||||
Rwc1 = Rcw1.t();
|
Rwc1 = Rcw1.t();
|
||||||
tcw1 = mpCurrentKeyFrame->GetRightTranslation();
|
tcw1 = mpCurrentKeyFrame->GetRightTranslation_();
|
||||||
Tcw1 = mpCurrentKeyFrame->GetRightPose();
|
Tcw1 = mpCurrentKeyFrame->GetRightPose_();
|
||||||
Ow1 = mpCurrentKeyFrame->GetRightCameraCenter();
|
Ow1 = mpCurrentKeyFrame->GetRightCameraCenter_();
|
||||||
|
|
||||||
Rcw2 = pKF2->GetRightRotation();
|
Rcw2 = pKF2->GetRightRotation_();
|
||||||
Rwc2 = Rcw2.t();
|
Rwc2 = Rcw2.t();
|
||||||
tcw2 = pKF2->GetRightTranslation();
|
tcw2 = pKF2->GetRightTranslation_();
|
||||||
Tcw2 = pKF2->GetRightPose();
|
Tcw2 = pKF2->GetRightPose_();
|
||||||
Ow2 = pKF2->GetRightCameraCenter();
|
Ow2 = pKF2->GetRightCameraCenter_();
|
||||||
|
|
||||||
pCamera1 = mpCurrentKeyFrame->mpCamera2;
|
pCamera1 = mpCurrentKeyFrame->mpCamera2;
|
||||||
pCamera2 = pKF2->mpCamera2;
|
pCamera2 = pKF2->mpCamera2;
|
||||||
}
|
}
|
||||||
else if(bRight1 && !bRight2){
|
else if(bRight1 && !bRight2){
|
||||||
Rcw1 = mpCurrentKeyFrame->GetRightRotation();
|
Rcw1 = mpCurrentKeyFrame->GetRightRotation_();
|
||||||
Rwc1 = Rcw1.t();
|
Rwc1 = Rcw1.t();
|
||||||
tcw1 = mpCurrentKeyFrame->GetRightTranslation();
|
tcw1 = mpCurrentKeyFrame->GetRightTranslation_();
|
||||||
Tcw1 = mpCurrentKeyFrame->GetRightPose();
|
Tcw1 = mpCurrentKeyFrame->GetRightPose_();
|
||||||
Ow1 = mpCurrentKeyFrame->GetRightCameraCenter();
|
Ow1 = mpCurrentKeyFrame->GetRightCameraCenter_();
|
||||||
|
|
||||||
Rcw2 = pKF2->GetRotation();
|
Rcw2 = pKF2->GetRotation_();
|
||||||
Rwc2 = Rcw2.t();
|
Rwc2 = Rcw2.t();
|
||||||
tcw2 = pKF2->GetTranslation();
|
tcw2 = pKF2->GetTranslation_();
|
||||||
Tcw2 = pKF2->GetPose();
|
Tcw2 = pKF2->GetPose_();
|
||||||
Ow2 = pKF2->GetCameraCenter();
|
Ow2 = pKF2->GetCameraCenter_();
|
||||||
|
|
||||||
pCamera1 = mpCurrentKeyFrame->mpCamera2;
|
pCamera1 = mpCurrentKeyFrame->mpCamera2;
|
||||||
pCamera2 = pKF2->mpCamera;
|
pCamera2 = pKF2->mpCamera;
|
||||||
}
|
}
|
||||||
else if(!bRight1 && bRight2){
|
else if(!bRight1 && bRight2){
|
||||||
Rcw1 = mpCurrentKeyFrame->GetRotation();
|
Rcw1 = mpCurrentKeyFrame->GetRotation_();
|
||||||
Rwc1 = Rcw1.t();
|
Rwc1 = Rcw1.t();
|
||||||
tcw1 = mpCurrentKeyFrame->GetTranslation();
|
tcw1 = mpCurrentKeyFrame->GetTranslation_();
|
||||||
Tcw1 = mpCurrentKeyFrame->GetPose();
|
Tcw1 = mpCurrentKeyFrame->GetPose_();
|
||||||
Ow1 = mpCurrentKeyFrame->GetCameraCenter();
|
Ow1 = mpCurrentKeyFrame->GetCameraCenter_();
|
||||||
|
|
||||||
Rcw2 = pKF2->GetRightRotation();
|
Rcw2 = pKF2->GetRightRotation_();
|
||||||
Rwc2 = Rcw2.t();
|
Rwc2 = Rcw2.t();
|
||||||
tcw2 = pKF2->GetRightTranslation();
|
tcw2 = pKF2->GetRightTranslation_();
|
||||||
Tcw2 = pKF2->GetRightPose();
|
Tcw2 = pKF2->GetRightPose_();
|
||||||
Ow2 = pKF2->GetRightCameraCenter();
|
Ow2 = pKF2->GetRightCameraCenter_();
|
||||||
|
|
||||||
pCamera1 = mpCurrentKeyFrame->mpCamera;
|
pCamera1 = mpCurrentKeyFrame->mpCamera;
|
||||||
pCamera2 = pKF2->mpCamera2;
|
pCamera2 = pKF2->mpCamera2;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
Rcw1 = mpCurrentKeyFrame->GetRotation();
|
Rcw1 = mpCurrentKeyFrame->GetRotation_();
|
||||||
Rwc1 = Rcw1.t();
|
Rwc1 = Rcw1.t();
|
||||||
tcw1 = mpCurrentKeyFrame->GetTranslation();
|
tcw1 = mpCurrentKeyFrame->GetTranslation_();
|
||||||
Tcw1 = mpCurrentKeyFrame->GetPose();
|
Tcw1 = mpCurrentKeyFrame->GetPose_();
|
||||||
Ow1 = mpCurrentKeyFrame->GetCameraCenter();
|
Ow1 = mpCurrentKeyFrame->GetCameraCenter_();
|
||||||
|
|
||||||
Rcw2 = pKF2->GetRotation();
|
Rcw2 = pKF2->GetRotation_();
|
||||||
Rwc2 = Rcw2.t();
|
Rwc2 = Rcw2.t();
|
||||||
tcw2 = pKF2->GetTranslation();
|
tcw2 = pKF2->GetTranslation_();
|
||||||
Tcw2 = pKF2->GetPose();
|
Tcw2 = pKF2->GetPose_();
|
||||||
Ow2 = pKF2->GetCameraCenter();
|
Ow2 = pKF2->GetCameraCenter_();
|
||||||
|
|
||||||
pCamera1 = mpCurrentKeyFrame->mpCamera;
|
pCamera1 = mpCurrentKeyFrame->mpCamera;
|
||||||
pCamera2 = pKF2->mpCamera;
|
pCamera2 = pKF2->mpCamera;
|
||||||
|
@ -680,11 +695,11 @@ void LocalMapping::CreateNewMapPoints()
|
||||||
// Check parallax between rays
|
// Check parallax between rays
|
||||||
// Step 6.2:利用匹配点反投影得到视差角
|
// Step 6.2:利用匹配点反投影得到视差角
|
||||||
// 特征点反投影,其实得到的是在各自相机坐标系下的一个非归一化的方向向量,和这个点的反投影射线重合
|
// 特征点反投影,其实得到的是在各自相机坐标系下的一个非归一化的方向向量,和这个点的反投影射线重合
|
||||||
cv::Mat xn1 = pCamera1->unprojectMat(kp1.pt);
|
auto xn1 = pCamera1->unprojectMat_(kp1.pt);
|
||||||
cv::Mat xn2 = pCamera2->unprojectMat(kp2.pt);
|
auto xn2 = pCamera2->unprojectMat_(kp2.pt);
|
||||||
// 由相机坐标系转到世界坐标系(得到的是那条反投影射线的一个同向向量在世界坐标系下的表示,还是只能够表示方向),得到视差角余弦值
|
// 由相机坐标系转到世界坐标系(得到的是那条反投影射线的一个同向向量在世界坐标系下的表示,还是只能够表示方向),得到视差角余弦值
|
||||||
cv::Mat ray1 = Rwc1*xn1;
|
auto ray1 = Rwc1*xn1;
|
||||||
cv::Mat ray2 = Rwc2*xn2;
|
auto ray2 = Rwc2*xn2;
|
||||||
// 这个就是求向量之间角度公式
|
// 这个就是求向量之间角度公式
|
||||||
const float cosParallaxRays = ray1.dot(ray2)/(cv::norm(ray1)*cv::norm(ray2));
|
const float cosParallaxRays = ray1.dot(ray2)/(cv::norm(ray1)*cv::norm(ray2));
|
||||||
|
|
||||||
|
@ -706,68 +721,70 @@ void LocalMapping::CreateNewMapPoints()
|
||||||
|
|
||||||
// 得到双目观测的视差角
|
// 得到双目观测的视差角
|
||||||
cosParallaxStereo = min(cosParallaxStereo1,cosParallaxStereo2);
|
cosParallaxStereo = min(cosParallaxStereo1,cosParallaxStereo2);
|
||||||
|
|
||||||
// Step 6.4:三角化恢复3D点
|
// Step 6.4:三角化恢复3D点
|
||||||
cv::Mat x3D;
|
cv::Matx31f x3D;
|
||||||
// cosParallaxRays>0 && (bStereo1 || bStereo2 || cosParallaxRays<0.9998)表明视差角正常,0.9998 对应1°
|
bool bEstimated = false;
|
||||||
// cosParallaxRays < cosParallaxStereo 表明视差角很小
|
|
||||||
// ?视差角度小时用三角法恢复3D点,视差角大时用双目恢复3D点(双目以及深度有效)
|
|
||||||
// 参考:https://github.com/raulmur/ORB_SLAM2/issues/345
|
|
||||||
if(cosParallaxRays<cosParallaxStereo && cosParallaxRays>0 && (bStereo1 || bStereo2 ||
|
if(cosParallaxRays<cosParallaxStereo && cosParallaxRays>0 && (bStereo1 || bStereo2 ||
|
||||||
(cosParallaxRays<0.9998 && mbInertial) || (cosParallaxRays<0.9998 && !mbInertial)))
|
(cosParallaxRays<0.9998 && mbInertial) || (cosParallaxRays<0.9998 && !mbInertial)))
|
||||||
{
|
{
|
||||||
// Linear Triangulation Method
|
// Linear Triangulation Method
|
||||||
// 见Initializer.cc的 Triangulate 函数,实现是一样的,顶多就是把投影矩阵换成了变换矩阵
|
cv::Matx14f A_r0 = xn1(0) * Tcw1.row(2) - Tcw1.row(0);
|
||||||
cv::Mat A(4,4,CV_32F);
|
cv::Matx14f A_r1 = xn1(1) * Tcw1.row(2) - Tcw1.row(1);
|
||||||
A.row(0) = xn1.at<float>(0)*Tcw1.row(2)-Tcw1.row(0);
|
cv::Matx14f A_r2 = xn2(0) * Tcw2.row(2) - Tcw2.row(0);
|
||||||
A.row(1) = xn1.at<float>(1)*Tcw1.row(2)-Tcw1.row(1);
|
cv::Matx14f A_r3 = xn2(1) * Tcw2.row(2) - Tcw2.row(1);
|
||||||
A.row(2) = xn2.at<float>(0)*Tcw2.row(2)-Tcw2.row(0);
|
cv::Matx44f A{A_r0(0), A_r0(1), A_r0(2), A_r0(3),
|
||||||
A.row(3) = xn2.at<float>(1)*Tcw2.row(2)-Tcw2.row(1);
|
A_r1(0), A_r1(1), A_r1(2), A_r1(3),
|
||||||
|
A_r2(0), A_r2(1), A_r2(2), A_r2(3),
|
||||||
|
A_r3(0), A_r3(1), A_r3(2), A_r3(3)};
|
||||||
|
|
||||||
cv::Mat w,u,vt;
|
cv::Matx44f u,vt;
|
||||||
|
cv::Matx41f w;
|
||||||
cv::SVD::compute(A,w,u,vt,cv::SVD::MODIFY_A| cv::SVD::FULL_UV);
|
cv::SVD::compute(A,w,u,vt,cv::SVD::MODIFY_A| cv::SVD::FULL_UV);
|
||||||
|
|
||||||
x3D = vt.row(3).t();
|
cv::Matx41f x3D_h = vt.row(3).t();
|
||||||
// 归一化之前的检查
|
|
||||||
if(x3D.at<float>(3)==0)
|
if(x3D_h(3)==0)
|
||||||
continue;
|
continue;
|
||||||
// 归一化成为齐次坐标,然后提取前面三个维度作为欧式坐标
|
// 归一化成为齐次坐标,然后提取前面三个维度作为欧式坐标
|
||||||
// Euclidean coordinates
|
// Euclidean coordinates
|
||||||
x3D = x3D.rowRange(0,3)/x3D.at<float>(3);
|
x3D = x3D_h.get_minor<3,1>(0,0) / x3D_h(3);
|
||||||
|
bEstimated = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(bStereo1 && cosParallaxStereo1<cosParallaxStereo2)
|
else if(bStereo1 && cosParallaxStereo1<cosParallaxStereo2)
|
||||||
{
|
{
|
||||||
// 如果是双目,用视差角更大的那个双目信息来恢复,直接用已知3D点反投影了
|
// 如果是双目,用视差角更大的那个双目信息来恢复,直接用已知3D点反投影了
|
||||||
x3D = mpCurrentKeyFrame->UnprojectStereo(idx1);
|
x3D = mpCurrentKeyFrame->UnprojectStereo_(idx1);
|
||||||
|
bEstimated = true;
|
||||||
}
|
}
|
||||||
else if(bStereo2 && cosParallaxStereo2<cosParallaxStereo1)
|
else if(bStereo2 && cosParallaxStereo2<cosParallaxStereo1)
|
||||||
{
|
{
|
||||||
x3D = pKF2->UnprojectStereo(idx2);
|
x3D = pKF2->UnprojectStereo_(idx2);
|
||||||
|
bEstimated = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
continue; //No stereo and very low parallax
|
continue; //No stereo and very low parallax
|
||||||
}
|
}
|
||||||
// 为方便后续计算,转换成为了行向量
|
// 为方便后续计算,转换成为了行向量
|
||||||
cv::Mat x3Dt = x3D.t();
|
cv::Matx13f x3Dt = x3D.t();
|
||||||
|
|
||||||
if(x3Dt.empty()) continue;
|
if(!bEstimated) continue;
|
||||||
//Check triangulation in front of cameras
|
//Check triangulation in front of cameras
|
||||||
// Step 6.5:检测生成的3D点是否在相机前方,不在的话就放弃这个点
|
// Step 6.5:检测生成的3D点是否在相机前方,不在的话就放弃这个点
|
||||||
float z1 = Rcw1.row(2).dot(x3Dt)+tcw1.at<float>(2);
|
float z1 = Rcw1.row(2).dot(x3Dt)+tcw1(2);
|
||||||
if(z1<=0)
|
if(z1<=0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
float z2 = Rcw2.row(2).dot(x3Dt)+tcw2.at<float>(2);
|
float z2 = Rcw2.row(2).dot(x3Dt)+tcw2(2);
|
||||||
if(z2<=0)
|
if(z2<=0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//Check reprojection error in first keyframe
|
//Check reprojection error in first keyframe
|
||||||
// Step 6.6:计算3D点在当前关键帧下的重投影误差
|
// Step 6.6:计算3D点在当前关键帧下的重投影误差
|
||||||
const float &sigmaSquare1 = mpCurrentKeyFrame->mvLevelSigma2[kp1.octave];
|
const float &sigmaSquare1 = mpCurrentKeyFrame->mvLevelSigma2[kp1.octave];
|
||||||
const float x1 = Rcw1.row(0).dot(x3Dt)+tcw1.at<float>(0);
|
const float x1 = Rcw1.row(0).dot(x3Dt)+tcw1(0);
|
||||||
const float y1 = Rcw1.row(1).dot(x3Dt)+tcw1.at<float>(1);
|
const float y1 = Rcw1.row(1).dot(x3Dt)+tcw1(1);
|
||||||
const float invz1 = 1.0/z1;
|
const float invz1 = 1.0/z1;
|
||||||
|
|
||||||
if(!bStereo1)
|
if(!bStereo1)
|
||||||
|
@ -799,8 +816,8 @@ void LocalMapping::CreateNewMapPoints()
|
||||||
//Check reprojection error in second keyframe
|
//Check reprojection error in second keyframe
|
||||||
// 计算3D点在另一个关键帧下的重投影误差,操作同上
|
// 计算3D点在另一个关键帧下的重投影误差,操作同上
|
||||||
const float sigmaSquare2 = pKF2->mvLevelSigma2[kp2.octave];
|
const float sigmaSquare2 = pKF2->mvLevelSigma2[kp2.octave];
|
||||||
const float x2 = Rcw2.row(0).dot(x3Dt)+tcw2.at<float>(0);
|
const float x2 = Rcw2.row(0).dot(x3Dt)+tcw2(0);
|
||||||
const float y2 = Rcw2.row(1).dot(x3Dt)+tcw2.at<float>(1);
|
const float y2 = Rcw2.row(1).dot(x3Dt)+tcw2(1);
|
||||||
const float invz2 = 1.0/z2;
|
const float invz2 = 1.0/z2;
|
||||||
if(!bStereo2)
|
if(!bStereo2)
|
||||||
{
|
{
|
||||||
|
@ -826,10 +843,10 @@ void LocalMapping::CreateNewMapPoints()
|
||||||
// Step 6.7:检查尺度连续性
|
// Step 6.7:检查尺度连续性
|
||||||
|
|
||||||
// 世界坐标系下,3D点与相机间的向量,方向由相机指向3D点
|
// 世界坐标系下,3D点与相机间的向量,方向由相机指向3D点
|
||||||
cv::Mat normal1 = x3D-Ow1;
|
auto normal1 = x3D-Ow1;
|
||||||
float dist1 = cv::norm(normal1);
|
float dist1 = cv::norm(normal1);
|
||||||
|
|
||||||
cv::Mat normal2 = x3D-Ow2;
|
auto normal2 = x3D-Ow2;
|
||||||
float dist2 = cv::norm(normal2);
|
float dist2 = cv::norm(normal2);
|
||||||
|
|
||||||
if(dist1==0 || dist2==0)
|
if(dist1==0 || dist2==0)
|
||||||
|
@ -848,7 +865,8 @@ void LocalMapping::CreateNewMapPoints()
|
||||||
|
|
||||||
// Triangulation is succesfull
|
// Triangulation is succesfull
|
||||||
// Step 6.8:三角化生成3D点成功,构造成MapPoint
|
// Step 6.8:三角化生成3D点成功,构造成MapPoint
|
||||||
MapPoint* pMP = new MapPoint(x3D,mpCurrentKeyFrame,mpAtlas->GetCurrentMap());
|
cv::Mat x3D_(x3D);
|
||||||
|
MapPoint* pMP = new MapPoint(x3D_,mpCurrentKeyFrame,mpAtlas->GetCurrentMap());
|
||||||
|
|
||||||
// Step 6.9:为该MapPoint添加属性:
|
// Step 6.9:为该MapPoint添加属性:
|
||||||
// a.观测到该MapPoint的关键帧
|
// a.观测到该MapPoint的关键帧
|
||||||
|
@ -1044,8 +1062,26 @@ cv::Mat LocalMapping::ComputeF12(KeyFrame *&pKF1, KeyFrame *&pKF2)
|
||||||
const cv::Mat &K1 = pKF1->mpCamera->toK();
|
const cv::Mat &K1 = pKF1->mpCamera->toK();
|
||||||
const cv::Mat &K2 = pKF2->mpCamera->toK();
|
const cv::Mat &K2 = pKF2->mpCamera->toK();
|
||||||
|
|
||||||
// Essential Matrix: t12叉乘R12
|
|
||||||
// Fundamental Matrix: inv(K1)*E*inv(K2)
|
return K1.t().inv()*t12x*R12*K2.inv();
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Matx33f LocalMapping::ComputeF12_(KeyFrame *&pKF1, KeyFrame *&pKF2)
|
||||||
|
{
|
||||||
|
auto R1w = pKF1->GetRotation_();
|
||||||
|
auto t1w = pKF1->GetTranslation_();
|
||||||
|
auto R2w = pKF2->GetRotation_();
|
||||||
|
auto t2w = pKF2->GetTranslation_();
|
||||||
|
|
||||||
|
auto R12 = R1w*R2w.t();
|
||||||
|
auto t12 = -R1w*R2w.t()*t2w+t1w;
|
||||||
|
|
||||||
|
auto t12x = SkewSymmetricMatrix_(t12);
|
||||||
|
|
||||||
|
const auto &K1 = pKF1->mpCamera->toK_();
|
||||||
|
const auto &K2 = pKF2->mpCamera->toK_();
|
||||||
|
|
||||||
|
|
||||||
return K1.t().inv()*t12x*R12*K2.inv();
|
return K1.t().inv()*t12x*R12*K2.inv();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1322,7 +1358,15 @@ cv::Mat LocalMapping::SkewSymmetricMatrix(const cv::Mat &v)
|
||||||
-v.at<float>(1), v.at<float>(0), 0);
|
-v.at<float>(1), v.at<float>(0), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 请求当前线程复位,由外部线程调用,堵塞的
|
cv::Matx33f LocalMapping::SkewSymmetricMatrix_(const cv::Matx31f &v)
|
||||||
|
{
|
||||||
|
cv::Matx33f skew{0.f, -v(2), v(1),
|
||||||
|
v(2), 0.f, -v(0),
|
||||||
|
-v(1), v(0), 0.f};
|
||||||
|
|
||||||
|
return skew;
|
||||||
|
}
|
||||||
|
|
||||||
void LocalMapping::RequestReset()
|
void LocalMapping::RequestReset()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
|
|
@ -73,7 +73,25 @@ void LoopClosing::Run()
|
||||||
mpLastCurrentKF->mvpLoopCandKFs.clear();
|
mpLastCurrentKF->mvpLoopCandKFs.clear();
|
||||||
mpLastCurrentKF->mvpMergeCandKFs.clear();
|
mpLastCurrentKF->mvpMergeCandKFs.clear();
|
||||||
}
|
}
|
||||||
if(NewDetectCommonRegions())
|
#ifdef REGISTER_TIMES
|
||||||
|
timeDetectBoW = 0;
|
||||||
|
std::chrono::steady_clock::time_point time_StartDetectBoW = std::chrono::steady_clock::now();
|
||||||
|
#endif
|
||||||
|
bool bDetected = NewDetectCommonRegions();
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_EndDetectBoW = std::chrono::steady_clock::now();
|
||||||
|
double timeDetect = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndDetectBoW - time_StartDetectBoW).count();
|
||||||
|
double timeDetectSE3 = timeDetect - timeDetectBoW;
|
||||||
|
|
||||||
|
if(timeDetectBoW > 0)
|
||||||
|
{
|
||||||
|
vTimeBoW_ms.push_back(timeDetectBoW);
|
||||||
|
}
|
||||||
|
vTimeSE3_ms.push_back(timeDetectSE3);
|
||||||
|
vTimePRTotal_ms.push_back(timeDetect);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(bDetected)
|
||||||
{
|
{
|
||||||
if(mbMergeDetected)
|
if(mbMergeDetected)
|
||||||
{
|
{
|
||||||
|
@ -119,21 +137,22 @@ void LoopClosing::Run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// cout << "tw2w1: " << mSold_new.translation() << endl;
|
|
||||||
// cout << "Rw2w1: " << mSold_new.rotation().toRotationMatrix() << endl;
|
|
||||||
// cout << "Angle Rw2w1: " << 180*LogSO3(mSold_new.rotation().toRotationMatrix())/3.14 << endl;
|
|
||||||
// cout << "scale w2w1: " << mSold_new.scale() << endl;
|
|
||||||
|
|
||||||
mg2oMergeSmw = gSmw2 * gSw2c * gScw1;
|
mg2oMergeSmw = gSmw2 * gSw2c * gScw1;
|
||||||
|
|
||||||
mg2oMergeScw = mg2oMergeSlw;
|
mg2oMergeScw = mg2oMergeSlw;
|
||||||
|
|
||||||
// TODO UNCOMMENT
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_StartMerge = std::chrono::steady_clock::now();
|
||||||
|
#endif
|
||||||
if (mpTracker->mSensor==System::IMU_MONOCULAR ||mpTracker->mSensor==System::IMU_STEREO)
|
if (mpTracker->mSensor==System::IMU_MONOCULAR ||mpTracker->mSensor==System::IMU_STEREO)
|
||||||
MergeLocal2();
|
MergeLocal2();
|
||||||
else
|
else
|
||||||
MergeLocal();
|
MergeLocal();
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_EndMerge = std::chrono::steady_clock::now();
|
||||||
|
double timeMerge = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndMerge - time_StartMerge).count();
|
||||||
|
vTimeMergeTotal_ms.push_back(timeMerge);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
vdPR_CurrentTime.push_back(mpCurrentKF->mTimeStamp);
|
vdPR_CurrentTime.push_back(mpCurrentKF->mTimeStamp);
|
||||||
|
@ -201,7 +220,16 @@ void LoopClosing::Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
mvpLoopMapPoints = mvpLoopMPs;//*mvvpLoopMapPoints[nCurrentIndex];
|
mvpLoopMapPoints = mvpLoopMPs;//*mvvpLoopMapPoints[nCurrentIndex];
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_StartLoop = std::chrono::steady_clock::now();
|
||||||
|
#endif
|
||||||
CorrectLoop();
|
CorrectLoop();
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_EndLoop = std::chrono::steady_clock::now();
|
||||||
|
double timeLoop = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndLoop - time_StartLoop).count();
|
||||||
|
vTimeLoopTotal_ms.push_back(timeLoop);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -211,7 +239,16 @@ void LoopClosing::Run()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mvpLoopMapPoints = mvpLoopMPs;
|
mvpLoopMapPoints = mvpLoopMPs;
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_StartLoop = std::chrono::steady_clock::now();
|
||||||
|
#endif
|
||||||
CorrectLoop();
|
CorrectLoop();
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_EndLoop = std::chrono::steady_clock::now();
|
||||||
|
double timeLoop = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndLoop - time_StartLoop).count();
|
||||||
|
vTimeLoopTotal_ms.push_back(timeLoop);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset all variables
|
// Reset all variables
|
||||||
|
@ -475,8 +512,15 @@ bool LoopClosing::NewDetectCommonRegions()
|
||||||
//cout << "LC: bMergeDetectedInKF: " << bMergeDetectedInKF << " bLoopDetectedInKF: " << bLoopDetectedInKF << endl;
|
//cout << "LC: bMergeDetectedInKF: " << bMergeDetectedInKF << " bLoopDetectedInKF: " << bLoopDetectedInKF << endl;
|
||||||
if(!bMergeDetectedInKF || !bLoopDetectedInKF)
|
if(!bMergeDetectedInKF || !bLoopDetectedInKF)
|
||||||
{
|
{
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_StartDetectBoW = std::chrono::steady_clock::now();
|
||||||
|
#endif
|
||||||
// Search in BoW
|
// Search in BoW
|
||||||
mpKeyFrameDB->DetectNBestCandidates(mpCurrentKF, vpLoopBowCand, vpMergeBowCand,3);
|
mpKeyFrameDB->DetectNBestCandidates(mpCurrentKF, vpLoopBowCand, vpMergeBowCand,3);
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_EndDetectBoW = std::chrono::steady_clock::now();
|
||||||
|
timeDetectBoW = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndDetectBoW - time_StartDetectBoW).count();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the BoW candidates if the geometric candidate list is empty
|
// Check the BoW candidates if the geometric candidate list is empty
|
||||||
|
@ -520,7 +564,6 @@ bool LoopClosing::DetectAndReffineSim3FromLastKF(KeyFrame* pCurrentKF, KeyFrame*
|
||||||
{
|
{
|
||||||
set<MapPoint*> spAlreadyMatchedMPs;
|
set<MapPoint*> spAlreadyMatchedMPs;
|
||||||
nNumProjMatches = FindMatchesByProjection(pCurrentKF, pMatchedKF, gScw, spAlreadyMatchedMPs, vpMPs, vpMatchedMPs);
|
nNumProjMatches = FindMatchesByProjection(pCurrentKF, pMatchedKF, gScw, spAlreadyMatchedMPs, vpMPs, vpMatchedMPs);
|
||||||
cout << "REFFINE-SIM3: Projection from last KF with " << nNumProjMatches << " matches" << endl;
|
|
||||||
|
|
||||||
|
|
||||||
int nProjMatches = 30;
|
int nProjMatches = 30;
|
||||||
|
@ -546,7 +589,6 @@ bool LoopClosing::DetectAndReffineSim3FromLastKF(KeyFrame* pCurrentKF, KeyFrame*
|
||||||
if(mpTracker->mSensor==System::IMU_MONOCULAR && !pCurrentKF->GetMap()->GetIniertialBA2())
|
if(mpTracker->mSensor==System::IMU_MONOCULAR && !pCurrentKF->GetMap()->GetIniertialBA2())
|
||||||
bFixedScale=false;
|
bFixedScale=false;
|
||||||
int numOptMatches = Optimizer::OptimizeSim3(mpCurrentKF, pMatchedKF, vpMatchedMPs, gScm, 10, bFixedScale, mHessian7x7, true);
|
int numOptMatches = Optimizer::OptimizeSim3(mpCurrentKF, pMatchedKF, vpMatchedMPs, gScm, 10, bFixedScale, mHessian7x7, true);
|
||||||
cout << "REFFINE-SIM3: Optimize Sim3 from last KF with " << numOptMatches << " inliers" << endl;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -744,7 +786,6 @@ bool LoopClosing::DetectCommonRegionsFromBoW(std::vector<KeyFrame*> &vpBowCand,
|
||||||
vector<KeyFrame*> vpMatchedKF;
|
vector<KeyFrame*> vpMatchedKF;
|
||||||
vpMatchedKF.resize(mpCurrentKF->GetMapPointMatches().size(), static_cast<KeyFrame*>(NULL));
|
vpMatchedKF.resize(mpCurrentKF->GetMapPointMatches().size(), static_cast<KeyFrame*>(NULL));
|
||||||
int numProjMatches = matcher.SearchByProjection(mpCurrentKF, mScw, vpMapPoints, vpKeyFrames, vpMatchedMP, vpMatchedKF, 8, 1.5);
|
int numProjMatches = matcher.SearchByProjection(mpCurrentKF, mScw, vpMapPoints, vpKeyFrames, vpMatchedMP, vpMatchedKF, 8, 1.5);
|
||||||
cout <<"BoW: " << numProjMatches << " matches between " << vpMapPoints.size() << " points with coarse Sim3" << endl;
|
|
||||||
|
|
||||||
if(numProjMatches >= nProjMatches)
|
if(numProjMatches >= nProjMatches)
|
||||||
{
|
{
|
||||||
|
@ -773,44 +814,6 @@ bool LoopClosing::DetectCommonRegionsFromBoW(std::vector<KeyFrame*> &vpBowCand,
|
||||||
|
|
||||||
if(numProjOptMatches >= nProjOptMatches)
|
if(numProjOptMatches >= nProjOptMatches)
|
||||||
{
|
{
|
||||||
cout << "BoW: Current KF " << mpCurrentKF->mnId << "; candidate KF " << pKFi->mnId << endl;
|
|
||||||
cout << "BoW: There are " << numProjOptMatches << " matches between them with the optimized Sim3" << endl;
|
|
||||||
int max_x = -1, min_x = 1000000;
|
|
||||||
int max_y = -1, min_y = 1000000;
|
|
||||||
for(MapPoint* pMPi : vpMatchedMP)
|
|
||||||
{
|
|
||||||
if(!pMPi || pMPi->isBad())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
tuple<size_t,size_t> indexes = pMPi->GetIndexInKeyFrame(pKFi);
|
|
||||||
int index = get<0>(indexes);
|
|
||||||
if(index >= 0)
|
|
||||||
{
|
|
||||||
int coord_x = pKFi->mvKeysUn[index].pt.x;
|
|
||||||
if(coord_x < min_x)
|
|
||||||
{
|
|
||||||
min_x = coord_x;
|
|
||||||
}
|
|
||||||
if(coord_x > max_x)
|
|
||||||
{
|
|
||||||
max_x = coord_x;
|
|
||||||
}
|
|
||||||
int coord_y = pKFi->mvKeysUn[index].pt.y;
|
|
||||||
if(coord_y < min_y)
|
|
||||||
{
|
|
||||||
min_y = coord_y;
|
|
||||||
}
|
|
||||||
if(coord_y > max_y)
|
|
||||||
{
|
|
||||||
max_y = coord_y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//cout << "BoW: Coord in X -> " << min_x << ", " << max_x << "; and Y -> " << min_y << ", " << max_y << endl;
|
|
||||||
//cout << "BoW: features area in X -> " << (max_x - min_x) << " and Y -> " << (max_y - min_y) << endl;
|
|
||||||
|
|
||||||
int nNumKFs = 0;
|
int nNumKFs = 0;
|
||||||
//vpMatchedMPs = vpMatchedMP;
|
//vpMatchedMPs = vpMatchedMP;
|
||||||
//vpMPs = vpMapPoints;
|
//vpMPs = vpMapPoints;
|
||||||
|
@ -832,27 +835,7 @@ bool LoopClosing::DetectCommonRegionsFromBoW(std::vector<KeyFrame*> &vpBowCand,
|
||||||
|
|
||||||
if(bValid)
|
if(bValid)
|
||||||
{
|
{
|
||||||
//cout << "BoW: KF " << pKFj->mnId << " has " << numProjMatches_j << " matches" << endl;
|
|
||||||
cv::Mat Tc_w = mpCurrentKF->GetPose();
|
|
||||||
cv::Mat Tw_cj = pKFj->GetPoseInverse();
|
|
||||||
cv::Mat Tc_cj = Tc_w * Tw_cj;
|
|
||||||
cv::Vec3d vector_dist = Tc_cj.rowRange(0, 3).col(3);
|
|
||||||
cv::Mat Rc_cj = Tc_cj.rowRange(0, 3).colRange(0, 3);
|
|
||||||
double dist = cv::norm(vector_dist);
|
|
||||||
cout << "BoW: KF " << pKFi->mnId << " to KF " << pKFj->mnId << " is separated by " << dist << " meters" << endl;
|
|
||||||
cout << "BoW: Rotation between KF -> " << Rc_cj << endl;
|
|
||||||
vector<float> v_euler = Converter::toEuler(Rc_cj);
|
|
||||||
v_euler[0] *= 180 /3.1415;
|
|
||||||
v_euler[1] *= 180 /3.1415;
|
|
||||||
v_euler[2] *= 180 /3.1415;
|
|
||||||
cout << "BoW: Rotation in angles (x, y, z) -> (" << v_euler[0] << ", " << v_euler[1] << ", " << v_euler[2] << ")" << endl;
|
|
||||||
nNumKFs++;
|
nNumKFs++;
|
||||||
/*if(numProjMatches_j > numProjOptMatches)
|
|
||||||
{
|
|
||||||
pLastCurrentKF = pKFj;
|
|
||||||
g2oScw = gSjw;
|
|
||||||
vpMatchedMPs = vpMatchedMPs_j;
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
j++;
|
j++;
|
||||||
|
@ -1067,9 +1050,7 @@ void LoopClosing::CorrectLoop()
|
||||||
// Step 1:根据共视关系更新当前关键帧与其它关键帧之间的连接关系
|
// Step 1:根据共视关系更新当前关键帧与其它关键帧之间的连接关系
|
||||||
// 因为之前闭环检测、计算Sim3中改变了该关键帧的地图点,所以需要更新
|
// 因为之前闭环检测、计算Sim3中改变了该关键帧的地图点,所以需要更新
|
||||||
cout << "start updating connections" << endl;
|
cout << "start updating connections" << endl;
|
||||||
assert(mpCurrentKF->GetMap()->CheckEssentialGraph());
|
|
||||||
mpCurrentKF->UpdateConnections();
|
mpCurrentKF->UpdateConnections();
|
||||||
assert(mpCurrentKF->GetMap()->CheckEssentialGraph());
|
|
||||||
|
|
||||||
// Retrive keyframes connected to the current keyframe and compute corrected Sim3 pose by propagation
|
// Retrive keyframes connected to the current keyframe and compute corrected Sim3 pose by propagation
|
||||||
// Step 2:通过位姿传播,得到Sim3优化后,与当前帧相连的关键帧的位姿,以及它们的地图点
|
// Step 2:通过位姿传播,得到Sim3优化后,与当前帧相连的关键帧的位姿,以及它们的地图点
|
||||||
|
@ -1129,8 +1110,6 @@ void LoopClosing::CorrectLoop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Correct all MapPoints obsrved by current keyframe and neighbors, so that they align with the other side of the loop
|
// Correct all MapPoints obsrved by current keyframe and neighbors, so that they align with the other side of the loop
|
||||||
cout << "LC: start correcting KeyFrames" << endl;
|
|
||||||
cout << "LC: there are " << CorrectedSim3.size() << " KFs in the local window" << endl;
|
|
||||||
// Step 2.2:得到矫正的当前关键帧的共视关键帧位姿后,修正这些关键帧的地图点
|
// Step 2.2:得到矫正的当前关键帧的共视关键帧位姿后,修正这些关键帧的地图点
|
||||||
// 遍历待矫正的共视关键帧(不包括当前关键帧)
|
// 遍历待矫正的共视关键帧(不包括当前关键帧)
|
||||||
for(KeyFrameAndPose::iterator mit=CorrectedSim3.begin(), mend=CorrectedSim3.end(); mit!=mend; mit++)
|
for(KeyFrameAndPose::iterator mit=CorrectedSim3.begin(), mend=CorrectedSim3.end(); mit!=mend; mit++)
|
||||||
|
@ -1201,13 +1180,11 @@ void LoopClosing::CorrectLoop()
|
||||||
pKFi->UpdateConnections();
|
pKFi->UpdateConnections();
|
||||||
}
|
}
|
||||||
// TODO Check this index increasement
|
// TODO Check this index increasement
|
||||||
mpAtlas->GetCurrentMap()->IncreaseChangeIndex();
|
pLoopMap->IncreaseChangeIndex();
|
||||||
cout << "LC: end correcting KeyFrames" << endl;
|
|
||||||
|
|
||||||
|
|
||||||
// Start Loop Fusion
|
// Start Loop Fusion
|
||||||
// Update matched map points and replace if duplicated
|
// Update matched map points and replace if duplicated
|
||||||
cout << "LC: start replacing duplicated" << endl;
|
|
||||||
// Step 3:检查当前帧的地图点与经过闭环匹配后该帧的地图点是否存在冲突,对冲突的进行替换或填补
|
// Step 3:检查当前帧的地图点与经过闭环匹配后该帧的地图点是否存在冲突,对冲突的进行替换或填补
|
||||||
// mvpCurrentMatchedPoints 是当前关键帧和闭环关键帧组的所有地图点进行投影得到的匹配点
|
// mvpCurrentMatchedPoints 是当前关键帧和闭环关键帧组的所有地图点进行投影得到的匹配点
|
||||||
for(size_t i=0; i<mvpLoopMatchedMPs.size(); i++)
|
for(size_t i=0; i<mvpLoopMatchedMPs.size(); i++)
|
||||||
|
@ -1232,7 +1209,6 @@ void LoopClosing::CorrectLoop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cout << "LC: end replacing duplicated" << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Project MapPoints observed in the neighborhood of the loop keyframe
|
// Project MapPoints observed in the neighborhood of the loop keyframe
|
||||||
|
@ -1330,8 +1306,7 @@ void LoopClosing::CorrectLoop()
|
||||||
|
|
||||||
void LoopClosing::MergeLocal()
|
void LoopClosing::MergeLocal()
|
||||||
{
|
{
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Merge Visual detected!!!!", Verbose::VERBOSITY_NORMAL);
|
Verbose::PrintMess("MERGE: Merge Visual detected!!!!", Verbose::VERBOSITY_NORMAL);
|
||||||
//mpTracker->SetStepByStep(true);
|
|
||||||
|
|
||||||
int numTemporalKFs = 15; //TODO (set by parameter): Temporal KFs in the local window if the map is inertial.
|
int numTemporalKFs = 15; //TODO (set by parameter): Temporal KFs in the local window if the map is inertial.
|
||||||
|
|
||||||
|
@ -1345,7 +1320,7 @@ void LoopClosing::MergeLocal()
|
||||||
// Flag that is true only when we stopped a running BA, in this case we need relaunch at the end of the merge
|
// Flag that is true only when we stopped a running BA, in this case we need relaunch at the end of the merge
|
||||||
bool bRelaunchBA = false;
|
bool bRelaunchBA = false;
|
||||||
|
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Check Full Bundle Adjustment", Verbose::VERBOSITY_DEBUG);
|
Verbose::PrintMess("MERGE: Check Full Bundle Adjustment", Verbose::VERBOSITY_DEBUG);
|
||||||
// If a Global Bundle Adjustment is running, abort it
|
// If a Global Bundle Adjustment is running, abort it
|
||||||
if(isRunningGBA())
|
if(isRunningGBA())
|
||||||
{
|
{
|
||||||
|
@ -1362,14 +1337,14 @@ void LoopClosing::MergeLocal()
|
||||||
bRelaunchBA = true;
|
bRelaunchBA = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Request Stop Local Mapping", Verbose::VERBOSITY_DEBUG);
|
Verbose::PrintMess("MERGE: Request Stop Local Mapping", Verbose::VERBOSITY_DEBUG);
|
||||||
mpLocalMapper->RequestStop();
|
mpLocalMapper->RequestStop();
|
||||||
// Wait until Local Mapping has effectively stopped
|
// Wait until Local Mapping has effectively stopped
|
||||||
while(!mpLocalMapper->isStopped())
|
while(!mpLocalMapper->isStopped())
|
||||||
{
|
{
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
}
|
}
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Local Map stopped", Verbose::VERBOSITY_DEBUG);
|
Verbose::PrintMess("MERGE: Local Map stopped", Verbose::VERBOSITY_DEBUG);
|
||||||
|
|
||||||
mpLocalMapper->EmptyQueue();
|
mpLocalMapper->EmptyQueue();
|
||||||
|
|
||||||
|
@ -1378,12 +1353,6 @@ void LoopClosing::MergeLocal()
|
||||||
Map* pCurrentMap = mpCurrentKF->GetMap();
|
Map* pCurrentMap = mpCurrentKF->GetMap();
|
||||||
Map* pMergeMap = mpMergeMatchedKF->GetMap();
|
Map* pMergeMap = mpMergeMatchedKF->GetMap();
|
||||||
|
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Initially there are " + to_string(pCurrentMap->KeyFramesInMap()) + " KFs and " + to_string(pCurrentMap->MapPointsInMap()) + " MPs in the active map ", Verbose::VERBOSITY_DEBUG);
|
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Initially there are " + to_string(pMergeMap->KeyFramesInMap()) + " KFs and " + to_string(pMergeMap->MapPointsInMap()) + " MPs in the matched map ", Verbose::VERBOSITY_DEBUG);
|
|
||||||
//vector<KeyFrame*> vpMergeKFs = pMergeMap->GetAllKeyFrames();
|
|
||||||
|
|
||||||
////
|
|
||||||
|
|
||||||
// Ensure current keyframe is updated
|
// Ensure current keyframe is updated
|
||||||
mpCurrentKF->UpdateConnections();
|
mpCurrentKF->UpdateConnections();
|
||||||
|
|
||||||
|
@ -1421,7 +1390,6 @@ void LoopClosing::MergeLocal()
|
||||||
|
|
||||||
vector<KeyFrame*> vpCovisibleKFs = mpCurrentKF->GetBestCovisibilityKeyFrames(numTemporalKFs);
|
vector<KeyFrame*> vpCovisibleKFs = mpCurrentKF->GetBestCovisibilityKeyFrames(numTemporalKFs);
|
||||||
spLocalWindowKFs.insert(vpCovisibleKFs.begin(), vpCovisibleKFs.end());
|
spLocalWindowKFs.insert(vpCovisibleKFs.begin(), vpCovisibleKFs.end());
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Initial number of KFs in local window from active map: " + to_string(spLocalWindowKFs.size()), Verbose::VERBOSITY_DEBUG);
|
|
||||||
const int nMaxTries = 3;
|
const int nMaxTries = 3;
|
||||||
int nNumTries = 0;
|
int nNumTries = 0;
|
||||||
while(spLocalWindowKFs.size() < numTemporalKFs && nNumTries < nMaxTries)
|
while(spLocalWindowKFs.size() < numTemporalKFs && nNumTries < nMaxTries)
|
||||||
|
@ -1444,11 +1412,6 @@ void LoopClosing::MergeLocal()
|
||||||
spLocalWindowKFs.insert(vpNewCovKFs.begin(), vpNewCovKFs.end());
|
spLocalWindowKFs.insert(vpNewCovKFs.begin(), vpNewCovKFs.end());
|
||||||
nNumTries++;
|
nNumTries++;
|
||||||
}
|
}
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Last number of KFs in local window from the active map: " + to_string(spLocalWindowKFs.size()), Verbose::VERBOSITY_DEBUG);
|
|
||||||
|
|
||||||
//TODO TEST
|
|
||||||
//vector<KeyFrame*> vpTestKFs = pCurrentMap->GetAllKeyFrames();
|
|
||||||
//spLocalWindowKFs.insert(vpTestKFs.begin(), vpTestKFs.end());
|
|
||||||
|
|
||||||
for(KeyFrame* pKFi : spLocalWindowKFs)
|
for(KeyFrame* pKFi : spLocalWindowKFs)
|
||||||
{
|
{
|
||||||
|
@ -1458,10 +1421,7 @@ void LoopClosing::MergeLocal()
|
||||||
set<MapPoint*> spMPs = pKFi->GetMapPoints();
|
set<MapPoint*> spMPs = pKFi->GetMapPoints();
|
||||||
spLocalWindowMPs.insert(spMPs.begin(), spMPs.end());
|
spLocalWindowMPs.insert(spMPs.begin(), spMPs.end());
|
||||||
}
|
}
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Number of MPs in local window from active map: " + to_string(spLocalWindowMPs.size()), Verbose::VERBOSITY_DEBUG);
|
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Number of MPs in the active map: " + to_string(pCurrentMap->GetAllMapPoints().size()), Verbose::VERBOSITY_DEBUG);
|
|
||||||
|
|
||||||
Verbose::PrintMess("-------", Verbose::VERBOSITY_DEBUG);
|
|
||||||
set<KeyFrame*> spMergeConnectedKFs;
|
set<KeyFrame*> spMergeConnectedKFs;
|
||||||
if(pCurrentMap->IsInertial() && pMergeMap->IsInertial()) //TODO Check the correct initialization
|
if(pCurrentMap->IsInertial() && pMergeMap->IsInertial()) //TODO Check the correct initialization
|
||||||
{
|
{
|
||||||
|
@ -1486,7 +1446,6 @@ void LoopClosing::MergeLocal()
|
||||||
}
|
}
|
||||||
vpCovisibleKFs = mpMergeMatchedKF->GetBestCovisibilityKeyFrames(numTemporalKFs);
|
vpCovisibleKFs = mpMergeMatchedKF->GetBestCovisibilityKeyFrames(numTemporalKFs);
|
||||||
spMergeConnectedKFs.insert(vpCovisibleKFs.begin(), vpCovisibleKFs.end());
|
spMergeConnectedKFs.insert(vpCovisibleKFs.begin(), vpCovisibleKFs.end());
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Initial number of KFs in the local window from matched map: " + to_string(spMergeConnectedKFs.size()), Verbose::VERBOSITY_DEBUG);
|
|
||||||
nNumTries = 0;
|
nNumTries = 0;
|
||||||
while(spMergeConnectedKFs.size() < numTemporalKFs && nNumTries < nMaxTries)
|
while(spMergeConnectedKFs.size() < numTemporalKFs && nNumTries < nMaxTries)
|
||||||
{
|
{
|
||||||
|
@ -1507,7 +1466,6 @@ void LoopClosing::MergeLocal()
|
||||||
spMergeConnectedKFs.insert(vpNewCovKFs.begin(), vpNewCovKFs.end());
|
spMergeConnectedKFs.insert(vpNewCovKFs.begin(), vpNewCovKFs.end());
|
||||||
nNumTries++;
|
nNumTries++;
|
||||||
}
|
}
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Last number of KFs in the localwindow from matched map: " + to_string(spMergeConnectedKFs.size()), Verbose::VERBOSITY_DEBUG);
|
|
||||||
|
|
||||||
set<MapPoint*> spMapPointMerge;
|
set<MapPoint*> spMapPointMerge;
|
||||||
for(KeyFrame* pKFi : spMergeConnectedKFs)
|
for(KeyFrame* pKFi : spMergeConnectedKFs)
|
||||||
|
@ -1533,24 +1491,13 @@ void LoopClosing::MergeLocal()
|
||||||
vCorrectedSim3[mpCurrentKF]=g2oCorrectedScw;
|
vCorrectedSim3[mpCurrentKF]=g2oCorrectedScw;
|
||||||
vNonCorrectedSim3[mpCurrentKF]=g2oNonCorrectedScw;
|
vNonCorrectedSim3[mpCurrentKF]=g2oNonCorrectedScw;
|
||||||
|
|
||||||
|
|
||||||
//TODO Time test
|
|
||||||
#ifdef COMPILEDWITHC11
|
|
||||||
std::chrono::steady_clock::time_point timeStartTransfMerge = std::chrono::steady_clock::now();
|
|
||||||
#else
|
|
||||||
std::chrono::monotonic_clock::time_point timeStartTransfMerge = std::chrono::monotonic_clock::now();
|
|
||||||
#endif
|
|
||||||
for(KeyFrame* pKFi : spLocalWindowKFs)
|
for(KeyFrame* pKFi : spLocalWindowKFs)
|
||||||
{
|
{
|
||||||
if(!pKFi || pKFi->isBad())
|
if(!pKFi || pKFi->isBad())
|
||||||
{
|
{
|
||||||
Verbose::PrintMess("Bad KF in correction", Verbose::VERBOSITY_DEBUG);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pKFi->GetMap() != pCurrentMap)
|
|
||||||
Verbose::PrintMess("Other map KF, this should't happen", Verbose::VERBOSITY_DEBUG);
|
|
||||||
|
|
||||||
g2o::Sim3 g2oCorrectedSiw;
|
g2o::Sim3 g2oCorrectedSiw;
|
||||||
|
|
||||||
if(pKFi!=mpCurrentKF)
|
if(pKFi!=mpCurrentKF)
|
||||||
|
@ -1583,32 +1530,16 @@ void LoopClosing::MergeLocal()
|
||||||
pKFi->mfScale = s;
|
pKFi->mfScale = s;
|
||||||
eigt *=(1./s); //[R t/s;0 1]
|
eigt *=(1./s); //[R t/s;0 1]
|
||||||
|
|
||||||
//cout << "R: " << mg2oMergeScw.rotation().toRotationMatrix() << endl;
|
|
||||||
//cout << "angle: " << 180*LogSO3(mg2oMergeScw.rotation().toRotationMatrix())/3.14 << endl;
|
|
||||||
//cout << "t: " << mg2oMergeScw.translation() << endl;
|
|
||||||
|
|
||||||
cv::Mat correctedTiw = Converter::toCvSE3(eigR,eigt);
|
cv::Mat correctedTiw = Converter::toCvSE3(eigR,eigt);
|
||||||
|
|
||||||
pKFi->mTcwMerge = correctedTiw;
|
pKFi->mTcwMerge = correctedTiw;
|
||||||
|
|
||||||
//pKFi->SetPose(correctedTiw);
|
|
||||||
|
|
||||||
// Make sure connections are updated
|
|
||||||
//pKFi->UpdateMap(pMergeMap);
|
|
||||||
//pMergeMap->AddKeyFrame(pKFi);
|
|
||||||
//pCurrentMap->EraseKeyFrame(pKFi);
|
|
||||||
|
|
||||||
//cout << "After -> Map current: " << pCurrentMap << "; New map: " << pKFi->GetMap() << endl;
|
|
||||||
|
|
||||||
if(pCurrentMap->isImuInitialized())
|
if(pCurrentMap->isImuInitialized())
|
||||||
{
|
{
|
||||||
Eigen::Matrix3d Rcor = eigR.transpose()*vNonCorrectedSim3[pKFi].rotation().toRotationMatrix();
|
Eigen::Matrix3d Rcor = eigR.transpose()*vNonCorrectedSim3[pKFi].rotation().toRotationMatrix();
|
||||||
pKFi->mVwbMerge = Converter::toCvMat(Rcor)*pKFi->GetVelocity();
|
pKFi->mVwbMerge = Converter::toCvMat(Rcor)*pKFi->GetVelocity();
|
||||||
//pKFi->SetVelocity(Converter::toCvMat(Rcor)*pKFi->GetVelocity()); // TODO: should add here scale s
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO DEBUG to know which are the KFs that had been moved to the other map
|
|
||||||
//pKFi->mnOriginMapId = 5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(MapPoint* pMPi : spLocalWindowMPs)
|
for(MapPoint* pMPi : spLocalWindowMPs)
|
||||||
|
@ -1630,30 +1561,9 @@ void LoopClosing::MergeLocal()
|
||||||
cv::Mat cvCorrectedP3Dw = Converter::toCvMat(eigCorrectedP3Dw);
|
cv::Mat cvCorrectedP3Dw = Converter::toCvMat(eigCorrectedP3Dw);
|
||||||
|
|
||||||
pMPi->mPosMerge = cvCorrectedP3Dw;
|
pMPi->mPosMerge = cvCorrectedP3Dw;
|
||||||
//cout << "Rcor: " << Rcor << endl;
|
|
||||||
//cout << "Normal: " << pMPi->GetNormal() << endl;
|
|
||||||
pMPi->mNormalVectorMerge = Converter::toCvMat(Rcor) * pMPi->GetNormal();
|
pMPi->mNormalVectorMerge = Converter::toCvMat(Rcor) * pMPi->GetNormal();
|
||||||
//pMPi->SetWorldPos(cvCorrectedP3Dw);
|
|
||||||
//pMPi->UpdateMap(pMergeMap);
|
|
||||||
//pMergeMap->AddMapPoint(pMPi);
|
|
||||||
//pCurrentMap->EraseMapPoint(pMPi);
|
|
||||||
//pMPi->UpdateNormalAndDepth();
|
|
||||||
}
|
}
|
||||||
#ifdef COMPILEDWITHC11
|
|
||||||
std::chrono::steady_clock::time_point timeFinishTransfMerge = std::chrono::steady_clock::now();
|
|
||||||
#else
|
|
||||||
std::chrono::monotonic_clock::time_point timeFinishTransfMerge = std::chrono::monotonic_clock::now();
|
|
||||||
#endif
|
|
||||||
std::chrono::duration<double,std::milli> timeTransfMerge = timeFinishTransfMerge - timeStartTransfMerge; // Time in milliseconds
|
|
||||||
Verbose::PrintMess("MERGE-VISUAL: TRANSF ms: " + to_string(timeTransfMerge.count()), Verbose::VERBOSITY_DEBUG);
|
|
||||||
|
|
||||||
|
|
||||||
//TODO Time test
|
|
||||||
#ifdef COMPILEDWITHC11
|
|
||||||
std::chrono::steady_clock::time_point timeStartCritMerge = std::chrono::steady_clock::now();
|
|
||||||
#else
|
|
||||||
std::chrono::monotonic_clock::time_point timeStartCritMerge = std::chrono::monotonic_clock::now();
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
unique_lock<mutex> currentLock(pCurrentMap->mMutexMapUpdate); // We update the current map with the Merge information
|
unique_lock<mutex> currentLock(pCurrentMap->mMutexMapUpdate); // We update the current map with the Merge information
|
||||||
unique_lock<mutex> mergeLock(pMergeMap->mMutexMapUpdate); // We remove the Kfs and MPs in the merged area from the old map
|
unique_lock<mutex> mergeLock(pMergeMap->mMutexMapUpdate); // We remove the Kfs and MPs in the merged area from the old map
|
||||||
|
@ -1692,25 +1602,13 @@ void LoopClosing::MergeLocal()
|
||||||
pMPi->UpdateMap(pMergeMap);
|
pMPi->UpdateMap(pMergeMap);
|
||||||
pMergeMap->AddMapPoint(pMPi);
|
pMergeMap->AddMapPoint(pMPi);
|
||||||
pCurrentMap->EraseMapPoint(pMPi);
|
pCurrentMap->EraseMapPoint(pMPi);
|
||||||
//pMPi->UpdateNormalAndDepth();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mpAtlas->ChangeMap(pMergeMap);
|
mpAtlas->ChangeMap(pMergeMap);
|
||||||
mpAtlas->SetMapBad(pCurrentMap);
|
mpAtlas->SetMapBad(pCurrentMap);
|
||||||
pMergeMap->IncreaseChangeIndex();
|
pMergeMap->IncreaseChangeIndex();
|
||||||
//TODO for debug
|
|
||||||
pMergeMap->ChangeId(pCurrentMap->GetId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef COMPILEDWITHC11
|
|
||||||
std::chrono::steady_clock::time_point timeFinishCritMerge = std::chrono::steady_clock::now();
|
|
||||||
#else
|
|
||||||
std::chrono::monotonic_clock::time_point timeFinishCritMerge = std::chrono::monotonic_clock::now();
|
|
||||||
#endif
|
|
||||||
std::chrono::duration<double,std::milli> timeCritMerge = timeFinishCritMerge - timeStartCritMerge; // Time in milliseconds
|
|
||||||
Verbose::PrintMess("MERGE-VISUAL: New current map: " + to_string(pMergeMap->GetId()), Verbose::VERBOSITY_DEBUG);
|
|
||||||
Verbose::PrintMess("MERGE-VISUAL: CRITICAL ms: " + to_string(timeCritMerge.count()), Verbose::VERBOSITY_DEBUG);
|
|
||||||
Verbose::PrintMess("MERGE-VISUAL: LOCAL MAPPING number of KFs: " + to_string(mpLocalMapper->KeyframesInQueue()), Verbose::VERBOSITY_DEBUG);
|
|
||||||
|
|
||||||
//Rebuild the essential graph in the local window
|
//Rebuild the essential graph in the local window
|
||||||
pCurrentMap->GetOriginKF()->SetFirstConnection(false);
|
pCurrentMap->GetOriginKF()->SetFirstConnection(false);
|
||||||
|
@ -1741,29 +1639,12 @@ void LoopClosing::MergeLocal()
|
||||||
vpCheckFuseMapPoint.reserve(spMapPointMerge.size());
|
vpCheckFuseMapPoint.reserve(spMapPointMerge.size());
|
||||||
std::copy(spMapPointMerge.begin(), spMapPointMerge.end(), std::back_inserter(vpCheckFuseMapPoint));
|
std::copy(spMapPointMerge.begin(), spMapPointMerge.end(), std::back_inserter(vpCheckFuseMapPoint));
|
||||||
|
|
||||||
|
|
||||||
//TODO Time test
|
|
||||||
#ifdef COMPILEDWITHC11
|
|
||||||
std::chrono::steady_clock::time_point timeStartFuseMerge = std::chrono::steady_clock::now();
|
|
||||||
#else
|
|
||||||
std::chrono::monotonic_clock::time_point timeStartFuseMerge = std::chrono::monotonic_clock::now();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Project MapPoints observed in the neighborhood of the merge keyframe
|
// Project MapPoints observed in the neighborhood of the merge keyframe
|
||||||
// into the current keyframe and neighbors using corrected poses.
|
// into the current keyframe and neighbors using corrected poses.
|
||||||
// Fuse duplications.
|
// Fuse duplications.
|
||||||
SearchAndFuse(vCorrectedSim3, vpCheckFuseMapPoint);
|
SearchAndFuse(vCorrectedSim3, vpCheckFuseMapPoint);
|
||||||
|
|
||||||
#ifdef COMPILEDWITHC11
|
|
||||||
std::chrono::steady_clock::time_point timeFinishFuseMerge = std::chrono::steady_clock::now();
|
|
||||||
#else
|
|
||||||
std::chrono::monotonic_clock::time_point timeFinishFuseMerge = std::chrono::monotonic_clock::now();
|
|
||||||
#endif
|
|
||||||
std::chrono::duration<double,std::milli> timeFuseMerge = timeFinishFuseMerge - timeStartFuseMerge; // Time in milliseconds
|
|
||||||
Verbose::PrintMess("MERGE-VISUAL: FUSE DUPLICATED ms: " + to_string(timeFuseMerge.count()), Verbose::VERBOSITY_DEBUG);
|
|
||||||
|
|
||||||
// Update connectivity
|
// Update connectivity
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Init to update connections in the welding area", Verbose::VERBOSITY_DEBUG);
|
|
||||||
for(KeyFrame* pKFi : spLocalWindowKFs)
|
for(KeyFrame* pKFi : spLocalWindowKFs)
|
||||||
{
|
{
|
||||||
if(!pKFi || pKFi->isBad())
|
if(!pKFi || pKFi->isBad())
|
||||||
|
@ -1779,34 +1660,25 @@ void LoopClosing::MergeLocal()
|
||||||
pKFi->UpdateConnections();
|
pKFi->UpdateConnections();
|
||||||
}
|
}
|
||||||
|
|
||||||
//CheckObservations(spLocalWindowKFs, spMergeConnectedKFs);
|
|
||||||
|
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Finish to update connections in the welding area", Verbose::VERBOSITY_DEBUG);
|
|
||||||
|
|
||||||
bool bStop = false;
|
bool bStop = false;
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Start local BA ", Verbose::VERBOSITY_DEBUG);
|
Verbose::PrintMess("MERGE: Start local BA ", Verbose::VERBOSITY_DEBUG);
|
||||||
vpLocalCurrentWindowKFs.clear();
|
vpLocalCurrentWindowKFs.clear();
|
||||||
vpMergeConnectedKFs.clear();
|
vpMergeConnectedKFs.clear();
|
||||||
std::copy(spLocalWindowKFs.begin(), spLocalWindowKFs.end(), std::back_inserter(vpLocalCurrentWindowKFs));
|
std::copy(spLocalWindowKFs.begin(), spLocalWindowKFs.end(), std::back_inserter(vpLocalCurrentWindowKFs));
|
||||||
std::copy(spMergeConnectedKFs.begin(), spMergeConnectedKFs.end(), std::back_inserter(vpMergeConnectedKFs));
|
std::copy(spMergeConnectedKFs.begin(), spMergeConnectedKFs.end(), std::back_inserter(vpMergeConnectedKFs));
|
||||||
if (mpTracker->mSensor==System::IMU_MONOCULAR || mpTracker->mSensor==System::IMU_STEREO)
|
if (mpTracker->mSensor==System::IMU_MONOCULAR || mpTracker->mSensor==System::IMU_STEREO)
|
||||||
{
|
{
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Visual-Inertial", Verbose::VERBOSITY_DEBUG);
|
|
||||||
Optimizer::MergeInertialBA(mpLocalMapper->GetCurrKF(),mpMergeMatchedKF,&bStop, mpCurrentKF->GetMap(),vCorrectedSim3);
|
Optimizer::MergeInertialBA(mpLocalMapper->GetCurrKF(),mpMergeMatchedKF,&bStop, mpCurrentKF->GetMap(),vCorrectedSim3);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Visual", Verbose::VERBOSITY_DEBUG);
|
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Local current window->" + to_string(vpLocalCurrentWindowKFs.size()) + "; Local merge window->" + to_string(vpMergeConnectedKFs.size()), Verbose::VERBOSITY_DEBUG);
|
|
||||||
Optimizer::LocalBundleAdjustment(mpCurrentKF, vpLocalCurrentWindowKFs, vpMergeConnectedKFs,&bStop);
|
Optimizer::LocalBundleAdjustment(mpCurrentKF, vpLocalCurrentWindowKFs, vpMergeConnectedKFs,&bStop);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop closed. Release Local Mapping.
|
// Loop closed. Release Local Mapping.
|
||||||
mpLocalMapper->Release();
|
mpLocalMapper->Release();
|
||||||
|
|
||||||
|
Verbose::PrintMess("MERGE: Finish the LBA", Verbose::VERBOSITY_DEBUG);
|
||||||
//return;
|
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Finish the LBA", Verbose::VERBOSITY_DEBUG);
|
|
||||||
|
|
||||||
|
|
||||||
////
|
////
|
||||||
|
@ -1816,11 +1688,11 @@ void LoopClosing::MergeLocal()
|
||||||
|
|
||||||
if(vpCurrentMapKFs.size() == 0)
|
if(vpCurrentMapKFs.size() == 0)
|
||||||
{
|
{
|
||||||
Verbose::PrintMess("MERGE-VISUAL: There are not KFs outside of the welding area", Verbose::VERBOSITY_DEBUG);
|
Verbose::PrintMess("MERGE: There are not KFs outside of the welding area", Verbose::VERBOSITY_DEBUG);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Calculate the new position of the elements outside of the window", Verbose::VERBOSITY_DEBUG);
|
Verbose::PrintMess("MERGE: Calculate the new position of the elements outside of the window", Verbose::VERBOSITY_DEBUG);
|
||||||
//Apply the transformation
|
//Apply the transformation
|
||||||
{
|
{
|
||||||
if(mpTracker->mSensor == System::MONOCULAR)
|
if(mpTracker->mSensor == System::MONOCULAR)
|
||||||
|
@ -1893,7 +1765,6 @@ void LoopClosing::MergeLocal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Apply transformation to all elements of the old map", Verbose::VERBOSITY_DEBUG);
|
|
||||||
|
|
||||||
mpLocalMapper->RequestStop();
|
mpLocalMapper->RequestStop();
|
||||||
// Wait until Local Mapping has effectively stopped
|
// Wait until Local Mapping has effectively stopped
|
||||||
|
@ -1901,7 +1772,6 @@ void LoopClosing::MergeLocal()
|
||||||
{
|
{
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
}
|
}
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Local Map stopped", Verbose::VERBOSITY_DEBUG);
|
|
||||||
|
|
||||||
// Optimize graph (and update the loop position for each element form the begining to the end)
|
// Optimize graph (and update the loop position for each element form the begining to the end)
|
||||||
if(mpTracker->mSensor != System::MONOCULAR)
|
if(mpTracker->mSensor != System::MONOCULAR)
|
||||||
|
@ -1915,9 +1785,6 @@ void LoopClosing::MergeLocal()
|
||||||
unique_lock<mutex> currentLock(pCurrentMap->mMutexMapUpdate); // We update the current map with the Merge information
|
unique_lock<mutex> currentLock(pCurrentMap->mMutexMapUpdate); // We update the current map with the Merge information
|
||||||
unique_lock<mutex> mergeLock(pMergeMap->mMutexMapUpdate); // We remove the Kfs and MPs in the merged area from the old map
|
unique_lock<mutex> mergeLock(pMergeMap->mMutexMapUpdate); // We remove the Kfs and MPs in the merged area from the old map
|
||||||
|
|
||||||
Verbose::PrintMess("MERGE-VISUAL: There are " + to_string(pMergeMap->KeyFramesInMap()) + " KFs in the map", Verbose::VERBOSITY_DEBUG);
|
|
||||||
Verbose::PrintMess("MERGE-VISUAL: It will be inserted " + to_string(vpCurrentMapKFs.size()) + " KFs in the map", Verbose::VERBOSITY_DEBUG);
|
|
||||||
|
|
||||||
for(KeyFrame* pKFi : vpCurrentMapKFs)
|
for(KeyFrame* pKFi : vpCurrentMapKFs)
|
||||||
{
|
{
|
||||||
if(!pKFi || pKFi->isBad() || pKFi->GetMap() != pCurrentMap)
|
if(!pKFi || pKFi->isBad() || pKFi->GetMap() != pCurrentMap)
|
||||||
|
@ -1930,8 +1797,6 @@ void LoopClosing::MergeLocal()
|
||||||
pMergeMap->AddKeyFrame(pKFi);
|
pMergeMap->AddKeyFrame(pKFi);
|
||||||
pCurrentMap->EraseKeyFrame(pKFi);
|
pCurrentMap->EraseKeyFrame(pKFi);
|
||||||
}
|
}
|
||||||
Verbose::PrintMess("MERGE-VISUAL: There are " + to_string(pMergeMap->MapPointsInMap()) + " MPs in the map", Verbose::VERBOSITY_DEBUG);
|
|
||||||
Verbose::PrintMess("MERGE-VISUAL: It will be inserted " + to_string(vpCurrentMapMPs.size()) + " MPs in the map", Verbose::VERBOSITY_DEBUG);
|
|
||||||
|
|
||||||
for(MapPoint* pMPi : vpCurrentMapMPs)
|
for(MapPoint* pMPi : vpCurrentMapMPs)
|
||||||
{
|
{
|
||||||
|
@ -1942,19 +1807,12 @@ void LoopClosing::MergeLocal()
|
||||||
pMergeMap->AddMapPoint(pMPi);
|
pMergeMap->AddMapPoint(pMPi);
|
||||||
pCurrentMap->EraseMapPoint(pMPi);
|
pCurrentMap->EraseMapPoint(pMPi);
|
||||||
}
|
}
|
||||||
Verbose::PrintMess("MERGE-VISUAL: There are " + to_string(pMergeMap->MapPointsInMap()) + " MPs in the map", Verbose::VERBOSITY_DEBUG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Optimaze the essential graph", Verbose::VERBOSITY_DEBUG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mpLocalMapper->Release();
|
mpLocalMapper->Release();
|
||||||
|
|
||||||
|
Verbose::PrintMess("MERGE:Completed!!!!!", Verbose::VERBOSITY_DEBUG);
|
||||||
Verbose::PrintMess("MERGE-VISUAL: Finally there are " + to_string(pMergeMap->KeyFramesInMap()) + "KFs and " + to_string(pMergeMap->MapPointsInMap()) + " MPs in the complete map ", Verbose::VERBOSITY_DEBUG);
|
|
||||||
Verbose::PrintMess("MERGE-VISUAL:Completed!!!!!", Verbose::VERBOSITY_DEBUG);
|
|
||||||
|
|
||||||
if(bRelaunchBA && (!pCurrentMap->isImuInitialized() || (pCurrentMap->KeyFramesInMap()<200 && mpAtlas->CountMaps()==1)))
|
if(bRelaunchBA && (!pCurrentMap->isImuInitialized() || (pCurrentMap->KeyFramesInMap()<200 && mpAtlas->CountMaps()==1)))
|
||||||
{
|
{
|
||||||
|
@ -1976,52 +1834,6 @@ void LoopClosing::MergeLocal()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoopClosing::printReprojectionError(set<KeyFrame*> &spLocalWindowKFs, KeyFrame* mpCurrentKF, string &name)
|
|
||||||
{
|
|
||||||
string path_imgs = "./test_Reproj/";
|
|
||||||
for(KeyFrame* pKFi : spLocalWindowKFs)
|
|
||||||
{
|
|
||||||
//cout << "KF " << pKFi->mnId << endl;
|
|
||||||
cv::Mat img_i = cv::imread(pKFi->mNameFile, CV_LOAD_IMAGE_UNCHANGED);
|
|
||||||
//cout << "Image -> " << img_i.cols << ", " << img_i.rows << endl;
|
|
||||||
cv::cvtColor(img_i, img_i, CV_GRAY2BGR);
|
|
||||||
//cout << "Change of color in the image " << endl;
|
|
||||||
|
|
||||||
vector<MapPoint*> vpMPs = pKFi->GetMapPointMatches();
|
|
||||||
int num_points = 0;
|
|
||||||
for(int j=0; j<vpMPs.size(); ++j)
|
|
||||||
{
|
|
||||||
MapPoint* pMPij = vpMPs[j];
|
|
||||||
if(!pMPij || pMPij->isBad())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
cv::KeyPoint point_img = pKFi->mvKeysUn[j];
|
|
||||||
cv::Point2f reproj_p;
|
|
||||||
float u, v;
|
|
||||||
bool bIsInImage = pKFi->ProjectPointUnDistort(pMPij, reproj_p, u, v);
|
|
||||||
if(bIsInImage){
|
|
||||||
//cout << "Reproj in the image" << endl;
|
|
||||||
cv::circle(img_i, point_img.pt, 1/*point_img.octave*/, cv::Scalar(0, 255, 0));
|
|
||||||
cv::line(img_i, point_img.pt, reproj_p, cv::Scalar(0, 0, 255));
|
|
||||||
num_points++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//cout << "Reproj out of the image" << endl;
|
|
||||||
cv::circle(img_i, point_img.pt, point_img.octave, cv::Scalar(0, 0, 255));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
//cout << "Image painted" << endl;
|
|
||||||
string filename_img = path_imgs + "KF" + to_string(mpCurrentKF->mnId) + "_" + to_string(pKFi->mnId) + name + "points" + to_string(num_points) + ".png";
|
|
||||||
cv::imwrite(filename_img, img_i);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LoopClosing::MergeLocal2()
|
void LoopClosing::MergeLocal2()
|
||||||
{
|
{
|
||||||
cout << "Merge detected!!!!" << endl;
|
cout << "Merge detected!!!!" << endl;
|
||||||
|
@ -2078,14 +1890,9 @@ void LoopClosing::MergeLocal2()
|
||||||
|
|
||||||
unique_lock<mutex> lock(mpAtlas->GetCurrentMap()->mMutexMapUpdate);
|
unique_lock<mutex> lock(mpAtlas->GetCurrentMap()->mMutexMapUpdate);
|
||||||
|
|
||||||
cout << "KFs before empty: " << mpAtlas->GetCurrentMap()->KeyFramesInMap() << endl;
|
|
||||||
mpLocalMapper->EmptyQueue();
|
mpLocalMapper->EmptyQueue();
|
||||||
cout << "KFs after empty: " << mpAtlas->GetCurrentMap()->KeyFramesInMap() << endl;
|
|
||||||
|
|
||||||
std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();
|
std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();
|
||||||
cout << "updating active map to merge reference" << endl;
|
|
||||||
cout << "curr merge KF id: " << mpCurrentKF->mnId << endl;
|
|
||||||
cout << "curr tracking KF id: " << mpTracker->GetLastKeyFrame()->mnId << endl;
|
|
||||||
bool bScaleVel=false;
|
bool bScaleVel=false;
|
||||||
if(s_on!=1)
|
if(s_on!=1)
|
||||||
bScaleVel=true;
|
bScaleVel=true;
|
||||||
|
@ -2114,11 +1921,7 @@ void LoopClosing::MergeLocal2()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cout << "MergeMap init ID: " << pMergeMap->GetInitKFid() << " CurrMap init ID: " << pCurrentMap->GetInitKFid() << endl;
|
|
||||||
|
|
||||||
// Load KFs and MPs from merge map
|
// Load KFs and MPs from merge map
|
||||||
cout << "updating current map" << endl;
|
|
||||||
{
|
{
|
||||||
// Get Merge Map Mutex (This section stops tracking!!)
|
// Get Merge Map Mutex (This section stops tracking!!)
|
||||||
unique_lock<mutex> currentLock(pCurrentMap->mMutexMapUpdate); // We update the current map with the Merge information
|
unique_lock<mutex> currentLock(pCurrentMap->mMutexMapUpdate); // We update the current map with the Merge information
|
||||||
|
@ -2164,17 +1967,6 @@ void LoopClosing::MergeLocal2()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "MergeMap init ID: " << pMergeMap->GetInitKFid() << " CurrMap init ID: " << pCurrentMap->GetInitKFid() << endl;
|
|
||||||
|
|
||||||
cout << "end updating current map" << endl;
|
|
||||||
|
|
||||||
// Critical zone
|
|
||||||
bool good = pCurrentMap->CheckEssentialGraph();
|
|
||||||
/*if(!good)
|
|
||||||
cout << "BAD ESSENTIAL GRAPH!!" << endl;*/
|
|
||||||
|
|
||||||
cout << "Update essential graph" << endl;
|
|
||||||
// mpCurrentKF->UpdateConnections(); // to put at false mbFirstConnection
|
|
||||||
pMergeMap->GetOriginKF()->SetFirstConnection(false);
|
pMergeMap->GetOriginKF()->SetFirstConnection(false);
|
||||||
pNewChild = mpMergeMatchedKF->GetParent(); // Old parent, it will be the new child of this KF
|
pNewChild = mpMergeMatchedKF->GetParent(); // Old parent, it will be the new child of this KF
|
||||||
pNewParent = mpMergeMatchedKF; // Old child, now it will be the parent of its own parent(we need eliminate this KF from children list in its old parent)
|
pNewParent = mpMergeMatchedKF; // Old child, now it will be the parent of its own parent(we need eliminate this KF from children list in its old parent)
|
||||||
|
@ -2189,33 +1981,17 @@ void LoopClosing::MergeLocal2()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cout << "MergeMap init ID: " << pMergeMap->GetInitKFid() << " CurrMap init ID: " << pCurrentMap->GetInitKFid() << endl;
|
|
||||||
|
|
||||||
cout << "end update essential graph" << endl;
|
|
||||||
|
|
||||||
good = pCurrentMap->CheckEssentialGraph();
|
|
||||||
if(!good)
|
|
||||||
cout << "BAD ESSENTIAL GRAPH 1!!" << endl;
|
|
||||||
|
|
||||||
cout << "Update relationship between KFs" << endl;
|
|
||||||
vector<MapPoint*> vpCheckFuseMapPoint; // MapPoint vector from current map to allow to fuse duplicated points with the old map (merge)
|
vector<MapPoint*> vpCheckFuseMapPoint; // MapPoint vector from current map to allow to fuse duplicated points with the old map (merge)
|
||||||
vector<KeyFrame*> vpCurrentConnectedKFs;
|
vector<KeyFrame*> vpCurrentConnectedKFs;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mvpMergeConnectedKFs.push_back(mpMergeMatchedKF);
|
mvpMergeConnectedKFs.push_back(mpMergeMatchedKF);
|
||||||
vector<KeyFrame*> aux = mpMergeMatchedKF->GetVectorCovisibleKeyFrames();
|
vector<KeyFrame*> aux = mpMergeMatchedKF->GetVectorCovisibleKeyFrames();
|
||||||
mvpMergeConnectedKFs.insert(mvpMergeConnectedKFs.end(), aux.begin(), aux.end());
|
mvpMergeConnectedKFs.insert(mvpMergeConnectedKFs.end(), aux.begin(), aux.end());
|
||||||
if (mvpMergeConnectedKFs.size()>6)
|
if (mvpMergeConnectedKFs.size()>6)
|
||||||
mvpMergeConnectedKFs.erase(mvpMergeConnectedKFs.begin()+6,mvpMergeConnectedKFs.end());
|
mvpMergeConnectedKFs.erase(mvpMergeConnectedKFs.begin()+6,mvpMergeConnectedKFs.end());
|
||||||
/*mvpMergeConnectedKFs = mpMergeMatchedKF->GetVectorCovisibleKeyFrames();
|
|
||||||
mvpMergeConnectedKFs.push_back(mpMergeMatchedKF);*/
|
|
||||||
|
|
||||||
mpCurrentKF->UpdateConnections();
|
mpCurrentKF->UpdateConnections();
|
||||||
vpCurrentConnectedKFs.push_back(mpCurrentKF);
|
vpCurrentConnectedKFs.push_back(mpCurrentKF);
|
||||||
/*vpCurrentConnectedKFs = mpCurrentKF->GetVectorCovisibleKeyFrames();
|
|
||||||
vpCurrentConnectedKFs.push_back(mpCurrentKF);*/
|
|
||||||
aux = mpCurrentKF->GetVectorCovisibleKeyFrames();
|
aux = mpCurrentKF->GetVectorCovisibleKeyFrames();
|
||||||
vpCurrentConnectedKFs.insert(vpCurrentConnectedKFs.end(), aux.begin(), aux.end());
|
vpCurrentConnectedKFs.insert(vpCurrentConnectedKFs.end(), aux.begin(), aux.end());
|
||||||
if (vpCurrentConnectedKFs.size()>6)
|
if (vpCurrentConnectedKFs.size()>6)
|
||||||
|
@ -2230,33 +2006,10 @@ void LoopClosing::MergeLocal2()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "vpCurrentConnectedKFs.size() " << vpCurrentConnectedKFs.size() << endl;
|
|
||||||
cout << "mvpMergeConnectedKFs.size() " << mvpMergeConnectedKFs.size() << endl;
|
|
||||||
cout << "spMapPointMerge.size() " << spMapPointMerge.size() << endl;
|
|
||||||
|
|
||||||
|
|
||||||
vpCheckFuseMapPoint.reserve(spMapPointMerge.size());
|
vpCheckFuseMapPoint.reserve(spMapPointMerge.size());
|
||||||
std::copy(spMapPointMerge.begin(), spMapPointMerge.end(), std::back_inserter(vpCheckFuseMapPoint));
|
std::copy(spMapPointMerge.begin(), spMapPointMerge.end(), std::back_inserter(vpCheckFuseMapPoint));
|
||||||
cout << "Finished to update relationship between KFs" << endl;
|
|
||||||
|
|
||||||
cout << "MergeMap init ID: " << pMergeMap->GetInitKFid() << " CurrMap init ID: " << pCurrentMap->GetInitKFid() << endl;
|
|
||||||
|
|
||||||
good = pCurrentMap->CheckEssentialGraph();
|
|
||||||
if(!good)
|
|
||||||
cout << "BAD ESSENTIAL GRAPH 2!!" << endl;
|
|
||||||
|
|
||||||
cout << "start SearchAndFuse" << endl;
|
|
||||||
SearchAndFuse(vpCurrentConnectedKFs, vpCheckFuseMapPoint);
|
SearchAndFuse(vpCurrentConnectedKFs, vpCheckFuseMapPoint);
|
||||||
cout << "end SearchAndFuse" << endl;
|
|
||||||
|
|
||||||
cout << "MergeMap init ID: " << pMergeMap->GetInitKFid() << " CurrMap init ID: " << pCurrentMap->GetInitKFid() << endl;
|
|
||||||
|
|
||||||
good = pCurrentMap->CheckEssentialGraph();
|
|
||||||
if(!good)
|
|
||||||
cout << "BAD ESSENTIAL GRAPH 3!!" << endl;
|
|
||||||
|
|
||||||
cout << "Init to update connections" << endl;
|
|
||||||
|
|
||||||
|
|
||||||
for(KeyFrame* pKFi : vpCurrentConnectedKFs)
|
for(KeyFrame* pKFi : vpCurrentConnectedKFs)
|
||||||
{
|
{
|
||||||
|
@ -2272,34 +2025,16 @@ void LoopClosing::MergeLocal2()
|
||||||
|
|
||||||
pKFi->UpdateConnections();
|
pKFi->UpdateConnections();
|
||||||
}
|
}
|
||||||
cout << "end update connections" << endl;
|
|
||||||
|
|
||||||
cout << "MergeMap init ID: " << pMergeMap->GetInitKFid() << " CurrMap init ID: " << pCurrentMap->GetInitKFid() << endl;
|
|
||||||
|
|
||||||
good = pCurrentMap->CheckEssentialGraph();
|
|
||||||
if(!good)
|
|
||||||
cout << "BAD ESSENTIAL GRAPH 4!!" << endl;
|
|
||||||
|
|
||||||
// TODO Check: If new map is too small, we suppose that not informaiton can be propagated from new to old map
|
|
||||||
if (numKFnew<10){
|
if (numKFnew<10){
|
||||||
mpLocalMapper->Release();
|
mpLocalMapper->Release();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
good = pCurrentMap->CheckEssentialGraph();
|
|
||||||
if(!good)
|
|
||||||
cout << "BAD ESSENTIAL GRAPH 5!!" << endl;
|
|
||||||
|
|
||||||
// Perform BA
|
// Perform BA
|
||||||
bool bStopFlag=false;
|
bool bStopFlag=false;
|
||||||
KeyFrame* pCurrKF = mpTracker->GetLastKeyFrame();
|
KeyFrame* pCurrKF = mpTracker->GetLastKeyFrame();
|
||||||
cout << "start MergeInertialBA" << endl;
|
|
||||||
Optimizer::MergeInertialBA(pCurrKF, mpMergeMatchedKF, &bStopFlag, pCurrentMap,CorrectedSim3);
|
Optimizer::MergeInertialBA(pCurrKF, mpMergeMatchedKF, &bStopFlag, pCurrentMap,CorrectedSim3);
|
||||||
cout << "end MergeInertialBA" << endl;
|
|
||||||
|
|
||||||
good = pCurrentMap->CheckEssentialGraph();
|
|
||||||
if(!good)
|
|
||||||
cout << "BAD ESSENTIAL GRAPH 6!!" << endl;
|
|
||||||
|
|
||||||
// Release Local Mapping.
|
// Release Local Mapping.
|
||||||
mpLocalMapper->Release();
|
mpLocalMapper->Release();
|
||||||
|
@ -2308,64 +2043,12 @@ void LoopClosing::MergeLocal2()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoopClosing::CheckObservations(set<KeyFrame*> &spKFsMap1, set<KeyFrame*> &spKFsMap2)
|
|
||||||
{
|
|
||||||
cout << "----------------------" << endl;
|
|
||||||
for(KeyFrame* pKFi1 : spKFsMap1)
|
|
||||||
{
|
|
||||||
map<KeyFrame*, int> mMatchedMP;
|
|
||||||
set<MapPoint*> spMPs = pKFi1->GetMapPoints();
|
|
||||||
|
|
||||||
for(MapPoint* pMPij : spMPs)
|
|
||||||
{
|
|
||||||
if(!pMPij || pMPij->isBad())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
map<KeyFrame*, tuple<int,int>> mMPijObs = pMPij->GetObservations();
|
|
||||||
for(KeyFrame* pKFi2 : spKFsMap2)
|
|
||||||
{
|
|
||||||
if(mMPijObs.find(pKFi2) != mMPijObs.end())
|
|
||||||
{
|
|
||||||
if(mMatchedMP.find(pKFi2) != mMatchedMP.end())
|
|
||||||
{
|
|
||||||
mMatchedMP[pKFi2] = mMatchedMP[pKFi2] + 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mMatchedMP[pKFi2] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mMatchedMP.size() == 0)
|
|
||||||
{
|
|
||||||
cout << "CHECK-OBS: KF " << pKFi1->mnId << " has not any matched MP with the other map" << endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cout << "CHECK-OBS: KF " << pKFi1->mnId << " has matched MP with " << mMatchedMP.size() << " KF from the other map" << endl;
|
|
||||||
for(pair<KeyFrame*, int> matchedKF : mMatchedMP)
|
|
||||||
{
|
|
||||||
cout << " -KF: " << matchedKF.first->mnId << ", Number of matches: " << matchedKF.second << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cout << "----------------------" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LoopClosing::SearchAndFuse(const KeyFrameAndPose &CorrectedPosesMap, vector<MapPoint*> &vpMapPoints)
|
void LoopClosing::SearchAndFuse(const KeyFrameAndPose &CorrectedPosesMap, vector<MapPoint*> &vpMapPoints)
|
||||||
{
|
{
|
||||||
ORBmatcher matcher(0.8);
|
ORBmatcher matcher(0.8);
|
||||||
|
|
||||||
int total_replaces = 0;
|
int total_replaces = 0;
|
||||||
|
|
||||||
cout << "FUSE: Initially there are " << vpMapPoints.size() << " MPs" << endl;
|
|
||||||
cout << "FUSE: Intially there are " << CorrectedPosesMap.size() << " KFs" << endl;
|
|
||||||
for(KeyFrameAndPose::const_iterator mit=CorrectedPosesMap.begin(), mend=CorrectedPosesMap.end(); mit!=mend;mit++)
|
for(KeyFrameAndPose::const_iterator mit=CorrectedPosesMap.begin(), mend=CorrectedPosesMap.end(); mit!=mend;mit++)
|
||||||
{
|
{
|
||||||
int num_replaces = 0;
|
int num_replaces = 0;
|
||||||
|
@ -2396,7 +2079,6 @@ void LoopClosing::SearchAndFuse(const KeyFrameAndPose &CorrectedPosesMap, vector
|
||||||
|
|
||||||
total_replaces += num_replaces;
|
total_replaces += num_replaces;
|
||||||
}
|
}
|
||||||
cout << "FUSE: " << total_replaces << " MPs had been fused" << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2406,8 +2088,6 @@ void LoopClosing::SearchAndFuse(const vector<KeyFrame*> &vConectedKFs, vector<Ma
|
||||||
|
|
||||||
int total_replaces = 0;
|
int total_replaces = 0;
|
||||||
|
|
||||||
cout << "FUSE-POSE: Initially there are " << vpMapPoints.size() << " MPs" << endl;
|
|
||||||
cout << "FUSE-POSE: Intially there are " << vConectedKFs.size() << " KFs" << endl;
|
|
||||||
for(auto mit=vConectedKFs.begin(), mend=vConectedKFs.end(); mit!=mend;mit++)
|
for(auto mit=vConectedKFs.begin(), mend=vConectedKFs.end(); mit!=mend;mit++)
|
||||||
{
|
{
|
||||||
int num_replaces = 0;
|
int num_replaces = 0;
|
||||||
|
@ -2430,10 +2110,8 @@ void LoopClosing::SearchAndFuse(const vector<KeyFrame*> &vConectedKFs, vector<Ma
|
||||||
pRep->Replace(vpMapPoints[i]);
|
pRep->Replace(vpMapPoints[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cout << "FUSE-POSE: KF " << pKF->mnId << " ->" << num_replaces << " MPs fused" << endl;
|
|
||||||
total_replaces += num_replaces;
|
total_replaces += num_replaces;
|
||||||
}
|
}
|
||||||
cout << "FUSE-POSE: " << total_replaces << " MPs had been fused" << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 由外部线程调用,请求复位当前线程
|
// 由外部线程调用,请求复位当前线程
|
||||||
|
@ -2513,11 +2191,22 @@ void LoopClosing::RunGlobalBundleAdjustment(Map* pActiveMap, unsigned long nLoop
|
||||||
|
|
||||||
const bool bImuInit = pActiveMap->isImuInitialized();
|
const bool bImuInit = pActiveMap->isImuInitialized();
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_StartFGBA = std::chrono::steady_clock::now();
|
||||||
|
#endif
|
||||||
|
|
||||||
if(!bImuInit)
|
if(!bImuInit)
|
||||||
Optimizer::GlobalBundleAdjustemnt(pActiveMap,10,&mbStopGBA,nLoopKF,false);
|
Optimizer::GlobalBundleAdjustemnt(pActiveMap,10,&mbStopGBA,nLoopKF,false);
|
||||||
else
|
else
|
||||||
Optimizer::FullInertialBA(pActiveMap,7,false,nLoopKF,&mbStopGBA);
|
Optimizer::FullInertialBA(pActiveMap,7,false,nLoopKF,&mbStopGBA);
|
||||||
// 记录GBA已经迭代次数,用来检查全局BA过程是否是因为意外结束的
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_StartMapUpdate = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
double timeFullGBA = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_StartMapUpdate - time_StartFGBA).count();
|
||||||
|
vTimeFullGBA_ms.push_back(timeFullGBA);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int idx = mnFullBAIdx;
|
int idx = mnFullBAIdx;
|
||||||
// Optimizer::GlobalBundleAdjustemnt(mpMap,10,&mbStopGBA,nLoopKF,false);
|
// Optimizer::GlobalBundleAdjustemnt(mpMap,10,&mbStopGBA,nLoopKF,false);
|
||||||
|
@ -2733,6 +2422,16 @@ void LoopClosing::RunGlobalBundleAdjustment(Map* pActiveMap, unsigned long nLoop
|
||||||
mbFinishedGBA = true;
|
mbFinishedGBA = true;
|
||||||
mbRunningGBA = false;
|
mbRunningGBA = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_EndMapUpdate = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
double timeMapUpdate = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndMapUpdate - time_StartMapUpdate).count();
|
||||||
|
vTimeMapUpdate_ms.push_back(timeMapUpdate);
|
||||||
|
|
||||||
|
double timeGBA = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndMapUpdate - time_StartFGBA).count();
|
||||||
|
vTimeGBATotal_ms.push_back(timeGBA);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// 由外部线程调用,请求终止当前线程
|
// 由外部线程调用,请求终止当前线程
|
||||||
|
|
149
src/Map.cc
149
src/Map.cc
|
@ -502,154 +502,5 @@ void Map::SetLastMapChange(int currentChangeId)
|
||||||
mnMapChangeNotified = currentChangeId;
|
mnMapChangeNotified = currentChangeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::printReprojectionError(list<KeyFrame*> &lpLocalWindowKFs, KeyFrame* mpCurrentKF, string &name, string &name_folder)
|
|
||||||
{
|
|
||||||
string path_imgs = "./" + name_folder + "/";
|
|
||||||
for(KeyFrame* pKFi : lpLocalWindowKFs)
|
|
||||||
{
|
|
||||||
//cout << "KF " << pKFi->mnId << endl;
|
|
||||||
cv::Mat img_i = cv::imread(pKFi->mNameFile, CV_LOAD_IMAGE_UNCHANGED);
|
|
||||||
//cout << "Image -> " << img_i.cols << ", " << img_i.rows << endl;
|
|
||||||
cv::cvtColor(img_i, img_i, CV_GRAY2BGR);
|
|
||||||
//cout << "Change of color in the image " << endl;
|
|
||||||
|
|
||||||
vector<MapPoint*> vpMPs = pKFi->GetMapPointMatches();
|
|
||||||
int num_points = 0;
|
|
||||||
for(int j=0; j<vpMPs.size(); ++j)
|
|
||||||
{
|
|
||||||
MapPoint* pMPij = vpMPs[j];
|
|
||||||
if(!pMPij || pMPij->isBad())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
cv::KeyPoint point_img = pKFi->mvKeysUn[j];
|
|
||||||
cv::Point2f reproj_p;
|
|
||||||
float u, v;
|
|
||||||
bool bIsInImage = pKFi->ProjectPointUnDistort(pMPij, reproj_p, u, v);
|
|
||||||
if(bIsInImage){
|
|
||||||
//cout << "Reproj in the image" << endl;
|
|
||||||
cv::circle(img_i, point_img.pt, 1/*point_img.octave*/, cv::Scalar(0, 255, 0));
|
|
||||||
cv::line(img_i, point_img.pt, reproj_p, cv::Scalar(0, 0, 255));
|
|
||||||
num_points++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//cout << "Reproj out of the image" << endl;
|
|
||||||
cv::circle(img_i, point_img.pt, point_img.octave, cv::Scalar(0, 0, 255));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
//cout << "Image painted" << endl;
|
|
||||||
string filename_img = path_imgs + "KF" + to_string(mpCurrentKF->mnId) + "_" + to_string(pKFi->mnId) + name + "points" + to_string(num_points) + ".png";
|
|
||||||
cv::imwrite(filename_img, img_i);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Map::PreSave(std::set<GeometricCamera*> &spCams)
|
|
||||||
{
|
|
||||||
int nMPWithoutObs = 0;
|
|
||||||
for(MapPoint* pMPi : mspMapPoints)
|
|
||||||
{
|
|
||||||
if(pMPi->GetObservations().size() == 0)
|
|
||||||
{
|
|
||||||
nMPWithoutObs++;
|
|
||||||
}
|
|
||||||
map<KeyFrame*, std::tuple<int,int>> mpObs = pMPi->GetObservations();
|
|
||||||
for(map<KeyFrame*, std::tuple<int,int>>::iterator it= mpObs.begin(), end=mpObs.end(); it!=end; ++it)
|
|
||||||
{
|
|
||||||
if(it->first->GetMap() != this)
|
|
||||||
{
|
|
||||||
pMPi->EraseObservation(it->first); //We need to find where the KF is set as Bad but the observation is not removed
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cout << " Bad MapPoints removed" << endl;
|
|
||||||
|
|
||||||
// Saves the id of KF origins
|
|
||||||
mvBackupKeyFrameOriginsId.reserve(mvpKeyFrameOrigins.size());
|
|
||||||
for(int i = 0, numEl = mvpKeyFrameOrigins.size(); i < numEl; ++i)
|
|
||||||
{
|
|
||||||
mvBackupKeyFrameOriginsId.push_back(mvpKeyFrameOrigins[i]->mnId);
|
|
||||||
}
|
|
||||||
|
|
||||||
mvpBackupMapPoints.clear();
|
|
||||||
// Backup of set container to vector
|
|
||||||
//std::copy(mspMapPoints.begin(), mspMapPoints.end(), std::back_inserter(mvpBackupMapPoints));
|
|
||||||
for(MapPoint* pMPi : mspMapPoints)
|
|
||||||
{
|
|
||||||
//cout << "Pre-save of mappoint " << pMPi->mnId << endl;
|
|
||||||
mvpBackupMapPoints.push_back(pMPi);
|
|
||||||
pMPi->PreSave(mspKeyFrames,mspMapPoints);
|
|
||||||
}
|
|
||||||
cout << " MapPoints back up done!!" << endl;
|
|
||||||
|
|
||||||
mvpBackupKeyFrames.clear();
|
|
||||||
//std::copy(mspKeyFrames.begin(), mspKeyFrames.end(), std::back_inserter(mvpBackupKeyFrames));
|
|
||||||
for(KeyFrame* pKFi : mspKeyFrames)
|
|
||||||
{
|
|
||||||
mvpBackupKeyFrames.push_back(pKFi);
|
|
||||||
pKFi->PreSave(mspKeyFrames,mspMapPoints, spCams);
|
|
||||||
}
|
|
||||||
cout << " KeyFrames back up done!!" << endl;
|
|
||||||
|
|
||||||
mnBackupKFinitialID = -1;
|
|
||||||
if(mpKFinitial)
|
|
||||||
{
|
|
||||||
mnBackupKFinitialID = mpKFinitial->mnId;
|
|
||||||
}
|
|
||||||
|
|
||||||
mnBackupKFlowerID = -1;
|
|
||||||
if(mpKFlowerID)
|
|
||||||
{
|
|
||||||
mnBackupKFlowerID = mpKFlowerID->mnId;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Map::PostLoad(KeyFrameDatabase* pKFDB, ORBVocabulary* pORBVoc, map<long unsigned int, KeyFrame*>& mpKeyFrameId, map<unsigned int, GeometricCamera*> &mpCams)
|
|
||||||
{
|
|
||||||
std::copy(mvpBackupMapPoints.begin(), mvpBackupMapPoints.end(), std::inserter(mspMapPoints, mspMapPoints.begin()));
|
|
||||||
std::copy(mvpBackupKeyFrames.begin(), mvpBackupKeyFrames.end(), std::inserter(mspKeyFrames, mspKeyFrames.begin()));
|
|
||||||
|
|
||||||
map<long unsigned int,MapPoint*> mpMapPointId;
|
|
||||||
for(MapPoint* pMPi : mspMapPoints)
|
|
||||||
{
|
|
||||||
pMPi->UpdateMap(this);
|
|
||||||
mpMapPointId[pMPi->mnId] = pMPi;
|
|
||||||
}
|
|
||||||
|
|
||||||
//map<long unsigned int, KeyFrame*> mpKeyFrameId;
|
|
||||||
for(KeyFrame* pKFi : mspKeyFrames)
|
|
||||||
{
|
|
||||||
pKFi->UpdateMap(this);
|
|
||||||
pKFi->SetORBVocabulary(pORBVoc);
|
|
||||||
pKFi->SetKeyFrameDatabase(pKFDB);
|
|
||||||
mpKeyFrameId[pKFi->mnId] = pKFi;
|
|
||||||
}
|
|
||||||
cout << "Number of KF: " << mspKeyFrames.size() << endl;
|
|
||||||
cout << "Number of MP: " << mspMapPoints.size() << endl;
|
|
||||||
|
|
||||||
// References reconstruction between different instances
|
|
||||||
for(MapPoint* pMPi : mspMapPoints)
|
|
||||||
{
|
|
||||||
//cout << "Post-Load of mappoint " << pMPi->mnId << endl;
|
|
||||||
pMPi->PostLoad(mpKeyFrameId, mpMapPointId);
|
|
||||||
}
|
|
||||||
cout << "End to rebuild MapPoint references" << endl;
|
|
||||||
|
|
||||||
for(KeyFrame* pKFi : mspKeyFrames)
|
|
||||||
{
|
|
||||||
pKFi->PostLoad(mpKeyFrameId, mpMapPointId, mpCams);
|
|
||||||
pKFDB->add(pKFi);
|
|
||||||
}
|
|
||||||
|
|
||||||
cout << "End to rebuild KeyFrame references" << endl;
|
|
||||||
|
|
||||||
mvpBackupMapPoints.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} //namespace ORB_SLAM3
|
} //namespace ORB_SLAM3
|
||||||
|
|
|
@ -186,14 +186,10 @@ void MapDrawer::DrawKeyFrames(const bool bDrawKF, const bool bDrawGraph, const b
|
||||||
glLineWidth(mKeyFrameLineWidth*5);
|
glLineWidth(mKeyFrameLineWidth*5);
|
||||||
glColor3f(1.0f,0.0f,0.0f);
|
glColor3f(1.0f,0.0f,0.0f);
|
||||||
glBegin(GL_LINES);
|
glBegin(GL_LINES);
|
||||||
|
|
||||||
//cout << "Initial KF: " << mpAtlas->GetCurrentMap()->GetOriginKF()->mnId << endl;
|
|
||||||
//cout << "Parent KF: " << vpKFs[i]->mnId << endl;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glLineWidth(mKeyFrameLineWidth);
|
glLineWidth(mKeyFrameLineWidth);
|
||||||
//glColor3f(0.0f,0.0f,1.0f);
|
|
||||||
glColor3f(mfFrameColors[index_color][0],mfFrameColors[index_color][1],mfFrameColors[index_color][2]);
|
glColor3f(mfFrameColors[index_color][0],mfFrameColors[index_color][1],mfFrameColors[index_color][2]);
|
||||||
glBegin(GL_LINES);
|
glBegin(GL_LINES);
|
||||||
}
|
}
|
||||||
|
@ -222,32 +218,6 @@ void MapDrawer::DrawKeyFrames(const bool bDrawKF, const bool bDrawGraph, const b
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
//Draw lines with Loop and Merge candidates
|
|
||||||
/*glLineWidth(mGraphLineWidth);
|
|
||||||
glColor4f(1.0f,0.6f,0.0f,1.0f);
|
|
||||||
glBegin(GL_LINES);
|
|
||||||
cv::Mat Ow = pKF->GetCameraCenter();
|
|
||||||
const vector<KeyFrame*> vpLoopCandKFs = pKF->mvpLoopCandKFs;
|
|
||||||
if(!vpLoopCandKFs.empty())
|
|
||||||
{
|
|
||||||
for(vector<KeyFrame*>::const_iterator vit=vpLoopCandKFs.begin(), vend=vpLoopCandKFs.end(); vit!=vend; vit++)
|
|
||||||
{
|
|
||||||
cv::Mat Ow2 = (*vit)->GetCameraCenter();
|
|
||||||
glVertex3f(Ow.at<float>(0),Ow.at<float>(1),Ow.at<float>(2));
|
|
||||||
glVertex3f(Ow2.at<float>(0),Ow2.at<float>(1),Ow2.at<float>(2));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const vector<KeyFrame*> vpMergeCandKFs = pKF->mvpMergeCandKFs;
|
|
||||||
if(!vpMergeCandKFs.empty())
|
|
||||||
{
|
|
||||||
for(vector<KeyFrame*>::const_iterator vit=vpMergeCandKFs.begin(), vend=vpMergeCandKFs.end(); vit!=vend; vit++)
|
|
||||||
{
|
|
||||||
cv::Mat Ow2 = (*vit)->GetCameraCenter();
|
|
||||||
glVertex3f(Ow.at<float>(0),Ow.at<float>(1),Ow.at<float>(2));
|
|
||||||
glVertex3f(Ow2.at<float>(0),Ow2.at<float>(1),Ow2.at<float>(2));
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
glEnd();
|
glEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,7 +228,6 @@ void MapDrawer::DrawKeyFrames(const bool bDrawKF, const bool bDrawGraph, const b
|
||||||
glColor4f(0.0f,1.0f,0.0f,0.6f);
|
glColor4f(0.0f,1.0f,0.0f,0.6f);
|
||||||
glBegin(GL_LINES);
|
glBegin(GL_LINES);
|
||||||
|
|
||||||
// cout << "-----------------Draw graph-----------------" << endl;
|
|
||||||
for(size_t i=0; i<vpKFs.size(); i++)
|
for(size_t i=0; i<vpKFs.size(); i++)
|
||||||
{
|
{
|
||||||
// Covisibility Graph
|
// Covisibility Graph
|
||||||
|
@ -353,7 +322,6 @@ void MapDrawer::DrawKeyFrames(const bool bDrawKF, const bool bDrawGraph, const b
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glLineWidth(mKeyFrameLineWidth);
|
glLineWidth(mKeyFrameLineWidth);
|
||||||
//glColor3f(0.0f,0.0f,1.0f);
|
|
||||||
glColor3f(mfFrameColors[index_color][0],mfFrameColors[index_color][1],mfFrameColors[index_color][2]);
|
glColor3f(mfFrameColors[index_color][0],mfFrameColors[index_color][1],mfFrameColors[index_color][2]);
|
||||||
glBegin(GL_LINES);
|
glBegin(GL_LINES);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,9 @@ MapPoint::MapPoint(const cv::Mat &Pos, KeyFrame *pRefKF, Map* pMap):
|
||||||
mnOriginMapId(pMap->GetId())
|
mnOriginMapId(pMap->GetId())
|
||||||
{
|
{
|
||||||
Pos.copyTo(mWorldPos);
|
Pos.copyTo(mWorldPos);
|
||||||
|
mWorldPosx = cv::Matx31f(Pos.at<float>(0), Pos.at<float>(1), Pos.at<float>(2));
|
||||||
mNormalVector = cv::Mat::zeros(3,1,CV_32F);
|
mNormalVector = cv::Mat::zeros(3,1,CV_32F);
|
||||||
|
mNormalVectorx = cv::Matx31f::zeros();
|
||||||
|
|
||||||
mbTrackInViewR = false;
|
mbTrackInViewR = false;
|
||||||
mbTrackInView = false;
|
mbTrackInView = false;
|
||||||
|
@ -67,6 +69,7 @@ MapPoint::MapPoint(const double invDepth, cv::Point2f uv_init, KeyFrame* pRefKF,
|
||||||
mpHostKF = pHostKF;
|
mpHostKF = pHostKF;
|
||||||
|
|
||||||
mNormalVector = cv::Mat::zeros(3,1,CV_32F);
|
mNormalVector = cv::Mat::zeros(3,1,CV_32F);
|
||||||
|
mNormalVectorx = cv::Matx31f::zeros();
|
||||||
|
|
||||||
// Worldpos is not set
|
// Worldpos is not set
|
||||||
// MapPoints can be created from Tracking and Local Mapping. This mutex avoid conflicts with id.
|
// MapPoints can be created from Tracking and Local Mapping. This mutex avoid conflicts with id.
|
||||||
|
@ -81,6 +84,8 @@ MapPoint::MapPoint(const cv::Mat &Pos, Map* pMap, Frame* pFrame, const int &idxF
|
||||||
mnFound(1), mbBad(false), mpReplaced(NULL), mpMap(pMap), mnOriginMapId(pMap->GetId())
|
mnFound(1), mbBad(false), mpReplaced(NULL), mpMap(pMap), mnOriginMapId(pMap->GetId())
|
||||||
{
|
{
|
||||||
Pos.copyTo(mWorldPos);
|
Pos.copyTo(mWorldPos);
|
||||||
|
mWorldPosx = cv::Matx31f(Pos.at<float>(0), Pos.at<float>(1), Pos.at<float>(2));
|
||||||
|
|
||||||
cv::Mat Ow;
|
cv::Mat Ow;
|
||||||
if(pFrame -> Nleft == -1 || idxF < pFrame -> Nleft){
|
if(pFrame -> Nleft == -1 || idxF < pFrame -> Nleft){
|
||||||
Ow = pFrame->GetCameraCenter();
|
Ow = pFrame->GetCameraCenter();
|
||||||
|
@ -94,6 +99,8 @@ MapPoint::MapPoint(const cv::Mat &Pos, Map* pMap, Frame* pFrame, const int &idxF
|
||||||
}
|
}
|
||||||
mNormalVector = mWorldPos - Ow;
|
mNormalVector = mWorldPos - Ow;
|
||||||
mNormalVector = mNormalVector/cv::norm(mNormalVector);
|
mNormalVector = mNormalVector/cv::norm(mNormalVector);
|
||||||
|
mNormalVectorx = cv::Matx31f(mNormalVector.at<float>(0), mNormalVector.at<float>(1), mNormalVector.at<float>(2));
|
||||||
|
|
||||||
|
|
||||||
cv::Mat PC = Pos - Ow;
|
cv::Mat PC = Pos - Ow;
|
||||||
const float dist = cv::norm(PC);
|
const float dist = cv::norm(PC);
|
||||||
|
@ -118,6 +125,7 @@ void MapPoint::SetWorldPos(const cv::Mat &Pos)
|
||||||
unique_lock<mutex> lock2(mGlobalMutex);
|
unique_lock<mutex> lock2(mGlobalMutex);
|
||||||
unique_lock<mutex> lock(mMutexPos);
|
unique_lock<mutex> lock(mMutexPos);
|
||||||
Pos.copyTo(mWorldPos);
|
Pos.copyTo(mWorldPos);
|
||||||
|
mWorldPosx = cv::Matx31f(Pos.at<float>(0), Pos.at<float>(1), Pos.at<float>(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::Mat MapPoint::GetWorldPos()
|
cv::Mat MapPoint::GetWorldPos()
|
||||||
|
@ -132,6 +140,18 @@ cv::Mat MapPoint::GetNormal()
|
||||||
return mNormalVector.clone();
|
return mNormalVector.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cv::Matx31f MapPoint::GetWorldPos2()
|
||||||
|
{
|
||||||
|
unique_lock<mutex> lock(mMutexPos);
|
||||||
|
return mWorldPosx;
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Matx31f MapPoint::GetNormal2()
|
||||||
|
{
|
||||||
|
unique_lock<mutex> lock(mMutexPos);
|
||||||
|
return mNormalVectorx;
|
||||||
|
}
|
||||||
|
|
||||||
KeyFrame* MapPoint::GetReferenceKeyFrame()
|
KeyFrame* MapPoint::GetReferenceKeyFrame()
|
||||||
{
|
{
|
||||||
unique_lock<mutex> lock(mMutexFeatures);
|
unique_lock<mutex> lock(mMutexFeatures);
|
||||||
|
@ -184,7 +204,6 @@ void MapPoint::EraseObservation(KeyFrame* pKF)
|
||||||
// 查找这个要删除的观测,根据单目和双目类型的不同从其中删除当前地图点的被观测次数
|
// 查找这个要删除的观测,根据单目和双目类型的不同从其中删除当前地图点的被观测次数
|
||||||
if(mObservations.count(pKF))
|
if(mObservations.count(pKF))
|
||||||
{
|
{
|
||||||
//int idx = mObservations[pKF];
|
|
||||||
tuple<int,int> indexes = mObservations[pKF];
|
tuple<int,int> indexes = mObservations[pKF];
|
||||||
int leftIndex = get<0>(indexes), rightIndex = get<1>(indexes);
|
int leftIndex = get<0>(indexes), rightIndex = get<1>(indexes);
|
||||||
|
|
||||||
|
@ -566,6 +585,7 @@ void MapPoint::UpdateNormalAndDepth()
|
||||||
mfMaxDistance = dist*levelScaleFactor; // 观测到该点的距离上限
|
mfMaxDistance = dist*levelScaleFactor; // 观测到该点的距离上限
|
||||||
mfMinDistance = mfMaxDistance/pRefKF->mvScaleFactors[nLevels-1]; // 观测到该点的距离下限
|
mfMinDistance = mfMaxDistance/pRefKF->mvScaleFactors[nLevels-1]; // 观测到该点的距离下限
|
||||||
mNormalVector = normal/n; // 获得地图点平均的观测方向
|
mNormalVector = normal/n; // 获得地图点平均的观测方向
|
||||||
|
mNormalVectorx = cv::Matx31f(mNormalVector.at<float>(0), mNormalVector.at<float>(1), mNormalVector.at<float>(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,6 +593,7 @@ void MapPoint::SetNormalVector(cv::Mat& normal)
|
||||||
{
|
{
|
||||||
unique_lock<mutex> lock3(mMutexPos);
|
unique_lock<mutex> lock3(mMutexPos);
|
||||||
mNormalVector = normal;
|
mNormalVector = normal;
|
||||||
|
mNormalVectorx = cv::Matx31f(mNormalVector.at<float>(0), mNormalVector.at<float>(1), mNormalVector.at<float>(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
float MapPoint::GetMinDistanceInvariance()
|
float MapPoint::GetMinDistanceInvariance()
|
||||||
|
@ -646,18 +667,6 @@ int MapPoint::PredictScale(const float ¤tDist, Frame* pF)
|
||||||
return nScale;
|
return nScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapPoint::PrintObservations()
|
|
||||||
{
|
|
||||||
cout << "MP_OBS: MP " << mnId << endl;
|
|
||||||
for(map<KeyFrame*,tuple<int,int>>::iterator mit=mObservations.begin(), mend=mObservations.end(); mit!=mend; mit++)
|
|
||||||
{
|
|
||||||
KeyFrame* pKFi = mit->first;
|
|
||||||
tuple<int,int> indexes = mit->second;
|
|
||||||
int leftIndex = get<0>(indexes), rightIndex = get<1>(indexes);
|
|
||||||
cout << "--OBS in KF " << pKFi->mnId << " in map " << pKFi->GetMap()->GetId() << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Map* MapPoint::GetMap()
|
Map* MapPoint::GetMap()
|
||||||
{
|
{
|
||||||
unique_lock<mutex> lock(mMutexMap);
|
unique_lock<mutex> lock(mMutexMap);
|
||||||
|
@ -670,66 +679,4 @@ void MapPoint::UpdateMap(Map* pMap)
|
||||||
mpMap = pMap;
|
mpMap = pMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapPoint::PreSave(set<KeyFrame*>& spKF,set<MapPoint*>& spMP)
|
|
||||||
{
|
|
||||||
mBackupReplacedId = -1;
|
|
||||||
if(mpReplaced && spMP.find(mpReplaced) != spMP.end())
|
|
||||||
mBackupReplacedId = mpReplaced->mnId;
|
|
||||||
|
|
||||||
mBackupObservationsId1.clear();
|
|
||||||
mBackupObservationsId2.clear();
|
|
||||||
// Save the id and position in each KF who view it
|
|
||||||
for(std::map<KeyFrame*,std::tuple<int,int> >::const_iterator it = mObservations.begin(), end = mObservations.end(); it != end; ++it)
|
|
||||||
{
|
|
||||||
KeyFrame* pKFi = it->first;
|
|
||||||
if(spKF.find(pKFi) != spKF.end())
|
|
||||||
{
|
|
||||||
mBackupObservationsId1[it->first->mnId] = get<0>(it->second);
|
|
||||||
mBackupObservationsId2[it->first->mnId] = get<1>(it->second);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
EraseObservation(pKFi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the id of the reference KF
|
|
||||||
if(spKF.find(mpRefKF) != spKF.end())
|
|
||||||
{
|
|
||||||
mBackupRefKFId = mpRefKF->mnId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MapPoint::PostLoad(map<long unsigned int, KeyFrame*>& mpKFid, map<long unsigned int, MapPoint*>& mpMPid)
|
|
||||||
{
|
|
||||||
mpRefKF = mpKFid[mBackupRefKFId];
|
|
||||||
if(!mpRefKF)
|
|
||||||
{
|
|
||||||
cout << "MP without KF reference " << mBackupRefKFId << "; Num obs: " << nObs << endl;
|
|
||||||
}
|
|
||||||
mpReplaced = static_cast<MapPoint*>(NULL);
|
|
||||||
if(mBackupReplacedId>=0)
|
|
||||||
{
|
|
||||||
map<long unsigned int, MapPoint*>::iterator it = mpMPid.find(mBackupReplacedId);
|
|
||||||
if (it != mpMPid.end())
|
|
||||||
mpReplaced = it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
mObservations.clear();
|
|
||||||
|
|
||||||
for(map<long unsigned int, int>::const_iterator it = mBackupObservationsId1.begin(), end = mBackupObservationsId1.end(); it != end; ++it)
|
|
||||||
{
|
|
||||||
KeyFrame* pKFi = mpKFid[it->first];
|
|
||||||
map<long unsigned int, int>::const_iterator it2 = mBackupObservationsId2.find(it->first);
|
|
||||||
std::tuple<int, int> indexes = tuple<int,int>(it->second,it2->second);
|
|
||||||
if(pKFi)
|
|
||||||
{
|
|
||||||
mObservations[pKFi] = indexes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mBackupObservationsId1.clear();
|
|
||||||
mBackupObservationsId2.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
} //namespace ORB_SLAM
|
} //namespace ORB_SLAM
|
||||||
|
|
|
@ -1043,7 +1043,7 @@ void ORBextractor::ComputeKeyPointsOctTree(
|
||||||
allKeypoints.resize(nlevels);
|
allKeypoints.resize(nlevels);
|
||||||
|
|
||||||
//图像cell的尺寸,是个正方形,可以理解为边长in像素坐标
|
//图像cell的尺寸,是个正方形,可以理解为边长in像素坐标
|
||||||
const float W = 30;
|
const float W = 35;
|
||||||
|
|
||||||
// 对每一层图像做处理
|
// 对每一层图像做处理
|
||||||
//遍历所有图像
|
//遍历所有图像
|
||||||
|
|
|
@ -1385,6 +1385,250 @@ int ORBmatcher::SearchForTriangulation(KeyFrame *pKF1, KeyFrame *pKF2, cv::Mat F
|
||||||
return nmatches;
|
return nmatches;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ORBmatcher::SearchForTriangulation_(KeyFrame *pKF1, KeyFrame *pKF2, cv::Matx33f F12,
|
||||||
|
vector<pair<size_t, size_t> > &vMatchedPairs, const bool bOnlyStereo, const bool bCoarse)
|
||||||
|
{
|
||||||
|
const DBoW2::FeatureVector &vFeatVec1 = pKF1->mFeatVec;
|
||||||
|
const DBoW2::FeatureVector &vFeatVec2 = pKF2->mFeatVec;
|
||||||
|
|
||||||
|
//Compute epipole in second image
|
||||||
|
auto Cw = pKF1->GetCameraCenter_();
|
||||||
|
auto R2w = pKF2->GetRotation_();
|
||||||
|
auto t2w = pKF2->GetTranslation_();
|
||||||
|
auto C2 = R2w*Cw+t2w;
|
||||||
|
|
||||||
|
cv::Point2f ep = pKF2->mpCamera->project(C2);
|
||||||
|
|
||||||
|
auto R1w = pKF1->GetRotation_();
|
||||||
|
auto t1w = pKF1->GetTranslation_();
|
||||||
|
|
||||||
|
cv::Matx33f R12;
|
||||||
|
cv::Matx31f t12;
|
||||||
|
|
||||||
|
cv::Matx33f Rll,Rlr,Rrl,Rrr;
|
||||||
|
cv::Matx31f tll,tlr,trl,trr;
|
||||||
|
|
||||||
|
GeometricCamera* pCamera1 = pKF1->mpCamera, *pCamera2 = pKF2->mpCamera;
|
||||||
|
|
||||||
|
if(!pKF1->mpCamera2 && !pKF2->mpCamera2){
|
||||||
|
R12 = R1w*R2w.t();
|
||||||
|
t12 = -R1w*R2w.t()*t2w+t1w;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Rll = pKF1->GetRotation_() * pKF2->GetRotation_().t();
|
||||||
|
Rlr = pKF1->GetRotation_() * pKF2->GetRightRotation_().t();
|
||||||
|
Rrl = pKF1->GetRightRotation_() * pKF2->GetRotation_().t();
|
||||||
|
Rrr = pKF1->GetRightRotation_() * pKF2->GetRightRotation_().t();
|
||||||
|
|
||||||
|
tll = pKF1->GetRotation_() * (-pKF2->GetRotation_().t() * pKF2->GetTranslation_()) + pKF1->GetTranslation_();
|
||||||
|
tlr = pKF1->GetRotation_() * (-pKF2->GetRightRotation_().t() * pKF2->GetRightTranslation_()) + pKF1->GetTranslation_();
|
||||||
|
trl = pKF1->GetRightRotation_() * (-pKF2->GetRotation_().t() * pKF2->GetTranslation_()) + pKF1->GetRightTranslation_();
|
||||||
|
trr = pKF1->GetRightRotation_() * (-pKF2->GetRightRotation_().t() * pKF2->GetRightTranslation_()) + pKF1->GetRightTranslation_();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find matches between not tracked keypoints
|
||||||
|
// Matching speed-up by ORB Vocabulary
|
||||||
|
// Compare only ORB that share the same node
|
||||||
|
|
||||||
|
int nmatches=0;
|
||||||
|
vector<bool> vbMatched2(pKF2->N,false);
|
||||||
|
vector<int> vMatches12(pKF1->N,-1);
|
||||||
|
|
||||||
|
vector<int> rotHist[HISTO_LENGTH];
|
||||||
|
for(int i=0;i<HISTO_LENGTH;i++)
|
||||||
|
rotHist[i].reserve(500);
|
||||||
|
|
||||||
|
const float factor = 1.0f/HISTO_LENGTH;
|
||||||
|
|
||||||
|
DBoW2::FeatureVector::const_iterator f1it = vFeatVec1.begin();
|
||||||
|
DBoW2::FeatureVector::const_iterator f2it = vFeatVec2.begin();
|
||||||
|
DBoW2::FeatureVector::const_iterator f1end = vFeatVec1.end();
|
||||||
|
DBoW2::FeatureVector::const_iterator f2end = vFeatVec2.end();
|
||||||
|
|
||||||
|
while(f1it!=f1end && f2it!=f2end)
|
||||||
|
{
|
||||||
|
if(f1it->first == f2it->first)
|
||||||
|
{
|
||||||
|
for(size_t i1=0, iend1=f1it->second.size(); i1<iend1; i1++)
|
||||||
|
{
|
||||||
|
const size_t idx1 = f1it->second[i1];
|
||||||
|
|
||||||
|
MapPoint* pMP1 = pKF1->GetMapPoint(idx1);
|
||||||
|
|
||||||
|
// If there is already a MapPoint skip
|
||||||
|
if(pMP1)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool bStereo1 = (!pKF1->mpCamera2 && pKF1->mvuRight[idx1]>=0);
|
||||||
|
|
||||||
|
if(bOnlyStereo)
|
||||||
|
if(!bStereo1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
const cv::KeyPoint &kp1 = (pKF1 -> NLeft == -1) ? pKF1->mvKeysUn[idx1]
|
||||||
|
: (idx1 < pKF1 -> NLeft) ? pKF1 -> mvKeys[idx1]
|
||||||
|
: pKF1 -> mvKeysRight[idx1 - pKF1 -> NLeft];
|
||||||
|
|
||||||
|
const bool bRight1 = (pKF1 -> NLeft == -1 || idx1 < pKF1 -> NLeft) ? false
|
||||||
|
: true;
|
||||||
|
//if(bRight1) continue;
|
||||||
|
const cv::Mat &d1 = pKF1->mDescriptors.row(idx1);
|
||||||
|
|
||||||
|
int bestDist = TH_LOW;
|
||||||
|
int bestIdx2 = -1;
|
||||||
|
|
||||||
|
for(size_t i2=0, iend2=f2it->second.size(); i2<iend2; i2++)
|
||||||
|
{
|
||||||
|
size_t idx2 = f2it->second[i2];
|
||||||
|
|
||||||
|
MapPoint* pMP2 = pKF2->GetMapPoint(idx2);
|
||||||
|
|
||||||
|
// If we have already matched or there is a MapPoint skip
|
||||||
|
if(vbMatched2[idx2] || pMP2)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const bool bStereo2 = (!pKF2->mpCamera2 && pKF2->mvuRight[idx2]>=0);
|
||||||
|
|
||||||
|
if(bOnlyStereo)
|
||||||
|
if(!bStereo2)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const cv::Mat &d2 = pKF2->mDescriptors.row(idx2);
|
||||||
|
|
||||||
|
const int dist = DescriptorDistance(d1,d2);
|
||||||
|
|
||||||
|
if(dist>TH_LOW || dist>bestDist)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const cv::KeyPoint &kp2 = (pKF2 -> NLeft == -1) ? pKF2->mvKeysUn[idx2]
|
||||||
|
: (idx2 < pKF2 -> NLeft) ? pKF2 -> mvKeys[idx2]
|
||||||
|
: pKF2 -> mvKeysRight[idx2 - pKF2 -> NLeft];
|
||||||
|
const bool bRight2 = (pKF2 -> NLeft == -1 || idx2 < pKF2 -> NLeft) ? false
|
||||||
|
: true;
|
||||||
|
|
||||||
|
if(!bStereo1 && !bStereo2 && !pKF1->mpCamera2)
|
||||||
|
{
|
||||||
|
const float distex = ep.x-kp2.pt.x;
|
||||||
|
const float distey = ep.y-kp2.pt.y;
|
||||||
|
if(distex*distex+distey*distey<100*pKF2->mvScaleFactors[kp2.octave])
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pKF1->mpCamera2 && pKF2->mpCamera2){
|
||||||
|
if(bRight1 && bRight2){
|
||||||
|
R12 = Rrr;
|
||||||
|
t12 = trr;
|
||||||
|
|
||||||
|
pCamera1 = pKF1->mpCamera2;
|
||||||
|
pCamera2 = pKF2->mpCamera2;
|
||||||
|
}
|
||||||
|
else if(bRight1 && !bRight2){
|
||||||
|
R12 = Rrl;
|
||||||
|
t12 = trl;
|
||||||
|
|
||||||
|
pCamera1 = pKF1->mpCamera2;
|
||||||
|
pCamera2 = pKF2->mpCamera;
|
||||||
|
}
|
||||||
|
else if(!bRight1 && bRight2){
|
||||||
|
R12 = Rlr;
|
||||||
|
t12 = tlr;
|
||||||
|
|
||||||
|
pCamera1 = pKF1->mpCamera;
|
||||||
|
pCamera2 = pKF2->mpCamera2;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
R12 = Rll;
|
||||||
|
t12 = tll;
|
||||||
|
|
||||||
|
pCamera1 = pKF1->mpCamera;
|
||||||
|
pCamera2 = pKF2->mpCamera;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(pCamera1->epipolarConstrain_(pCamera2,kp1,kp2,R12,t12,pKF1->mvLevelSigma2[kp1.octave],pKF2->mvLevelSigma2[kp2.octave])||bCoarse) // MODIFICATION_2
|
||||||
|
{
|
||||||
|
bestIdx2 = idx2;
|
||||||
|
bestDist = dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bestIdx2>=0)
|
||||||
|
{
|
||||||
|
const cv::KeyPoint &kp2 = (pKF2 -> NLeft == -1) ? pKF2->mvKeysUn[bestIdx2]
|
||||||
|
: (bestIdx2 < pKF2 -> NLeft) ? pKF2 -> mvKeys[bestIdx2]
|
||||||
|
: pKF2 -> mvKeysRight[bestIdx2 - pKF2 -> NLeft];
|
||||||
|
vMatches12[idx1]=bestIdx2;
|
||||||
|
nmatches++;
|
||||||
|
|
||||||
|
if(mbCheckOrientation)
|
||||||
|
{
|
||||||
|
float rot = kp1.angle-kp2.angle;
|
||||||
|
if(rot<0.0)
|
||||||
|
rot+=360.0f;
|
||||||
|
int bin = round(rot*factor);
|
||||||
|
if(bin==HISTO_LENGTH)
|
||||||
|
bin=0;
|
||||||
|
assert(bin>=0 && bin<HISTO_LENGTH);
|
||||||
|
rotHist[bin].push_back(idx1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f1it++;
|
||||||
|
f2it++;
|
||||||
|
}
|
||||||
|
else if(f1it->first < f2it->first)
|
||||||
|
{
|
||||||
|
f1it = vFeatVec1.lower_bound(f2it->first);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
f2it = vFeatVec2.lower_bound(f1it->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mbCheckOrientation)
|
||||||
|
{
|
||||||
|
int ind1=-1;
|
||||||
|
int ind2=-1;
|
||||||
|
int ind3=-1;
|
||||||
|
|
||||||
|
ComputeThreeMaxima(rotHist,HISTO_LENGTH,ind1,ind2,ind3);
|
||||||
|
|
||||||
|
for(int i=0; i<HISTO_LENGTH; i++)
|
||||||
|
{
|
||||||
|
if(i==ind1 || i==ind2 || i==ind3)
|
||||||
|
continue;
|
||||||
|
for(size_t j=0, jend=rotHist[i].size(); j<jend; j++)
|
||||||
|
{
|
||||||
|
vMatches12[rotHist[i][j]]=-1;
|
||||||
|
nmatches--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
vMatchedPairs.clear();
|
||||||
|
vMatchedPairs.reserve(nmatches);
|
||||||
|
|
||||||
|
for(size_t i=0, iend=vMatches12.size(); i<iend; i++)
|
||||||
|
{
|
||||||
|
if(vMatches12[i]<0)
|
||||||
|
continue;
|
||||||
|
vMatchedPairs.push_back(make_pair(i,vMatches12[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return nmatches;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int ORBmatcher::SearchForTriangulation(KeyFrame *pKF1, KeyFrame *pKF2, cv::Mat F12,
|
int ORBmatcher::SearchForTriangulation(KeyFrame *pKF1, KeyFrame *pKF2, cv::Mat F12,
|
||||||
vector<pair<size_t, size_t> > &vMatchedPairs, const bool bOnlyStereo, vector<cv::Mat> &vMatchedPoints)
|
vector<pair<size_t, size_t> > &vMatchedPairs, const bool bOnlyStereo, vector<cv::Mat> &vMatchedPoints)
|
||||||
{
|
{
|
||||||
|
@ -1620,8 +1864,6 @@ int ORBmatcher::Fuse(KeyFrame *pKF, const vector<MapPoint *> &vpMapPoints, const
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 地图点无效 或 已经是该帧的地图点(无需融合),跳过
|
// 地图点无效 或 已经是该帧的地图点(无需融合),跳过
|
||||||
/*if(pMP->isBad() || pMP->IsInKeyFrame(pKF))
|
|
||||||
continue;*/
|
|
||||||
if(pMP->isBad())
|
if(pMP->isBad())
|
||||||
{
|
{
|
||||||
count_bad++;
|
count_bad++;
|
||||||
|
@ -1792,16 +2034,6 @@ int ORBmatcher::Fuse(KeyFrame *pKF, const vector<MapPoint *> &vpMapPoints, const
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*cout << "count_notMP = " << count_notMP << endl;
|
|
||||||
cout << "count_bad = " << count_bad << endl;
|
|
||||||
cout << "count_isinKF = " << count_isinKF << endl;
|
|
||||||
cout << "count_negdepth = " << count_negdepth << endl;
|
|
||||||
cout << "count_notinim = " << count_notinim << endl;
|
|
||||||
cout << "count_dist = " << count_dist << endl;
|
|
||||||
cout << "count_normal = " << count_normal << endl;
|
|
||||||
cout << "count_notidx = " << count_notidx << endl;
|
|
||||||
cout << "count_thcheck = " << count_thcheck << endl;
|
|
||||||
cout << "tot fused points: " << nFused << endl;*/
|
|
||||||
return nFused;
|
return nFused;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
780
src/Optimizer.cc
780
src/Optimizer.cc
File diff suppressed because it is too large
Load Diff
|
@ -381,7 +381,7 @@ cv::Mat Sim3Solver::find(vector<bool> &vbInliers12, int &nInliers)
|
||||||
void Sim3Solver::ComputeCentroid(cv::Mat &P, cv::Mat &Pr, cv::Mat &C)
|
void Sim3Solver::ComputeCentroid(cv::Mat &P, cv::Mat &Pr, cv::Mat &C)
|
||||||
{
|
{
|
||||||
// 矩阵P每一行求和,结果存在C。这两句也可以使用CV_REDUCE_AVG选项来实现
|
// 矩阵P每一行求和,结果存在C。这两句也可以使用CV_REDUCE_AVG选项来实现
|
||||||
cv::reduce(P,C,1,CV_REDUCE_SUM);
|
cv::reduce(P,C,1,cv::REDUCE_SUM);
|
||||||
C = C/P.cols;// 求平均
|
C = C/P.cols;// 求平均
|
||||||
|
|
||||||
for(int i=0; i<P.cols; i++)
|
for(int i=0; i<P.cols; i++)
|
||||||
|
@ -458,7 +458,7 @@ void Sim3Solver::ComputeSim3(cv::Mat &P1, cv::Mat &P2)
|
||||||
double ang=atan2(norm(vec),evec.at<float>(0,0));
|
double ang=atan2(norm(vec),evec.at<float>(0,0));
|
||||||
|
|
||||||
// vec/norm(vec)归一化得到归一化后的旋转向量,然后乘上角度得到包含了旋转轴和旋转角信息的旋转向量vec
|
// vec/norm(vec)归一化得到归一化后的旋转向量,然后乘上角度得到包含了旋转轴和旋转角信息的旋转向量vec
|
||||||
vec = 2*ang*vec/norm(vec); //Angle-axis x. quaternion angle is the half
|
vec = 2*ang*vec/norm(vec); //Angle-axis representation. quaternion angle is the half
|
||||||
|
|
||||||
mR12i.create(3,3,P1.type());
|
mR12i.create(3,3,P1.type());
|
||||||
// 旋转向量(轴角)转换为旋转矩阵
|
// 旋转向量(轴角)转换为旋转矩阵
|
||||||
|
|
318
src/System.cc
318
src/System.cc
|
@ -47,10 +47,10 @@ System::System(const string &strVocFile, //词袋文件所在路
|
||||||
const string &strLoadingFile //看起来作者貌似想加地图重载功能的一个参数
|
const string &strLoadingFile //看起来作者貌似想加地图重载功能的一个参数
|
||||||
):
|
):
|
||||||
mSensor(sensor), //初始化传感器类型
|
mSensor(sensor), //初始化传感器类型
|
||||||
mpViewer(static_cast<Viewer*>(NULL)), // ?空。。。对象指针? TODO
|
mpViewer(static_cast<Viewer*>(NULL)), // 空对象指针
|
||||||
mbReset(false), mbResetActiveMap(false),// ?重新设置ActiveMap
|
mbReset(false), mbResetActiveMap(false),// ?重新设置ActiveMap
|
||||||
mbActivateLocalizationMode(false), // ?是否开启局部定位功能开关
|
mbActivateLocalizationMode(false), // 是否开启局部定位功能开关
|
||||||
mbDeactivateLocalizationMode(false) // ?没有这个模式转换标志
|
mbDeactivateLocalizationMode(false) //
|
||||||
{
|
{
|
||||||
// Output welcome message
|
// Output welcome message
|
||||||
cout << endl <<
|
cout << endl <<
|
||||||
|
@ -84,7 +84,7 @@ System::System(const string &strVocFile, //词袋文件所在路
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ?ORBSLAM3新加的多地图管理功能,这里好像是加载Atlas标识符
|
// ORBSLAM3新加的多地图管理功能,这里加载Atlas标识符
|
||||||
bool loadedAtlas = false;
|
bool loadedAtlas = false;
|
||||||
|
|
||||||
//----
|
//----
|
||||||
|
@ -113,74 +113,6 @@ System::System(const string &strVocFile, //词袋文件所在路
|
||||||
// Step 5 创建多地图,参数0表示初始化关键帧id为0
|
// Step 5 创建多地图,参数0表示初始化关键帧id为0
|
||||||
mpAtlas = new Atlas(0);
|
mpAtlas = new Atlas(0);
|
||||||
|
|
||||||
// 下面注释看起来作者貌似想加地图重载功能,期待期待
|
|
||||||
/*if(strLoadingFile.empty())
|
|
||||||
{
|
|
||||||
//Load ORB Vocabulary
|
|
||||||
cout << endl << "Loading ORB Vocabulary. This could take a while..." << endl;
|
|
||||||
|
|
||||||
mpVocabulary = new ORBVocabulary();
|
|
||||||
bool bVocLoad = mpVocabulary->loadFromTextFile(strVocFile);
|
|
||||||
if(!bVocLoad)
|
|
||||||
{
|
|
||||||
cerr << "Wrong path to vocabulary. " << endl;
|
|
||||||
cerr << "Falied to open at: " << strVocFile << endl;
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
cout << "Vocabulary loaded!" << endl << endl;
|
|
||||||
|
|
||||||
//Create KeyFrame Database
|
|
||||||
mpKeyFrameDatabase = new KeyFrameDatabase(*mpVocabulary);
|
|
||||||
|
|
||||||
//Create the Atlas
|
|
||||||
//mpMap = new Map();
|
|
||||||
mpAtlas = new Atlas(0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Load ORB Vocabulary
|
|
||||||
cout << endl << "Loading ORB Vocabulary. This could take a while..." << endl;
|
|
||||||
|
|
||||||
mpVocabulary = new ORBVocabulary();
|
|
||||||
bool bVocLoad = mpVocabulary->loadFromTextFile(strVocFile);
|
|
||||||
if(!bVocLoad)
|
|
||||||
{
|
|
||||||
cerr << "Wrong path to vocabulary. " << endl;
|
|
||||||
cerr << "Falied to open at: " << strVocFile << endl;
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
cout << "Vocabulary loaded!" << endl << endl;
|
|
||||||
|
|
||||||
cout << "Load File" << endl;
|
|
||||||
|
|
||||||
// Load the file with an earlier session
|
|
||||||
//clock_t start = clock();
|
|
||||||
bool isRead = LoadAtlas(strLoadingFile,BINARY_FILE);
|
|
||||||
|
|
||||||
if(!isRead)
|
|
||||||
{
|
|
||||||
cout << "Error to load the file, please try with other session file or vocabulary file" << endl;
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
mpKeyFrameDatabase = new KeyFrameDatabase(*mpVocabulary);
|
|
||||||
|
|
||||||
mpAtlas->SetKeyFrameDababase(mpKeyFrameDatabase);
|
|
||||||
mpAtlas->SetORBVocabulary(mpVocabulary);
|
|
||||||
mpAtlas->PostLoad();
|
|
||||||
//cout << "KF in DB: " << mpKeyFrameDatabase->mnNumKFs << "; words: " << mpKeyFrameDatabase->mnNumWords << endl;
|
|
||||||
|
|
||||||
loadedAtlas = true;
|
|
||||||
|
|
||||||
mpAtlas->CreateNewMap();
|
|
||||||
|
|
||||||
//clock_t timeElapsed = clock() - start;
|
|
||||||
//unsigned msElapsed = timeElapsed / (CLOCKS_PER_SEC / 1000);
|
|
||||||
//cout << "Binary file read in " << msElapsed << " ms" << endl;
|
|
||||||
|
|
||||||
//usleep(10*1000*1000);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// 设置Atlas中的传感器类型
|
|
||||||
if (mSensor==IMU_STEREO || mSensor==IMU_MONOCULAR)
|
if (mSensor==IMU_STEREO || mSensor==IMU_MONOCULAR)
|
||||||
// ? 如果是有imu的传感器类型,将mbIsInertial设置为imu属性,以后的跟踪和预积分将和这个标志有关
|
// ? 如果是有imu的传感器类型,将mbIsInertial设置为imu属性,以后的跟踪和预积分将和这个标志有关
|
||||||
mpAtlas->SetInertialSensor();
|
mpAtlas->SetInertialSensor();
|
||||||
|
@ -203,8 +135,6 @@ System::System(const string &strVocFile, //词袋文件所在路
|
||||||
mpLocalMapper = new LocalMapping(this, mpAtlas, mSensor==MONOCULAR || mSensor==IMU_MONOCULAR, mSensor==IMU_MONOCULAR || mSensor==IMU_STEREO, strSequence);
|
mpLocalMapper = new LocalMapping(this, mpAtlas, mSensor==MONOCULAR || mSensor==IMU_MONOCULAR, mSensor==IMU_MONOCULAR || mSensor==IMU_STEREO, strSequence);
|
||||||
mptLocalMapping = new thread(&ORB_SLAM3::LocalMapping::Run,mpLocalMapper);
|
mptLocalMapping = new thread(&ORB_SLAM3::LocalMapping::Run,mpLocalMapper);
|
||||||
|
|
||||||
//initFr表示初始化帧的id,代码里设置为0
|
|
||||||
mpLocalMapper->mInitFr = initFr;
|
|
||||||
//设置最远3D地图点的深度值,如果超过阈值,说明可能三角化不太准确,丢弃
|
//设置最远3D地图点的深度值,如果超过阈值,说明可能三角化不太准确,丢弃
|
||||||
mpLocalMapper->mThFarPoints = fsSettings["thFarPoints"];
|
mpLocalMapper->mThFarPoints = fsSettings["thFarPoints"];
|
||||||
// ? 这里有个疑问,C++中浮点型跟0比较是否用精确?
|
// ? 这里有个疑问,C++中浮点型跟0比较是否用精确?
|
||||||
|
@ -302,11 +232,8 @@ cv::Mat System::TrackStereo(const cv::Mat &imLeft, const cv::Mat &imRight, const
|
||||||
for(size_t i_imu = 0; i_imu < vImuMeas.size(); i_imu++)
|
for(size_t i_imu = 0; i_imu < vImuMeas.size(); i_imu++)
|
||||||
mpTracker->GrabImuData(vImuMeas[i_imu]);
|
mpTracker->GrabImuData(vImuMeas[i_imu]);
|
||||||
|
|
||||||
// std::cout << "start GrabImageStereo" << std::endl;
|
|
||||||
cv::Mat Tcw = mpTracker->GrabImageStereo(imLeft,imRight,timestamp,filename);
|
cv::Mat Tcw = mpTracker->GrabImageStereo(imLeft,imRight,timestamp,filename);
|
||||||
|
|
||||||
// std::cout << "out grabber" << std::endl;
|
|
||||||
|
|
||||||
unique_lock<mutex> lock2(mMutexState);
|
unique_lock<mutex> lock2(mMutexState);
|
||||||
mTrackingState = mpTracker->mState;
|
mTrackingState = mpTracker->mState;
|
||||||
mTrackedMapPoints = mpTracker->mCurrentFrame.mvpMapPoints;
|
mTrackedMapPoints = mpTracker->mCurrentFrame.mvpMapPoints;
|
||||||
|
@ -518,6 +445,10 @@ void System::Shutdown()
|
||||||
|
|
||||||
if(mpViewer)
|
if(mpViewer)
|
||||||
pangolin::BindToContext("ORB-SLAM2: Map Viewer");
|
pangolin::BindToContext("ORB-SLAM2: Map Viewer");
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
mpTracker->PrintTimeStats();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -650,7 +581,6 @@ void System::SaveTrajectoryEuRoC(const string &filename)
|
||||||
|
|
||||||
ofstream f;
|
ofstream f;
|
||||||
f.open(filename.c_str());
|
f.open(filename.c_str());
|
||||||
// cout << "file open" << endl;
|
|
||||||
f << fixed;
|
f << fixed;
|
||||||
|
|
||||||
// Frame pose is stored relative to its reference keyframe (which is optimized by BA and pose graph).
|
// Frame pose is stored relative to its reference keyframe (which is optimized by BA and pose graph).
|
||||||
|
@ -663,56 +593,34 @@ void System::SaveTrajectoryEuRoC(const string &filename)
|
||||||
list<double>::iterator lT = mpTracker->mlFrameTimes.begin();
|
list<double>::iterator lT = mpTracker->mlFrameTimes.begin();
|
||||||
list<bool>::iterator lbL = mpTracker->mlbLost.begin();
|
list<bool>::iterator lbL = mpTracker->mlbLost.begin();
|
||||||
|
|
||||||
//cout << "size mlpReferences: " << mpTracker->mlpReferences.size() << endl;
|
|
||||||
//cout << "size mlRelativeFramePoses: " << mpTracker->mlRelativeFramePoses.size() << endl;
|
|
||||||
//cout << "size mpTracker->mlFrameTimes: " << mpTracker->mlFrameTimes.size() << endl;
|
|
||||||
//cout << "size mpTracker->mlbLost: " << mpTracker->mlbLost.size() << endl;
|
|
||||||
|
|
||||||
|
|
||||||
for(list<cv::Mat>::iterator lit=mpTracker->mlRelativeFramePoses.begin(),
|
for(list<cv::Mat>::iterator lit=mpTracker->mlRelativeFramePoses.begin(),
|
||||||
lend=mpTracker->mlRelativeFramePoses.end();lit!=lend;lit++, lRit++, lT++, lbL++)
|
lend=mpTracker->mlRelativeFramePoses.end();lit!=lend;lit++, lRit++, lT++, lbL++)
|
||||||
{
|
{
|
||||||
//cout << "1" << endl;
|
|
||||||
if(*lbL)
|
if(*lbL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
||||||
KeyFrame* pKF = *lRit;
|
KeyFrame* pKF = *lRit;
|
||||||
//cout << "KF: " << pKF->mnId << endl;
|
|
||||||
|
|
||||||
cv::Mat Trw = cv::Mat::eye(4,4,CV_32F);
|
cv::Mat Trw = cv::Mat::eye(4,4,CV_32F);
|
||||||
|
|
||||||
/*cout << "2" << endl;
|
|
||||||
cout << "KF id: " << pKF->mnId << endl;*/
|
|
||||||
|
|
||||||
// If the reference keyframe was culled, traverse the spanning tree to get a suitable keyframe.
|
// If the reference keyframe was culled, traverse the spanning tree to get a suitable keyframe.
|
||||||
if (!pKF)
|
if (!pKF)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//cout << "2.5" << endl;
|
|
||||||
|
|
||||||
while(pKF->isBad())
|
while(pKF->isBad())
|
||||||
{
|
{
|
||||||
//cout << " 2.bad" << endl;
|
|
||||||
Trw = Trw*pKF->mTcp;
|
Trw = Trw*pKF->mTcp;
|
||||||
pKF = pKF->GetParent();
|
pKF = pKF->GetParent();
|
||||||
//cout << "--Parent KF: " << pKF->mnId << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!pKF || pKF->GetMap() != pBiggerMap)
|
if(!pKF || pKF->GetMap() != pBiggerMap)
|
||||||
{
|
{
|
||||||
//cout << "--Parent KF is from another map" << endl;
|
|
||||||
/*if(pKF)
|
|
||||||
cout << "--Parent KF " << pKF->mnId << " is from another map " << pKF->GetMap()->GetId() << endl;*/
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//cout << "3" << endl;
|
|
||||||
|
|
||||||
Trw = Trw*pKF->GetPose()*Twb; // Tcp*Tpw*Twb0=Tcb0 where b0 is the new world reference
|
Trw = Trw*pKF->GetPose()*Twb; // Tcp*Tpw*Twb0=Tcb0 where b0 is the new world reference
|
||||||
|
|
||||||
// cout << "4" << endl;
|
|
||||||
|
|
||||||
if (mSensor == IMU_MONOCULAR || mSensor == IMU_STEREO)
|
if (mSensor == IMU_MONOCULAR || mSensor == IMU_STEREO)
|
||||||
{
|
{
|
||||||
cv::Mat Tbw = pKF->mImuCalib.Tbc*(*lit)*Trw;
|
cv::Mat Tbw = pKF->mImuCalib.Tbc*(*lit)*Trw;
|
||||||
|
@ -730,7 +638,6 @@ void System::SaveTrajectoryEuRoC(const string &filename)
|
||||||
f << setprecision(6) << 1e9*(*lT) << " " << setprecision(9) << twc.at<float>(0) << " " << twc.at<float>(1) << " " << twc.at<float>(2) << " " << q[0] << " " << q[1] << " " << q[2] << " " << q[3] << endl;
|
f << setprecision(6) << 1e9*(*lT) << " " << setprecision(9) << twc.at<float>(0) << " " << twc.at<float>(1) << " " << twc.at<float>(2) << " " << q[0] << " " << q[1] << " " << q[2] << " " << q[3] << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cout << "5" << endl;
|
|
||||||
}
|
}
|
||||||
//cout << "end saving trajectory" << endl;
|
//cout << "end saving trajectory" << endl;
|
||||||
f.close();
|
f.close();
|
||||||
|
@ -767,8 +674,6 @@ void System::SaveKeyFrameTrajectoryEuRoC(const string &filename)
|
||||||
{
|
{
|
||||||
KeyFrame* pKF = vpKFs[i];
|
KeyFrame* pKF = vpKFs[i];
|
||||||
|
|
||||||
// pKF->SetPose(pKF->GetPose()*Two);
|
|
||||||
|
|
||||||
if(pKF->isBad())
|
if(pKF->isBad())
|
||||||
continue;
|
continue;
|
||||||
if (mSensor == IMU_MONOCULAR || mSensor == IMU_STEREO)
|
if (mSensor == IMU_MONOCULAR || mSensor == IMU_STEREO)
|
||||||
|
@ -843,63 +748,6 @@ void System::SaveTrajectoryKITTI(const string &filename)
|
||||||
f.close();
|
f.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void System::SaveDebugData(const int &initIdx)
|
|
||||||
{
|
|
||||||
// 0. Save initialization trajectory
|
|
||||||
SaveTrajectoryEuRoC("init_FrameTrajectoy_" +to_string(mpLocalMapper->mInitSect)+ "_" + to_string(initIdx)+".txt");
|
|
||||||
|
|
||||||
// 1. Save scale
|
|
||||||
ofstream f;
|
|
||||||
f.open("init_Scale_" + to_string(mpLocalMapper->mInitSect) + ".txt", ios_base::app);
|
|
||||||
f << fixed;
|
|
||||||
f << mpLocalMapper->mScale << endl;
|
|
||||||
f.close();
|
|
||||||
|
|
||||||
// 2. Save gravity direction
|
|
||||||
f.open("init_GDir_" +to_string(mpLocalMapper->mInitSect)+ ".txt", ios_base::app);
|
|
||||||
f << fixed;
|
|
||||||
f << mpLocalMapper->mRwg(0,0) << "," << mpLocalMapper->mRwg(0,1) << "," << mpLocalMapper->mRwg(0,2) << endl;
|
|
||||||
f << mpLocalMapper->mRwg(1,0) << "," << mpLocalMapper->mRwg(1,1) << "," << mpLocalMapper->mRwg(1,2) << endl;
|
|
||||||
f << mpLocalMapper->mRwg(2,0) << "," << mpLocalMapper->mRwg(2,1) << "," << mpLocalMapper->mRwg(2,2) << endl;
|
|
||||||
f.close();
|
|
||||||
|
|
||||||
// 3. Save computational cost
|
|
||||||
f.open("init_CompCost_" +to_string(mpLocalMapper->mInitSect)+ ".txt", ios_base::app);
|
|
||||||
f << fixed;
|
|
||||||
f << mpLocalMapper->mCostTime << endl;
|
|
||||||
f.close();
|
|
||||||
|
|
||||||
// 4. Save biases
|
|
||||||
f.open("init_Biases_" +to_string(mpLocalMapper->mInitSect)+ ".txt", ios_base::app);
|
|
||||||
f << fixed;
|
|
||||||
f << mpLocalMapper->mbg(0) << "," << mpLocalMapper->mbg(1) << "," << mpLocalMapper->mbg(2) << endl;
|
|
||||||
f << mpLocalMapper->mba(0) << "," << mpLocalMapper->mba(1) << "," << mpLocalMapper->mba(2) << endl;
|
|
||||||
f.close();
|
|
||||||
|
|
||||||
// 5. Save covariance matrix
|
|
||||||
f.open("init_CovMatrix_" +to_string(mpLocalMapper->mInitSect)+ "_" +to_string(initIdx)+".txt", ios_base::app);
|
|
||||||
f << fixed;
|
|
||||||
for(int i=0; i<mpLocalMapper->mcovInertial.rows(); i++)
|
|
||||||
{
|
|
||||||
for(int j=0; j<mpLocalMapper->mcovInertial.cols(); j++)
|
|
||||||
{
|
|
||||||
if(j!=0)
|
|
||||||
f << ",";
|
|
||||||
f << setprecision(15) << mpLocalMapper->mcovInertial(i,j);
|
|
||||||
}
|
|
||||||
f << endl;
|
|
||||||
}
|
|
||||||
f.close();
|
|
||||||
|
|
||||||
// 6. Save initialization time
|
|
||||||
f.open("init_Time_" +to_string(mpLocalMapper->mInitSect)+ ".txt", ios_base::app);
|
|
||||||
f << fixed;
|
|
||||||
f << mpLocalMapper->mInitTime << endl;
|
|
||||||
f.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int System::GetTrackingState()
|
int System::GetTrackingState()
|
||||||
{
|
{
|
||||||
unique_lock<mutex> lock(mMutexState);
|
unique_lock<mutex> lock(mMutexState);
|
||||||
|
@ -933,7 +781,7 @@ bool System::isLost()
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((mpTracker->mState==Tracking::LOST)) //||(mpTracker->mState==Tracking::RECENTLY_LOST))
|
if ((mpTracker->mState==Tracking::LOST))
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
@ -960,154 +808,18 @@ void System::ChangeDataset()
|
||||||
mpTracker->NewDataset();
|
mpTracker->NewDataset();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*void System::SaveAtlas(int type){
|
#ifdef REGISTER_TIMES
|
||||||
cout << endl << "Enter the name of the file if you want to save the current Atlas session. To exit press ENTER: ";
|
void System::InsertRectTime(double& time)
|
||||||
string saveFileName;
|
|
||||||
getline(cin,saveFileName);
|
|
||||||
if(!saveFileName.empty())
|
|
||||||
{
|
{
|
||||||
//clock_t start = clock();
|
mpTracker->vdRectStereo_ms.push_back(time);
|
||||||
|
|
||||||
// Save the current session
|
|
||||||
mpAtlas->PreSave();
|
|
||||||
mpKeyFrameDatabase->PreSave();
|
|
||||||
|
|
||||||
string pathSaveFileName = "./";
|
|
||||||
pathSaveFileName = pathSaveFileName.append(saveFileName);
|
|
||||||
pathSaveFileName = pathSaveFileName.append(".osa");
|
|
||||||
|
|
||||||
string strVocabularyChecksum = CalculateCheckSum(mStrVocabularyFilePath,TEXT_FILE);
|
|
||||||
std::size_t found = mStrVocabularyFilePath.find_last_of("/\\");
|
|
||||||
string strVocabularyName = mStrVocabularyFilePath.substr(found+1);
|
|
||||||
|
|
||||||
if(type == TEXT_FILE) // File text
|
|
||||||
{
|
|
||||||
cout << "Starting to write the save text file " << endl;
|
|
||||||
std::remove(pathSaveFileName.c_str());
|
|
||||||
std::ofstream ofs(pathSaveFileName, std::ios::binary);
|
|
||||||
boost::archive::text_oarchive oa(ofs);
|
|
||||||
|
|
||||||
oa << strVocabularyName;
|
|
||||||
oa << strVocabularyChecksum;
|
|
||||||
oa << mpAtlas;
|
|
||||||
oa << mpKeyFrameDatabase;
|
|
||||||
cout << "End to write the save text file" << endl;
|
|
||||||
}
|
|
||||||
else if(type == BINARY_FILE) // File binary
|
|
||||||
{
|
|
||||||
cout << "Starting to write the save binary file" << endl;
|
|
||||||
std::remove(pathSaveFileName.c_str());
|
|
||||||
std::ofstream ofs(pathSaveFileName, std::ios::binary);
|
|
||||||
boost::archive::binary_oarchive oa(ofs);
|
|
||||||
oa << strVocabularyName;
|
|
||||||
oa << strVocabularyChecksum;
|
|
||||||
oa << mpAtlas;
|
|
||||||
oa << mpKeyFrameDatabase;
|
|
||||||
cout << "End to write save binary file" << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//clock_t timeElapsed = clock() - start;
|
void System::InsertTrackTime(double& time)
|
||||||
//unsigned msElapsed = timeElapsed / (CLOCKS_PER_SEC / 1000);
|
|
||||||
//cout << "Binary file saved in " << msElapsed << " ms" << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool System::LoadAtlas(string filename, int type)
|
|
||||||
{
|
{
|
||||||
string strFileVoc, strVocChecksum;
|
mpTracker->vdTrackTotal_ms.push_back(time);
|
||||||
bool isRead = false;
|
|
||||||
|
|
||||||
if(type == TEXT_FILE) // File text
|
|
||||||
{
|
|
||||||
cout << "Starting to read the save text file " << endl;
|
|
||||||
std::ifstream ifs(filename, std::ios::binary);
|
|
||||||
if(!ifs.good())
|
|
||||||
{
|
|
||||||
cout << "Load file not found" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
boost::archive::text_iarchive ia(ifs);
|
|
||||||
ia >> strFileVoc;
|
|
||||||
ia >> strVocChecksum;
|
|
||||||
ia >> mpAtlas;
|
|
||||||
//ia >> mpKeyFrameDatabase;
|
|
||||||
cout << "End to load the save text file " << endl;
|
|
||||||
isRead = true;
|
|
||||||
}
|
|
||||||
else if(type == BINARY_FILE) // File binary
|
|
||||||
{
|
|
||||||
cout << "Starting to read the save binary file" << endl;
|
|
||||||
std::ifstream ifs(filename, std::ios::binary);
|
|
||||||
if(!ifs.good())
|
|
||||||
{
|
|
||||||
cout << "Load file not found" << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
boost::archive::binary_iarchive ia(ifs);
|
|
||||||
ia >> strFileVoc;
|
|
||||||
ia >> strVocChecksum;
|
|
||||||
ia >> mpAtlas;
|
|
||||||
//ia >> mpKeyFrameDatabase;
|
|
||||||
cout << "End to load the save binary file" << endl;
|
|
||||||
isRead = true;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if(isRead)
|
|
||||||
{
|
|
||||||
//Check if the vocabulary is the same
|
|
||||||
string strInputVocabularyChecksum = CalculateCheckSum(mStrVocabularyFilePath,TEXT_FILE);
|
|
||||||
|
|
||||||
if(strInputVocabularyChecksum.compare(strVocChecksum) != 0)
|
|
||||||
{
|
|
||||||
cout << "The vocabulary load isn't the same which the load session was created " << endl;
|
|
||||||
cout << "-Vocabulary name: " << strFileVoc << endl;
|
|
||||||
return false; // Both are differents
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
string System::CalculateCheckSum(string filename, int type)
|
|
||||||
{
|
|
||||||
string checksum = "";
|
|
||||||
|
|
||||||
unsigned char c[MD5_DIGEST_LENGTH];
|
|
||||||
|
|
||||||
std::ios_base::openmode flags = std::ios::in;
|
|
||||||
if(type == BINARY_FILE) // Binary file
|
|
||||||
flags = std::ios::in | std::ios::binary;
|
|
||||||
|
|
||||||
ifstream f(filename.c_str(), flags);
|
|
||||||
if ( !f.is_open() )
|
|
||||||
{
|
|
||||||
cout << "[E] Unable to open the in file " << filename << " for Md5 hash." << endl;
|
|
||||||
return checksum;
|
|
||||||
}
|
|
||||||
|
|
||||||
MD5_CTX md5Context;
|
|
||||||
char buffer[1024];
|
|
||||||
|
|
||||||
MD5_Init (&md5Context);
|
|
||||||
while ( int count = f.readsome(buffer, sizeof(buffer)))
|
|
||||||
{
|
|
||||||
MD5_Update(&md5Context, buffer, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
f.close();
|
|
||||||
|
|
||||||
MD5_Final(c, &md5Context );
|
|
||||||
|
|
||||||
for(int i = 0; i < MD5_DIGEST_LENGTH; i++)
|
|
||||||
{
|
|
||||||
char aux[10];
|
|
||||||
sprintf(aux,"%02x", c[i]);
|
|
||||||
checksum = checksum + aux;
|
|
||||||
}
|
|
||||||
|
|
||||||
return checksum;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
} //namespace ORB_SLAM
|
} //namespace ORB_SLAM
|
||||||
|
|
||||||
|
|
682
src/Tracking.cc
682
src/Tracking.cc
|
@ -28,7 +28,6 @@
|
||||||
#include "Initializer.h"
|
#include "Initializer.h"
|
||||||
#include "G2oTypes.h"
|
#include "G2oTypes.h"
|
||||||
#include "Optimizer.h"
|
#include "Optimizer.h"
|
||||||
#include"PnPsolver.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
@ -49,7 +48,7 @@ Tracking::Tracking(System *pSys, ORBVocabulary* pVoc, FrameDrawer *pFrameDrawer,
|
||||||
mState(NO_IMAGES_YET), mSensor(sensor), mTrackedFr(0), mbStep(false),
|
mState(NO_IMAGES_YET), mSensor(sensor), mTrackedFr(0), mbStep(false),
|
||||||
mbOnlyTracking(false), mbMapUpdated(false), mbVO(false), mpORBVocabulary(pVoc), mpKeyFrameDB(pKFDB),
|
mbOnlyTracking(false), mbMapUpdated(false), mbVO(false), mpORBVocabulary(pVoc), mpKeyFrameDB(pKFDB),
|
||||||
mpInitializer(static_cast<Initializer*>(NULL)), mpSystem(pSys), mpViewer(NULL),
|
mpInitializer(static_cast<Initializer*>(NULL)), mpSystem(pSys), mpViewer(NULL),
|
||||||
mpFrameDrawer(pFrameDrawer), mpMapDrawer(pMapDrawer), mpAtlas(pAtlas), mnLastRelocFrameId(0), time_recently_lost(5.0),
|
mpFrameDrawer(pFrameDrawer), mpMapDrawer(pMapDrawer), mpAtlas(pAtlas), mnLastRelocFrameId(0), time_recently_lost(5.0), time_recently_lost_visual(2.0),
|
||||||
mnInitialFrameId(0), mbCreatedMap(false), mnFirstFrameId(0), mpCamera2(nullptr)
|
mnInitialFrameId(0), mbCreatedMap(false), mnFirstFrameId(0), mpCamera2(nullptr)
|
||||||
{
|
{
|
||||||
// Load camera parameters from settings file
|
// Load camera parameters from settings file
|
||||||
|
@ -85,52 +84,6 @@ Tracking::Tracking(System *pSys, ORBVocabulary* pVoc, FrameDrawer *pFrameDrawer,
|
||||||
|
|
||||||
mbInitWith3KFs = false;
|
mbInitWith3KFs = false;
|
||||||
|
|
||||||
|
|
||||||
//Rectification parameters
|
|
||||||
/*mbNeedRectify = false;
|
|
||||||
if((mSensor == System::STEREO || mSensor == System::IMU_STEREO) && sCameraName == "PinHole")
|
|
||||||
{
|
|
||||||
cv::Mat K_l, K_r, P_l, P_r, R_l, R_r, D_l, D_r;
|
|
||||||
fSettings["LEFT.K"] >> K_l;
|
|
||||||
fSettings["RIGHT.K"] >> K_r;
|
|
||||||
|
|
||||||
fSettings["LEFT.P"] >> P_l;
|
|
||||||
fSettings["RIGHT.P"] >> P_r;
|
|
||||||
|
|
||||||
fSettings["LEFT.R"] >> R_l;
|
|
||||||
fSettings["RIGHT.R"] >> R_r;
|
|
||||||
|
|
||||||
fSettings["LEFT.D"] >> D_l;
|
|
||||||
fSettings["RIGHT.D"] >> D_r;
|
|
||||||
|
|
||||||
int rows_l = fSettings["LEFT.height"];
|
|
||||||
int cols_l = fSettings["LEFT.width"];
|
|
||||||
int rows_r = fSettings["RIGHT.height"];
|
|
||||||
int cols_r = fSettings["RIGHT.width"];
|
|
||||||
|
|
||||||
if(K_l.empty() || K_r.empty() || P_l.empty() || P_r.empty() || R_l.empty() || R_r.empty() || D_l.empty() || D_r.empty()
|
|
||||||
|| rows_l==0 || cols_l==0 || rows_r==0 || cols_r==0)
|
|
||||||
{
|
|
||||||
mbNeedRectify = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mbNeedRectify = true;
|
|
||||||
// M1r y M2r son los outputs (igual para l)
|
|
||||||
// M1r y M2r son las matrices relativas al mapeo correspondiente a la rectificación de mapa en el eje X e Y respectivamente
|
|
||||||
//cv::initUndistortRectifyMap(K_l,D_l,R_l,P_l.rowRange(0,3).colRange(0,3),cv::Size(cols_l,rows_l),CV_32F,M1l,M2l);
|
|
||||||
//cv::initUndistortRectifyMap(K_r,D_r,R_r,P_r.rowRange(0,3).colRange(0,3),cv::Size(cols_r,rows_r),CV_32F,M1r,M2r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int cols = 752;
|
|
||||||
int rows = 480;
|
|
||||||
cv::Mat R_l = cv::Mat::eye(3, 3, CV_32F);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
mnNumDataset = 0;
|
mnNumDataset = 0;
|
||||||
|
|
||||||
if(!b_parse_cam || !b_parse_orb || !b_parse_imu)
|
if(!b_parse_cam || !b_parse_orb || !b_parse_imu)
|
||||||
|
@ -146,24 +99,399 @@ Tracking::Tracking(System *pSys, ORBVocabulary* pVoc, FrameDrawer *pFrameDrawer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//f_track_stats.open("tracking_stats"+ _nameSeq + ".txt");
|
#ifdef REGISTER_TIMES
|
||||||
/*f_track_stats.open("tracking_stats.txt");
|
vdRectStereo_ms.clear();
|
||||||
f_track_stats << "# timestamp, Num KF local, Num MP local, time" << endl;
|
vdORBExtract_ms.clear();
|
||||||
f_track_stats << fixed ;*/
|
vdStereoMatch_ms.clear();
|
||||||
|
vdIMUInteg_ms.clear();
|
||||||
|
vdPosePred_ms.clear();
|
||||||
|
vdLMTrack_ms.clear();
|
||||||
|
vdNewKF_ms.clear();
|
||||||
|
vdTrackTotal_ms.clear();
|
||||||
|
|
||||||
#ifdef SAVE_TIMES
|
vdUpdatedLM_ms.clear();
|
||||||
f_track_times.open("tracking_times.txt");
|
vdSearchLP_ms.clear();
|
||||||
f_track_times << "# ORB_Ext(ms), Stereo matching(ms), Preintegrate_IMU(ms), Pose pred(ms), LocalMap_track(ms), NewKF_dec(ms)" << endl;
|
vdPoseOpt_ms.clear();
|
||||||
f_track_times << fixed ;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
vnKeyFramesLM.clear();
|
||||||
|
vnMapPointsLM.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
double calcAverage(vector<double> v_times)
|
||||||
|
{
|
||||||
|
double accum = 0;
|
||||||
|
for(double value : v_times)
|
||||||
|
{
|
||||||
|
accum += value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return accum / v_times.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
double calcDeviation(vector<double> v_times, double average)
|
||||||
|
{
|
||||||
|
double accum = 0;
|
||||||
|
for(double value : v_times)
|
||||||
|
{
|
||||||
|
accum += pow(value - average, 2);
|
||||||
|
}
|
||||||
|
return sqrt(accum / v_times.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
double calcAverage(vector<int> v_values)
|
||||||
|
{
|
||||||
|
double accum = 0;
|
||||||
|
int total = 0;
|
||||||
|
for(double value : v_values)
|
||||||
|
{
|
||||||
|
if(value == 0)
|
||||||
|
continue;
|
||||||
|
accum += value;
|
||||||
|
total++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return accum / total;
|
||||||
|
}
|
||||||
|
|
||||||
|
double calcDeviation(vector<int> v_values, double average)
|
||||||
|
{
|
||||||
|
double accum = 0;
|
||||||
|
int total = 0;
|
||||||
|
for(double value : v_values)
|
||||||
|
{
|
||||||
|
if(value == 0)
|
||||||
|
continue;
|
||||||
|
accum += pow(value - average, 2);
|
||||||
|
total++;
|
||||||
|
}
|
||||||
|
return sqrt(accum / total);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tracking::LocalMapStats2File()
|
||||||
|
{
|
||||||
|
ofstream f;
|
||||||
|
f.open("LocalMapTimeStats.txt");
|
||||||
|
f << fixed << setprecision(6);
|
||||||
|
f << "#Stereo rect[ms], MP culling[ms], MP creation[ms], LBA[ms], KF culling[ms], Total[ms]" << endl;
|
||||||
|
for(int i=0; i<mpLocalMapper->vdLMTotal_ms.size(); ++i)
|
||||||
|
{
|
||||||
|
f << mpLocalMapper->vdKFInsert_ms[i] << "," << mpLocalMapper->vdMPCulling_ms[i] << ","
|
||||||
|
<< mpLocalMapper->vdMPCreation_ms[i] << "," << mpLocalMapper->vdLBA_ms[i] << ","
|
||||||
|
<< mpLocalMapper->vdKFCulling_ms[i] << "," << mpLocalMapper->vdLMTotal_ms[i] << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
f.open("LBA_Stats.txt");
|
||||||
|
f << fixed << setprecision(6);
|
||||||
|
f << "#LBA time[ms], KF opt[#], KF fixed[#], MP[#], Edges[#]" << endl;
|
||||||
|
for(int i=0; i<mpLocalMapper->vdLBASync_ms.size(); ++i)
|
||||||
|
{
|
||||||
|
f << mpLocalMapper->vdLBASync_ms[i] << "," << mpLocalMapper->vnLBA_KFopt[i] << ","
|
||||||
|
<< mpLocalMapper->vnLBA_KFfixed[i] << "," << mpLocalMapper->vnLBA_MPs[i] << ","
|
||||||
|
<< mpLocalMapper->vnLBA_edges[i] << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
f.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tracking::TrackStats2File()
|
||||||
|
{
|
||||||
|
ofstream f;
|
||||||
|
f.open("SessionInfo.txt");
|
||||||
|
f << fixed;
|
||||||
|
f << "Number of KFs: " << mpAtlas->GetAllKeyFrames().size() << endl;
|
||||||
|
f << "Number of MPs: " << mpAtlas->GetAllMapPoints().size() << endl;
|
||||||
|
|
||||||
|
f << "OpenCV version: " << CV_VERSION << endl;
|
||||||
|
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
f.open("TrackingTimeStats.txt");
|
||||||
|
f << fixed << setprecision(6);
|
||||||
|
|
||||||
|
f << "#KF insert[ms], ORB ext[ms], Stereo match[ms], IMU preint[ms], Pose pred[ms], LM track[ms], KF dec[ms], Total[ms]" << endl;
|
||||||
|
|
||||||
|
for(int i=0; i<vdTrackTotal_ms.size(); ++i)
|
||||||
|
{
|
||||||
|
double stereo_rect = 0.0;
|
||||||
|
if(!vdRectStereo_ms.empty())
|
||||||
|
{
|
||||||
|
stereo_rect = vdStereoMatch_ms[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
double stereo_match = 0.0;
|
||||||
|
if(!vdStereoMatch_ms.empty())
|
||||||
|
{
|
||||||
|
stereo_match = vdStereoMatch_ms[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
double imu_preint = 0.0;
|
||||||
|
if(!vdIMUInteg_ms.empty())
|
||||||
|
{
|
||||||
|
imu_preint = vdIMUInteg_ms[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
f << stereo_rect << "," << vdORBExtract_ms[i] << "," << stereo_match << "," << imu_preint << ","
|
||||||
|
<< vdPosePred_ms[i] << "," << vdLMTrack_ms[i] << "," << vdNewKF_ms[i] << "," << vdTrackTotal_ms[i] << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
f.open("TrackLocalMapStats.txt");
|
||||||
|
f << fixed << setprecision(6);
|
||||||
|
|
||||||
|
f << "# number of KF, number of MP, UpdateLM[ms], SearchLP[ms], PoseOpt[ms]" << endl;
|
||||||
|
|
||||||
|
for(int i=0; i<vnKeyFramesLM.size(); ++i)
|
||||||
|
{
|
||||||
|
|
||||||
|
f << vnKeyFramesLM[i] << "," << vnMapPointsLM[i] << "," << vdUpdatedLM_ms[i] << "," << vdSearchLP_ms[i] << "," << vdPoseOpt_ms[i] << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
f.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tracking::PrintTimeStats()
|
||||||
|
{
|
||||||
|
// Save data in files
|
||||||
|
TrackStats2File();
|
||||||
|
LocalMapStats2File();
|
||||||
|
|
||||||
|
|
||||||
|
ofstream f;
|
||||||
|
f.open("ExecTimeMean.txt");
|
||||||
|
f << fixed;
|
||||||
|
//Report the mean and std of each one
|
||||||
|
std::cout << std::endl << " TIME STATS in ms (mean$\\pm$std)" << std::endl;
|
||||||
|
f << " TIME STATS in ms (mean$\\pm$std)" << std::endl;
|
||||||
|
cout << "OpenCV version: " << CV_VERSION << endl;
|
||||||
|
f << "OpenCV version: " << CV_VERSION << endl;
|
||||||
|
std::cout << "---------------------------" << std::endl;
|
||||||
|
std::cout << "Tracking" << std::setprecision(5) << std::endl << std::endl;
|
||||||
|
f << "---------------------------" << std::endl;
|
||||||
|
f << "Tracking" << std::setprecision(5) << std::endl << std::endl;
|
||||||
|
double average, deviation;
|
||||||
|
if(!vdRectStereo_ms.empty())
|
||||||
|
{
|
||||||
|
average = calcAverage(vdRectStereo_ms);
|
||||||
|
deviation = calcDeviation(vdRectStereo_ms, average);
|
||||||
|
std::cout << "Stereo Rectification: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "Stereo Rectification: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
average = calcAverage(vdORBExtract_ms);
|
||||||
|
deviation = calcDeviation(vdORBExtract_ms, average);
|
||||||
|
std::cout << "ORB Extraction: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "ORB Extraction: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
|
||||||
|
if(!vdStereoMatch_ms.empty())
|
||||||
|
{
|
||||||
|
average = calcAverage(vdStereoMatch_ms);
|
||||||
|
deviation = calcDeviation(vdStereoMatch_ms, average);
|
||||||
|
std::cout << "Stereo Matching: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "Stereo Matching: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!vdIMUInteg_ms.empty())
|
||||||
|
{
|
||||||
|
average = calcAverage(vdIMUInteg_ms);
|
||||||
|
deviation = calcDeviation(vdIMUInteg_ms, average);
|
||||||
|
std::cout << "IMU Preintegration: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "IMU Preintegration: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
average = calcAverage(vdPosePred_ms);
|
||||||
|
deviation = calcDeviation(vdPosePred_ms, average);
|
||||||
|
std::cout << "Pose Prediction: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "Pose Prediction: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
|
||||||
|
average = calcAverage(vdLMTrack_ms);
|
||||||
|
deviation = calcDeviation(vdLMTrack_ms, average);
|
||||||
|
std::cout << "LM Track: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "LM Track: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
|
||||||
|
average = calcAverage(vdNewKF_ms);
|
||||||
|
deviation = calcDeviation(vdNewKF_ms, average);
|
||||||
|
std::cout << "New KF decision: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "New KF decision: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
|
||||||
|
average = calcAverage(vdTrackTotal_ms);
|
||||||
|
deviation = calcDeviation(vdTrackTotal_ms, average);
|
||||||
|
std::cout << "Total Tracking: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "Total Tracking: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
|
||||||
|
// Local Map Tracking complexity
|
||||||
|
std::cout << "---------------------------" << std::endl;
|
||||||
|
std::cout << std::endl << "Local Map Tracking complexity (mean$\\pm$std)" << std::endl;
|
||||||
|
f << "---------------------------" << std::endl;
|
||||||
|
f << std::endl << "Local Map Tracking complexity (mean$\\pm$std)" << std::endl;
|
||||||
|
|
||||||
|
average = calcAverage(vnKeyFramesLM);
|
||||||
|
deviation = calcDeviation(vnKeyFramesLM, average);
|
||||||
|
std::cout << "Local KFs: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "Local KFs: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
|
||||||
|
average = calcAverage(vnMapPointsLM);
|
||||||
|
deviation = calcDeviation(vnMapPointsLM, average);
|
||||||
|
std::cout << "Local MPs: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "Local MPs: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
|
||||||
|
// Local Mapping time stats
|
||||||
|
std::cout << std::endl << std::endl << std::endl;
|
||||||
|
std::cout << "Local Mapping" << std::endl << std::endl;
|
||||||
|
f << std::endl << "Local Mapping" << std::endl << std::endl;
|
||||||
|
|
||||||
|
average = calcAverage(mpLocalMapper->vdKFInsert_ms);
|
||||||
|
deviation = calcDeviation(mpLocalMapper->vdKFInsert_ms, average);
|
||||||
|
std::cout << "KF Insertion: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "KF Insertion: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
|
||||||
|
average = calcAverage(mpLocalMapper->vdMPCulling_ms);
|
||||||
|
deviation = calcDeviation(mpLocalMapper->vdMPCulling_ms, average);
|
||||||
|
std::cout << "MP Culling: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "MP Culling: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
|
||||||
|
average = calcAverage(mpLocalMapper->vdMPCreation_ms);
|
||||||
|
deviation = calcDeviation(mpLocalMapper->vdMPCreation_ms, average);
|
||||||
|
std::cout << "MP Creation: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "MP Creation: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
|
||||||
|
average = calcAverage(mpLocalMapper->vdLBASync_ms);
|
||||||
|
deviation = calcDeviation(mpLocalMapper->vdLBASync_ms, average);
|
||||||
|
std::cout << "LBA: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "LBA: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
|
||||||
|
average = calcAverage(mpLocalMapper->vdKFCullingSync_ms);
|
||||||
|
deviation = calcDeviation(mpLocalMapper->vdKFCullingSync_ms, average);
|
||||||
|
std::cout << "KF Culling: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "KF Culling: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
|
||||||
|
average = calcAverage(mpLocalMapper->vdLMTotal_ms);
|
||||||
|
deviation = calcDeviation(mpLocalMapper->vdLMTotal_ms, average);
|
||||||
|
std::cout << "Total Local Mapping: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "Total Local Mapping: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
|
||||||
|
// Local Mapping LBA complexity
|
||||||
|
std::cout << "---------------------------" << std::endl;
|
||||||
|
std::cout << std::endl << "LBA complexity (mean$\\pm$std)" << std::endl;
|
||||||
|
f << "---------------------------" << std::endl;
|
||||||
|
f << std::endl << "LBA complexity (mean$\\pm$std)" << std::endl;
|
||||||
|
|
||||||
|
average = calcAverage(mpLocalMapper->vnLBA_edges);
|
||||||
|
deviation = calcDeviation(mpLocalMapper->vnLBA_edges, average);
|
||||||
|
std::cout << "LBA Edges: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "LBA Edges: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
|
||||||
|
average = calcAverage(mpLocalMapper->vnLBA_KFopt);
|
||||||
|
deviation = calcDeviation(mpLocalMapper->vnLBA_KFopt, average);
|
||||||
|
std::cout << "LBA KF optimized: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "LBA KF optimized: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
|
||||||
|
average = calcAverage(mpLocalMapper->vnLBA_KFfixed);
|
||||||
|
deviation = calcDeviation(mpLocalMapper->vnLBA_KFfixed, average);
|
||||||
|
std::cout << "LBA KF fixed: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "LBA KF fixed: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
|
||||||
|
average = calcAverage(mpLocalMapper->vnLBA_MPs);
|
||||||
|
deviation = calcDeviation(mpLocalMapper->vnLBA_MPs, average);
|
||||||
|
std::cout << "LBA MP: " << average << "$\\pm$" << deviation << std::endl << std::endl;
|
||||||
|
f << "LBA MP: " << average << "$\\pm$" << deviation << std::endl << std::endl;
|
||||||
|
|
||||||
|
std::cout << "LBA executions: " << mpLocalMapper->nLBA_exec << std::endl;
|
||||||
|
std::cout << "LBA aborts: " << mpLocalMapper->nLBA_abort << std::endl;
|
||||||
|
f << "LBA executions: " << mpLocalMapper->nLBA_exec << std::endl;
|
||||||
|
f << "LBA aborts: " << mpLocalMapper->nLBA_abort << std::endl;
|
||||||
|
|
||||||
|
// Map complexity
|
||||||
|
std::cout << "---------------------------" << std::endl;
|
||||||
|
std::cout << std::endl << "Map complexity" << std::endl;
|
||||||
|
std::cout << "KFs in map: " << mpAtlas->GetAllMaps()[0]->GetAllKeyFrames().size() << std::endl;
|
||||||
|
std::cout << "MPs in map: " << mpAtlas->GetAllMaps()[0]->GetAllMapPoints().size() << std::endl;
|
||||||
|
f << "---------------------------" << std::endl;
|
||||||
|
f << std::endl << "Map complexity" << std::endl;
|
||||||
|
f << "KFs in map: " << mpAtlas->GetAllMaps()[0]->GetAllKeyFrames().size() << std::endl;
|
||||||
|
f << "MPs in map: " << mpAtlas->GetAllMaps()[0]->GetAllMapPoints().size() << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
// Place recognition time stats
|
||||||
|
std::cout << std::endl << std::endl << std::endl;
|
||||||
|
std::cout << "Place Recognition (mean$\\pm$std)" << std::endl << std::endl;
|
||||||
|
f << std::endl << "Place Recognition (mean$\\pm$std)" << std::endl << std::endl;
|
||||||
|
|
||||||
|
average = calcAverage(mpLoopClosing->vTimeBoW_ms);
|
||||||
|
deviation = calcDeviation(mpLoopClosing->vTimeBoW_ms, average);
|
||||||
|
std::cout << "Database Query: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "Database Query: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
average = calcAverage(mpLoopClosing->vTimeSE3_ms);
|
||||||
|
deviation = calcDeviation(mpLoopClosing->vTimeSE3_ms, average);
|
||||||
|
std::cout << "SE3 estimation: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "SE3 estimation: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
average = calcAverage(mpLoopClosing->vTimePRTotal_ms);
|
||||||
|
deviation = calcDeviation(mpLoopClosing->vTimePRTotal_ms, average);
|
||||||
|
std::cout << "Total Place Recognition: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "Total Place Recognition: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
|
||||||
|
// Loop Closing time stats
|
||||||
|
if(mpLoopClosing->vTimeLoopTotal_ms.size() > 0)
|
||||||
|
{
|
||||||
|
std::cout << std::endl << std::endl << std::endl;
|
||||||
|
std::cout << "Loop Closing (mean$\\pm$std)" << std::endl << std::endl;
|
||||||
|
f << std::endl << "Loop Closing (mean$\\pm$std)" << std::endl << std::endl;
|
||||||
|
|
||||||
|
average = calcAverage(mpLoopClosing->vTimeLoopTotal_ms);
|
||||||
|
deviation = calcDeviation(mpLoopClosing->vTimeLoopTotal_ms, average);
|
||||||
|
std::cout << "Total Loop Closing: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "Total Loop Closing: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mpLoopClosing->vTimeMergeTotal_ms.size() > 0)
|
||||||
|
{
|
||||||
|
// Map Merging time stats
|
||||||
|
std::cout << std::endl << std::endl << std::endl;
|
||||||
|
std::cout << "Map Merging (mean$\\pm$std)" << std::endl << std::endl;
|
||||||
|
f << std::endl << "Map Merging (mean$\\pm$std)" << std::endl << std::endl;
|
||||||
|
|
||||||
|
average = calcAverage(mpLoopClosing->vTimeMergeTotal_ms);
|
||||||
|
deviation = calcDeviation(mpLoopClosing->vTimeMergeTotal_ms, average);
|
||||||
|
std::cout << "Total Map Merging: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "Total Map Merging: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(mpLoopClosing->vTimeGBATotal_ms.size() > 0)
|
||||||
|
{
|
||||||
|
// Full GBA time stats
|
||||||
|
std::cout << std::endl << std::endl << std::endl;
|
||||||
|
std::cout << "Full GBA (mean$\\pm$std)" << std::endl << std::endl;
|
||||||
|
f << std::endl << "Full GBA (mean$\\pm$std)" << std::endl << std::endl;
|
||||||
|
|
||||||
|
average = calcAverage(mpLoopClosing->vTimeFullGBA_ms);
|
||||||
|
deviation = calcDeviation(mpLoopClosing->vTimeFullGBA_ms, average);
|
||||||
|
std::cout << "GBA: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "GBA: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
average = calcAverage(mpLoopClosing->vTimeMapUpdate_ms);
|
||||||
|
deviation = calcDeviation(mpLoopClosing->vTimeMapUpdate_ms, average);
|
||||||
|
std::cout << "Map Update: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "Map Update: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
average = calcAverage(mpLoopClosing->vTimeGBATotal_ms);
|
||||||
|
deviation = calcDeviation(mpLoopClosing->vTimeGBATotal_ms, average);
|
||||||
|
std::cout << "Total Full GBA: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
f << "Total Full GBA: " << average << "$\\pm$" << deviation << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
Tracking::~Tracking()
|
Tracking::~Tracking()
|
||||||
{
|
{
|
||||||
//f_track_stats.close();
|
|
||||||
#ifdef SAVE_TIMES
|
|
||||||
f_track_times.close();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Tracking::ParseCamParamFile(cv::FileStorage &fSettings)
|
bool Tracking::ParseCamParamFile(cv::FileStorage &fSettings)
|
||||||
|
@ -918,26 +1246,26 @@ cv::Mat Tracking::GrabImageStereo(const cv::Mat &imRectLeft, const cv::Mat &imRe
|
||||||
{
|
{
|
||||||
if(mbRGB)
|
if(mbRGB)
|
||||||
{
|
{
|
||||||
cvtColor(mImGray,mImGray,CV_RGB2GRAY);
|
cvtColor(mImGray,mImGray,cv::COLOR_RGB2GRAY);
|
||||||
cvtColor(imGrayRight,imGrayRight,CV_RGB2GRAY);
|
cvtColor(imGrayRight,imGrayRight,cv::COLOR_RGB2GRAY);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cvtColor(mImGray,mImGray,CV_BGR2GRAY);
|
cvtColor(mImGray,mImGray,cv::COLOR_BGR2GRAY);
|
||||||
cvtColor(imGrayRight,imGrayRight,CV_BGR2GRAY);
|
cvtColor(imGrayRight,imGrayRight,cv::COLOR_BGR2GRAY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(mImGray.channels()==4)
|
else if(mImGray.channels()==4)
|
||||||
{
|
{
|
||||||
if(mbRGB)
|
if(mbRGB)
|
||||||
{
|
{
|
||||||
cvtColor(mImGray,mImGray,CV_RGBA2GRAY);
|
cvtColor(mImGray,mImGray,cv::COLOR_RGBA2GRAY);
|
||||||
cvtColor(imGrayRight,imGrayRight,CV_RGBA2GRAY);
|
cvtColor(imGrayRight,imGrayRight,cv::COLOR_RGBA2GRAY);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cvtColor(mImGray,mImGray,CV_BGRA2GRAY);
|
cvtColor(mImGray,mImGray,cv::COLOR_BGRA2GRAY);
|
||||||
cvtColor(imGrayRight,imGrayRight,CV_BGRA2GRAY);
|
cvtColor(imGrayRight,imGrayRight,cv::COLOR_BGRA2GRAY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -950,32 +1278,16 @@ cv::Mat Tracking::GrabImageStereo(const cv::Mat &imRectLeft, const cv::Mat &imRe
|
||||||
else if(mSensor == System::IMU_STEREO && mpCamera2)
|
else if(mSensor == System::IMU_STEREO && mpCamera2)
|
||||||
mCurrentFrame = Frame(mImGray,imGrayRight,timestamp,mpORBextractorLeft,mpORBextractorRight,mpORBVocabulary,mK,mDistCoef,mbf,mThDepth,mpCamera,mpCamera2,mTlr,&mLastFrame,*mpImuCalib);
|
mCurrentFrame = Frame(mImGray,imGrayRight,timestamp,mpORBextractorLeft,mpORBextractorRight,mpORBVocabulary,mK,mDistCoef,mbf,mThDepth,mpCamera,mpCamera2,mTlr,&mLastFrame,*mpImuCalib);
|
||||||
|
|
||||||
std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
|
|
||||||
mCurrentFrame.mNameFile = filename;
|
mCurrentFrame.mNameFile = filename;
|
||||||
mCurrentFrame.mnDataset = mnNumDataset;
|
mCurrentFrame.mnDataset = mnNumDataset;
|
||||||
|
|
||||||
Track();
|
#ifdef REGISTER_TIMES
|
||||||
|
vdORBExtract_ms.push_back(mCurrentFrame.mTimeORB_Ext);
|
||||||
std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
|
vdStereoMatch_ms.push_back(mCurrentFrame.mTimeStereoMatch);
|
||||||
|
|
||||||
double t_track = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t1 - t0).count();
|
|
||||||
|
|
||||||
/*cout << "trracking time: " << t_track << endl;
|
|
||||||
f_track_stats << setprecision(0) << mCurrentFrame.mTimeStamp*1e9 << ",";
|
|
||||||
f_track_stats << mvpLocalKeyFrames.size() << ",";
|
|
||||||
f_track_stats << mvpLocalMapPoints.size() << ",";
|
|
||||||
f_track_stats << setprecision(6) << t_track << endl;*/
|
|
||||||
|
|
||||||
#ifdef SAVE_TIMES
|
|
||||||
f_track_times << mCurrentFrame.mTimeORB_Ext << ",";
|
|
||||||
f_track_times << mCurrentFrame.mTimeStereoMatch << ",";
|
|
||||||
f_track_times << mTime_PreIntIMU << ",";
|
|
||||||
f_track_times << mTime_PosePred << ",";
|
|
||||||
f_track_times << mTime_LocalMapTrack << ",";
|
|
||||||
f_track_times << mTime_NewKF_Dec << ",";
|
|
||||||
f_track_times << t_track << endl;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Track();
|
||||||
|
|
||||||
return mCurrentFrame.mTcw.clone();
|
return mCurrentFrame.mTcw.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -988,49 +1300,32 @@ cv::Mat Tracking::GrabImageRGBD(const cv::Mat &imRGB,const cv::Mat &imD, const d
|
||||||
if(mImGray.channels()==3)
|
if(mImGray.channels()==3)
|
||||||
{
|
{
|
||||||
if(mbRGB)
|
if(mbRGB)
|
||||||
cvtColor(mImGray,mImGray,CV_RGB2GRAY);
|
cvtColor(mImGray,mImGray,cv::COLOR_RGB2GRAY);
|
||||||
else
|
else
|
||||||
cvtColor(mImGray,mImGray,CV_BGR2GRAY);
|
cvtColor(mImGray,mImGray,cv::COLOR_BGR2GRAY);
|
||||||
}
|
}
|
||||||
else if(mImGray.channels()==4)
|
else if(mImGray.channels()==4)
|
||||||
{
|
{
|
||||||
if(mbRGB)
|
if(mbRGB)
|
||||||
cvtColor(mImGray,mImGray,CV_RGBA2GRAY);
|
cvtColor(mImGray,mImGray,cv::COLOR_RGBA2GRAY);
|
||||||
else
|
else
|
||||||
cvtColor(mImGray,mImGray,CV_BGRA2GRAY);
|
cvtColor(mImGray,mImGray,cv::COLOR_BGRA2GRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((fabs(mDepthMapFactor-1.0f)>1e-5) || imDepth.type()!=CV_32F)
|
if((fabs(mDepthMapFactor-1.0f)>1e-5) || imDepth.type()!=CV_32F)
|
||||||
imDepth.convertTo(imDepth,CV_32F,mDepthMapFactor);
|
imDepth.convertTo(imDepth,CV_32F,mDepthMapFactor);
|
||||||
|
|
||||||
std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
|
|
||||||
mCurrentFrame = Frame(mImGray,imDepth,timestamp,mpORBextractorLeft,mpORBVocabulary,mK,mDistCoef,mbf,mThDepth,mpCamera);
|
mCurrentFrame = Frame(mImGray,imDepth,timestamp,mpORBextractorLeft,mpORBVocabulary,mK,mDistCoef,mbf,mThDepth,mpCamera);
|
||||||
|
|
||||||
mCurrentFrame.mNameFile = filename;
|
mCurrentFrame.mNameFile = filename;
|
||||||
mCurrentFrame.mnDataset = mnNumDataset;
|
mCurrentFrame.mnDataset = mnNumDataset;
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
vdORBExtract_ms.push_back(mCurrentFrame.mTimeORB_Ext);
|
||||||
|
#endif
|
||||||
|
|
||||||
Track();
|
Track();
|
||||||
|
|
||||||
std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
double t_track = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t1 - t0).count();
|
|
||||||
|
|
||||||
/*f_track_stats << setprecision(0) << mCurrentFrame.mTimeStamp*1e9 << ",";
|
|
||||||
f_track_stats << mvpLocalKeyFrames.size() << ",";
|
|
||||||
f_track_stats << mvpLocalMapPoints.size() << ",";
|
|
||||||
f_track_stats << setprecision(6) << t_track << endl;*/
|
|
||||||
|
|
||||||
#ifdef SAVE_TIMES
|
|
||||||
f_track_times << mCurrentFrame.mTimeORB_Ext << ",";
|
|
||||||
f_track_times << mCurrentFrame.mTimeStereoMatch << ",";
|
|
||||||
f_track_times << mTime_PreIntIMU << ",";
|
|
||||||
f_track_times << mTime_PosePred << ",";
|
|
||||||
f_track_times << mTime_LocalMapTrack << ",";
|
|
||||||
f_track_times << mTime_NewKF_Dec << ",";
|
|
||||||
f_track_times << t_track << endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return mCurrentFrame.mTcw.clone();
|
return mCurrentFrame.mTcw.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1051,16 +1346,16 @@ cv::Mat Tracking::GrabImageMonocular(const cv::Mat &im, const double ×tamp,
|
||||||
if(mImGray.channels()==3)
|
if(mImGray.channels()==3)
|
||||||
{
|
{
|
||||||
if(mbRGB)
|
if(mbRGB)
|
||||||
cvtColor(mImGray,mImGray,CV_RGB2GRAY);
|
cvtColor(mImGray,mImGray,cv::COLOR_RGB2GRAY);
|
||||||
else
|
else
|
||||||
cvtColor(mImGray,mImGray,CV_BGR2GRAY);
|
cvtColor(mImGray,mImGray,cv::COLOR_BGR2GRAY);
|
||||||
}
|
}
|
||||||
else if(mImGray.channels()==4)
|
else if(mImGray.channels()==4)
|
||||||
{
|
{
|
||||||
if(mbRGB)
|
if(mbRGB)
|
||||||
cvtColor(mImGray,mImGray,CV_RGBA2GRAY);
|
cvtColor(mImGray,mImGray,cv::COLOR_RGBA2GRAY);
|
||||||
else
|
else
|
||||||
cvtColor(mImGray,mImGray,CV_BGRA2GRAY);
|
cvtColor(mImGray,mImGray,cv::COLOR_BGRA2GRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2 :构造Frame
|
// Step 2 :构造Frame
|
||||||
|
@ -1086,36 +1381,18 @@ cv::Mat Tracking::GrabImageMonocular(const cv::Mat &im, const double ×tamp,
|
||||||
if (mState==NO_IMAGES_YET)
|
if (mState==NO_IMAGES_YET)
|
||||||
t0=timestamp;
|
t0=timestamp;
|
||||||
|
|
||||||
std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
mCurrentFrame.mNameFile = filename;
|
mCurrentFrame.mNameFile = filename;
|
||||||
mCurrentFrame.mnDataset = mnNumDataset;
|
mCurrentFrame.mnDataset = mnNumDataset;
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
vdORBExtract_ms.push_back(mCurrentFrame.mTimeORB_Ext);
|
||||||
|
#endif
|
||||||
|
|
||||||
lastID = mCurrentFrame.mnId;
|
lastID = mCurrentFrame.mnId;
|
||||||
|
|
||||||
// Step 3 :跟踪
|
// Step 3 :跟踪
|
||||||
Track();
|
Track();
|
||||||
|
|
||||||
std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
double t_track = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t1 - t0).count();
|
|
||||||
|
|
||||||
/*f_track_stats << setprecision(0) << mCurrentFrame.mTimeStamp*1e9 << ",";
|
|
||||||
f_track_stats << mvpLocalKeyFrames.size() << ",";
|
|
||||||
f_track_stats << mvpLocalMapPoints.size() << ",";
|
|
||||||
f_track_stats << setprecision(6) << t_track << endl;*/
|
|
||||||
|
|
||||||
//开启保存数据模式
|
|
||||||
#ifdef SAVE_TIMES
|
|
||||||
f_track_times << mCurrentFrame.mTimeORB_Ext << ",";
|
|
||||||
f_track_times << mCurrentFrame.mTimeStereoMatch << ",";
|
|
||||||
f_track_times << mTime_PreIntIMU << ",";
|
|
||||||
f_track_times << mTime_PosePred << ",";
|
|
||||||
f_track_times << mTime_LocalMapTrack << ",";
|
|
||||||
f_track_times << mTime_NewKF_Dec << ",";
|
|
||||||
f_track_times << t_track << endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//返回当前帧的位姿
|
//返回当前帧的位姿
|
||||||
return mCurrentFrame.mTcw.clone();
|
return mCurrentFrame.mTcw.clone();
|
||||||
}
|
}
|
||||||
|
@ -1454,10 +1731,6 @@ void Tracking::ComputeVelocitiesAccBias(const vector<Frame*> &vpFs, float &bax,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tracking::ResetFrameIMU()
|
|
||||||
{
|
|
||||||
// TODO To implement...
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 跟踪过程,包括恒速模型跟踪、参考关键帧跟踪、局部地图跟踪
|
* @brief 跟踪过程,包括恒速模型跟踪、参考关键帧跟踪、局部地图跟踪
|
||||||
|
@ -1469,13 +1742,7 @@ void Tracking::ResetFrameIMU()
|
||||||
*/
|
*/
|
||||||
void Tracking::Track()
|
void Tracking::Track()
|
||||||
{
|
{
|
||||||
#ifdef SAVE_TIMES
|
|
||||||
mTime_PreIntIMU = 0;
|
|
||||||
mTime_PosePred = 0;
|
|
||||||
mTime_LocalMapTrack = 0;
|
|
||||||
mTime_NewKF_Dec = 0;
|
|
||||||
#endif
|
|
||||||
// ? 还不清楚这个标识符,跟绘图相关?
|
|
||||||
if (bStepByStep)
|
if (bStepByStep)
|
||||||
{
|
{
|
||||||
while(!mbStep)
|
while(!mbStep)
|
||||||
|
@ -1556,15 +1823,16 @@ void Tracking::Track()
|
||||||
// Step 4 IMU模式下对IMU数据进行预积分 -> // ? 没有创建地图的情况下
|
// Step 4 IMU模式下对IMU数据进行预积分 -> // ? 没有创建地图的情况下
|
||||||
if ((mSensor == System::IMU_MONOCULAR || mSensor == System::IMU_STEREO) && !mbCreatedMap)
|
if ((mSensor == System::IMU_MONOCULAR || mSensor == System::IMU_STEREO) && !mbCreatedMap)
|
||||||
{
|
{
|
||||||
#ifdef SAVE_TIMES
|
#ifdef REGISTER_TIMES
|
||||||
std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
|
std::chrono::steady_clock::time_point time_StartPreIMU = std::chrono::steady_clock::now();
|
||||||
#endif
|
#endif
|
||||||
// IMU数据进行预积分
|
// IMU数据进行预积分
|
||||||
PreintegrateIMU();
|
PreintegrateIMU();
|
||||||
#ifdef SAVE_TIMES
|
#ifdef REGISTER_TIMES
|
||||||
std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
|
std::chrono::steady_clock::time_point time_EndPreIMU = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
mTime_PreIntIMU = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(t1 - t0).count();
|
double timePreImu = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndPreIMU - time_StartPreIMU).count();
|
||||||
|
vdIMUInteg_ms.push_back(timePreImu);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -1625,14 +1893,15 @@ void Tracking::Track()
|
||||||
// Step 6 系统成功初始化,下面是具体跟踪过程
|
// Step 6 系统成功初始化,下面是具体跟踪过程
|
||||||
bool bOK;
|
bool bOK;
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_StartPosePred = std::chrono::steady_clock::now();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Initial camera pose estimation using motion model or relocalization (if tracking is lost)
|
// Initial camera pose estimation using motion model or relocalization (if tracking is lost)
|
||||||
// mbOnlyTracking等于false表示正常SLAM模式(定位+地图更新),mbOnlyTracking等于true表示仅定位模式
|
// mbOnlyTracking等于false表示正常SLAM模式(定位+地图更新),mbOnlyTracking等于true表示仅定位模式
|
||||||
// tracking 类构造时默认为false。在viewer中有个开关ActivateLocalizationMode,可以控制是否开启mbOnlyTracking
|
// tracking 类构造时默认为false。在viewer中有个开关ActivateLocalizationMode,可以控制是否开启mbOnlyTracking
|
||||||
if(!mbOnlyTracking)
|
if(!mbOnlyTracking)
|
||||||
{
|
{
|
||||||
#ifdef SAVE_TIMES
|
|
||||||
std::chrono::steady_clock::time_point timeStartPosePredict = std::chrono::steady_clock::now();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// State OK
|
// State OK
|
||||||
// Local Mapping is activated. This is the normal behaviour, unless
|
// Local Mapping is activated. This is the normal behaviour, unless
|
||||||
|
@ -1761,13 +2030,6 @@ void Tracking::Track()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef SAVE_TIMES
|
|
||||||
std::chrono::steady_clock::time_point timeEndPosePredict = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
mTime_PosePred = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(timeEndPosePredict - timeStartPosePredict).count();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else // 纯定位模式,时间关系暂时不看 TOSEE
|
else // 纯定位模式,时间关系暂时不看 TOSEE
|
||||||
{
|
{
|
||||||
|
@ -1871,7 +2133,18 @@ void Tracking::Track()
|
||||||
if(!mCurrentFrame.mpReferenceKF)
|
if(!mCurrentFrame.mpReferenceKF)
|
||||||
mCurrentFrame.mpReferenceKF = mpReferenceKF;
|
mCurrentFrame.mpReferenceKF = mpReferenceKF;
|
||||||
|
|
||||||
// If we have an initial estimation of the camera pose and matching. Track the local map.
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_EndPosePred = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
double timePosePred = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndPosePred - time_StartPosePred).count();
|
||||||
|
vdPosePred_ms.push_back(timePosePred);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_StartLMTrack = std::chrono::steady_clock::now();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Step 7 在跟踪得到当前帧初始姿态后,现在对local map进行跟踪得到更多的匹配,并优化当前位姿
|
// Step 7 在跟踪得到当前帧初始姿态后,现在对local map进行跟踪得到更多的匹配,并优化当前位姿
|
||||||
// 前面只是跟踪一帧得到初始位姿,这里搜索局部关键帧、局部地图点,和当前帧进行投影匹配,得到更多匹配的MapPoints后进行Pose优化
|
// 前面只是跟踪一帧得到初始位姿,这里搜索局部关键帧、局部地图点,和当前帧进行投影匹配,得到更多匹配的MapPoints后进行Pose优化
|
||||||
// 在帧间匹配得到初始的姿态后,现在对local map进行跟踪得到更多的匹配,并优化当前位姿
|
// 在帧间匹配得到初始的姿态后,现在对local map进行跟踪得到更多的匹配,并优化当前位姿
|
||||||
|
@ -1883,17 +2156,8 @@ void Tracking::Track()
|
||||||
{
|
{
|
||||||
if(bOK)
|
if(bOK)
|
||||||
{
|
{
|
||||||
#ifdef SAVE_TIMES
|
|
||||||
std::chrono::steady_clock::time_point time_StartTrackLocalMap = std::chrono::steady_clock::now();
|
|
||||||
#endif
|
|
||||||
// 局部地图跟踪
|
// 局部地图跟踪
|
||||||
bOK = TrackLocalMap();
|
bOK = TrackLocalMap();
|
||||||
#ifdef SAVE_TIMES
|
|
||||||
std::chrono::steady_clock::time_point time_EndTrackLocalMap = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
mTime_LocalMapTrack = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndTrackLocalMap - time_StartTrackLocalMap).count();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if(!bOK)
|
if(!bOK)
|
||||||
|
@ -1978,13 +2242,19 @@ void Tracking::Track()
|
||||||
if(mCurrentFrame.mnId==(mnLastRelocFrameId+mnFramesToResetIMU))
|
if(mCurrentFrame.mnId==(mnLastRelocFrameId+mnFramesToResetIMU))
|
||||||
{
|
{
|
||||||
cout << "RESETING FRAME!!!" << endl;
|
cout << "RESETING FRAME!!!" << endl;
|
||||||
ResetFrameIMU();
|
|
||||||
}
|
}
|
||||||
else if(mCurrentFrame.mnId>(mnLastRelocFrameId+30))
|
else if(mCurrentFrame.mnId>(mnLastRelocFrameId+30))
|
||||||
mLastBias = mCurrentFrame.mImuBias; // 没啥用,后面会重新赋值后传给普通帧
|
mLastBias = mCurrentFrame.mImuBias; // 没啥用,后面会重新赋值后传给普通帧
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_EndLMTrack = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
double timeLMTrack = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndLMTrack - time_StartLMTrack).count();
|
||||||
|
vdLMTrack_ms.push_back(timeLMTrack);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Update drawer
|
// Update drawer
|
||||||
// 更新显示线程中的图像、特征点、地图点等信息
|
// 更新显示线程中的图像、特征点、地图点等信息
|
||||||
mpFrameDrawer->Update(this);
|
mpFrameDrawer->Update(this);
|
||||||
|
@ -2051,16 +2321,12 @@ void Tracking::Track()
|
||||||
// 不能够直接执行这个是因为其中存储的都是指针,之前的操作都是为了避免内存泄露
|
// 不能够直接执行这个是因为其中存储的都是指针,之前的操作都是为了避免内存泄露
|
||||||
mlpTemporalPoints.clear();
|
mlpTemporalPoints.clear();
|
||||||
|
|
||||||
#ifdef SAVE_TIMES
|
#ifdef REGISTER_TIMES
|
||||||
std::chrono::steady_clock::time_point timeStartNewKF = std::chrono::steady_clock::now();
|
std::chrono::steady_clock::time_point time_StartNewKF = std::chrono::steady_clock::now();
|
||||||
#endif
|
#endif
|
||||||
// 判断是否需要插入关键帧
|
// 判断是否需要插入关键帧
|
||||||
bool bNeedKF = NeedNewKeyFrame();
|
bool bNeedKF = NeedNewKeyFrame();
|
||||||
#ifdef SAVE_TIMES
|
|
||||||
std::chrono::steady_clock::time_point timeEndNewKF = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
mTime_NewKF_Dec = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(timeEndNewKF - timeStartNewKF).count();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -2073,6 +2339,13 @@ void Tracking::Track()
|
||||||
// 创建关键帧,对于双目或RGB-D会产生新的地图点
|
// 创建关键帧,对于双目或RGB-D会产生新的地图点
|
||||||
CreateNewKeyFrame();
|
CreateNewKeyFrame();
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_EndNewKF = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
double timeNewKF = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndNewKF - time_StartNewKF).count();
|
||||||
|
vdNewKF_ms.push_back(timeNewKF);
|
||||||
|
#endif
|
||||||
|
|
||||||
// We allow points with high innovation (considererd outliers by the Huber Function)
|
// We allow points with high innovation (considererd outliers by the Huber Function)
|
||||||
// pass to the new keyframe, so that bundle adjustment will finally decide
|
// pass to the new keyframe, so that bundle adjustment will finally decide
|
||||||
// if they are outliers or not. We don't want next frame to estimate its position
|
// if they are outliers or not. We don't want next frame to estimate its position
|
||||||
|
@ -2343,8 +2616,6 @@ void Tracking::MonocularInitialization()
|
||||||
|
|
||||||
CreateInitialMapMonocular();
|
CreateInitialMapMonocular();
|
||||||
|
|
||||||
// Just for video
|
|
||||||
// bStepByStep = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2581,7 +2852,6 @@ bool Tracking::TrackReferenceKeyFrame()
|
||||||
int nmatchesMap = 0;
|
int nmatchesMap = 0;
|
||||||
for(int i =0; i<mCurrentFrame.N; i++)
|
for(int i =0; i<mCurrentFrame.N; i++)
|
||||||
{
|
{
|
||||||
//if(i >= mCurrentFrame.Nleft) break;
|
|
||||||
if(mCurrentFrame.mvpMapPoints[i])
|
if(mCurrentFrame.mvpMapPoints[i])
|
||||||
{
|
{
|
||||||
if(mCurrentFrame.mvbOutlier[i])
|
if(mCurrentFrame.mvbOutlier[i])
|
||||||
|
@ -2781,8 +3051,24 @@ bool Tracking::TrackLocalMap()
|
||||||
// We retrieve the local map and try to find matches to points in the local map.
|
// We retrieve the local map and try to find matches to points in the local map.
|
||||||
mTrackedFr++;
|
mTrackedFr++;
|
||||||
|
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_StartLMUpdate = std::chrono::steady_clock::now();
|
||||||
|
#endif
|
||||||
UpdateLocalMap();
|
UpdateLocalMap();
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_StartSearchLP = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
double timeUpdatedLM_ms = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_StartSearchLP - time_StartLMUpdate).count();
|
||||||
|
vdUpdatedLM_ms.push_back(timeUpdatedLM_ms);
|
||||||
|
#endif
|
||||||
|
|
||||||
SearchLocalPoints();
|
SearchLocalPoints();
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_StartPoseOpt = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
double timeSearchLP_ms = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_StartPoseOpt - time_StartSearchLP).count();
|
||||||
|
vdSearchLP_ms.push_back(timeSearchLP_ms);
|
||||||
|
#endif
|
||||||
|
|
||||||
// TOO check outliers before PO
|
// TOO check outliers before PO
|
||||||
int aux1 = 0, aux2=0;
|
int aux1 = 0, aux2=0;
|
||||||
|
@ -2806,8 +3092,7 @@ bool Tracking::TrackLocalMap()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// if(!mbMapUpdated && mState == OK) // && (mnMatchesInliers>30))
|
if(!mbMapUpdated)
|
||||||
if(!mbMapUpdated) // && (mnMatchesInliers>30))
|
|
||||||
{
|
{
|
||||||
Verbose::PrintMess("TLM: PoseInertialOptimizationLastFrame ", Verbose::VERBOSITY_DEBUG);
|
Verbose::PrintMess("TLM: PoseInertialOptimizationLastFrame ", Verbose::VERBOSITY_DEBUG);
|
||||||
inliers = Optimizer::PoseInertialOptimizationLastFrame(&mCurrentFrame); // , !mpLastKeyFrame->GetMap()->GetIniertialBA1());
|
inliers = Optimizer::PoseInertialOptimizationLastFrame(&mCurrentFrame); // , !mpLastKeyFrame->GetMap()->GetIniertialBA1());
|
||||||
|
@ -2819,6 +3104,15 @@ bool Tracking::TrackLocalMap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef REGISTER_TIMES
|
||||||
|
std::chrono::steady_clock::time_point time_EndPoseOpt = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
double timePoseOpt_ms = std::chrono::duration_cast<std::chrono::duration<double,std::milli> >(time_EndPoseOpt - time_StartPoseOpt).count();
|
||||||
|
vdPoseOpt_ms.push_back(timePoseOpt_ms);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vnKeyFramesLM.push_back(mvpLocalKeyFrames.size());
|
||||||
|
vnMapPointsLM.push_back(mvpLocalMapPoints.size());
|
||||||
|
|
||||||
aux1 = 0, aux2 = 0;
|
aux1 = 0, aux2 = 0;
|
||||||
for(int i=0; i<mCurrentFrame.N; i++)
|
for(int i=0; i<mCurrentFrame.N; i++)
|
||||||
|
@ -3134,7 +3428,7 @@ void Tracking::CreateNewKeyFrame()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nPoints++; // TODO check ???
|
nPoints++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(vDepthIdx[j].first>mThDepth && nPoints>maxPoint)
|
if(vDepthIdx[j].first>mThDepth && nPoints>maxPoint)
|
||||||
|
@ -3226,7 +3520,7 @@ void Tracking::SearchLocalPoints()
|
||||||
th=5;
|
th=5;
|
||||||
|
|
||||||
if(mState==LOST || mState==RECENTLY_LOST) // Lost for less than 1 second
|
if(mState==LOST || mState==RECENTLY_LOST) // Lost for less than 1 second
|
||||||
th=15; // 15
|
th=15;
|
||||||
|
|
||||||
int matches = matcher.SearchByProjection(mCurrentFrame, mvpLocalMapPoints, th, mpLocalMapper->mbFarPoints, mpLocalMapper->mThFarPoints);
|
int matches = matcher.SearchByProjection(mCurrentFrame, mvpLocalMapPoints, th, mpLocalMapper->mbFarPoints, mpLocalMapper->mThFarPoints);
|
||||||
}
|
}
|
||||||
|
@ -3314,7 +3608,6 @@ void Tracking::UpdateLocalKeyFrames()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// MODIFICATION
|
|
||||||
mLastFrame.mvpMapPoints[i]=NULL;
|
mLastFrame.mvpMapPoints[i]=NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3350,7 +3643,7 @@ void Tracking::UpdateLocalKeyFrames()
|
||||||
for(vector<KeyFrame*>::const_iterator itKF=mvpLocalKeyFrames.begin(), itEndKF=mvpLocalKeyFrames.end(); itKF!=itEndKF; itKF++)
|
for(vector<KeyFrame*>::const_iterator itKF=mvpLocalKeyFrames.begin(), itEndKF=mvpLocalKeyFrames.end(); itKF!=itEndKF; itKF++)
|
||||||
{
|
{
|
||||||
// Limit the number of keyframes
|
// Limit the number of keyframes
|
||||||
if(mvpLocalKeyFrames.size()>80) // 80
|
if(mvpLocalKeyFrames.size()>80)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
KeyFrame* pKF = *itKF;
|
KeyFrame* pKF = *itKF;
|
||||||
|
@ -3747,12 +4040,9 @@ void Tracking::ResetActiveMap(bool bLocMap)
|
||||||
// Clear Map (this erase MapPoints and KeyFrames)
|
// Clear Map (this erase MapPoints and KeyFrames)
|
||||||
mpAtlas->clearMap();
|
mpAtlas->clearMap();
|
||||||
|
|
||||||
|
|
||||||
//KeyFrame::nNextId = mpAtlas->GetLastInitKFid();
|
|
||||||
//Frame::nNextId = mnLastInitFrameId;
|
|
||||||
mnLastInitFrameId = Frame::nNextId;
|
mnLastInitFrameId = Frame::nNextId;
|
||||||
mnLastRelocFrameId = mnLastInitFrameId;
|
mnLastRelocFrameId = mnLastInitFrameId;
|
||||||
mState = NO_IMAGES_YET; //NOT_INITIALIZED;
|
mState = NO_IMAGES_YET;
|
||||||
|
|
||||||
if(mpInitializer)
|
if(mpInitializer)
|
||||||
{
|
{
|
||||||
|
@ -3761,7 +4051,6 @@ void Tracking::ResetActiveMap(bool bLocMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
list<bool> lbLost;
|
list<bool> lbLost;
|
||||||
// lbLost.reserve(mlbLost.size());
|
|
||||||
unsigned int index = mnFirstFrameId;
|
unsigned int index = mnFirstFrameId;
|
||||||
cout << "mnFirstFrameId = " << mnFirstFrameId << endl;
|
cout << "mnFirstFrameId = " << mnFirstFrameId << endl;
|
||||||
for(Map* pMap : mpAtlas->GetAllMaps())
|
for(Map* pMap : mpAtlas->GetAllMaps())
|
||||||
|
@ -3773,7 +4062,6 @@ void Tracking::ResetActiveMap(bool bLocMap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//cout << "First Frame id: " << index << endl;
|
|
||||||
int num_lost = 0;
|
int num_lost = 0;
|
||||||
cout << "mnInitialFrameId = " << mnInitialFrameId << endl;
|
cout << "mnInitialFrameId = " << mnInitialFrameId << endl;
|
||||||
|
|
||||||
|
|
|
@ -145,15 +145,12 @@ void Viewer::Run()
|
||||||
pangolin::Var<bool> menuFollowCamera("menu.Follow Camera",true,true);
|
pangolin::Var<bool> menuFollowCamera("menu.Follow Camera",true,true);
|
||||||
pangolin::Var<bool> menuCamView("menu.Camera View",false,false);
|
pangolin::Var<bool> menuCamView("menu.Camera View",false,false);
|
||||||
pangolin::Var<bool> menuTopView("menu.Top View",false,false);
|
pangolin::Var<bool> menuTopView("menu.Top View",false,false);
|
||||||
// pangolin::Var<bool> menuSideView("menu.Side View",false,false);
|
|
||||||
pangolin::Var<bool> menuShowPoints("menu.Show Points",true,true);
|
pangolin::Var<bool> menuShowPoints("menu.Show Points",true,true);
|
||||||
pangolin::Var<bool> menuShowKeyFrames("menu.Show KeyFrames",true,true);
|
pangolin::Var<bool> menuShowKeyFrames("menu.Show KeyFrames",true,true);
|
||||||
pangolin::Var<bool> menuShowGraph("menu.Show Graph",false,true);
|
pangolin::Var<bool> menuShowGraph("menu.Show Graph",false,true);
|
||||||
pangolin::Var<bool> menuShowInertialGraph("menu.Show Inertial Graph",true,true);
|
pangolin::Var<bool> menuShowInertialGraph("menu.Show Inertial Graph",true,true);
|
||||||
pangolin::Var<bool> menuLocalizationMode("menu.Localization Mode",false,true);
|
pangolin::Var<bool> menuLocalizationMode("menu.Localization Mode",false,true);
|
||||||
pangolin::Var<bool> menuReset("menu.Reset",false,false);
|
pangolin::Var<bool> menuReset("menu.Reset",false,false);
|
||||||
pangolin::Var<bool> menuStepByStep("menu.Step By Step",false,true); // false, true
|
|
||||||
pangolin::Var<bool> menuStep("menu.Step",false,false);
|
|
||||||
|
|
||||||
// Define Camera Render Object (for view / scene browsing)
|
// Define Camera Render Object (for view / scene browsing)
|
||||||
pangolin::OpenGlRenderState s_cam(
|
pangolin::OpenGlRenderState s_cam(
|
||||||
|
@ -192,7 +189,6 @@ void Viewer::Run()
|
||||||
|
|
||||||
if(mbStopTrack)
|
if(mbStopTrack)
|
||||||
{
|
{
|
||||||
menuStepByStep = true;
|
|
||||||
mbStopTrack = false;
|
mbStopTrack = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,21 +233,11 @@ void Viewer::Run()
|
||||||
{
|
{
|
||||||
menuTopView = false;
|
menuTopView = false;
|
||||||
bCameraView = false;
|
bCameraView = false;
|
||||||
/*s_cam.SetProjectionMatrix(pangolin::ProjectionMatrix(1024,768,3000,3000,512,389,0.1,1000));
|
|
||||||
s_cam.SetModelViewMatrix(pangolin::ModelViewLookAt(0,0.01,10, 0,0,0,0.0,0.0, 1.0));*/
|
|
||||||
s_cam.SetProjectionMatrix(pangolin::ProjectionMatrix(1024,768,3000,3000,512,389,0.1,10000));
|
s_cam.SetProjectionMatrix(pangolin::ProjectionMatrix(1024,768,3000,3000,512,389,0.1,10000));
|
||||||
s_cam.SetModelViewMatrix(pangolin::ModelViewLookAt(0,0.01,50, 0,0,0,0.0,0.0, 1.0));
|
s_cam.SetModelViewMatrix(pangolin::ModelViewLookAt(0,0.01,50, 0,0,0,0.0,0.0, 1.0));
|
||||||
s_cam.Follow(Ow);
|
s_cam.Follow(Ow);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if(menuSideView && mpMapDrawer->mpAtlas->isImuInitialized())
|
|
||||||
{
|
|
||||||
s_cam.SetProjectionMatrix(pangolin::ProjectionMatrix(1024,768,3000,3000,512,389,0.1,10000));
|
|
||||||
s_cam.SetModelViewMatrix(pangolin::ModelViewLookAt(0.0,0.1,30.0,0,0,0,0.0,0.0,1.0));
|
|
||||||
s_cam.Follow(Twwp);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
if(menuLocalizationMode && !bLocalizationMode)
|
if(menuLocalizationMode && !bLocalizationMode)
|
||||||
{
|
{
|
||||||
mpSystem->ActivateLocalizationMode();
|
mpSystem->ActivateLocalizationMode();
|
||||||
|
@ -263,24 +249,6 @@ void Viewer::Run()
|
||||||
bLocalizationMode = false;
|
bLocalizationMode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(menuStepByStep && !bStepByStep)
|
|
||||||
{
|
|
||||||
mpTracker->SetStepByStep(true);
|
|
||||||
bStepByStep = true;
|
|
||||||
}
|
|
||||||
else if(!menuStepByStep && bStepByStep)
|
|
||||||
{
|
|
||||||
mpTracker->SetStepByStep(false);
|
|
||||||
bStepByStep = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(menuStep)
|
|
||||||
{
|
|
||||||
mpTracker->mbStep = true;
|
|
||||||
menuStep = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
d_cam.Activate(s_cam);
|
d_cam.Activate(s_cam);
|
||||||
glClearColor(1.0f,1.0f,1.0f,1.0f);
|
glClearColor(1.0f,1.0f,1.0f,1.0f);
|
||||||
mpMapDrawer->DrawCurrentCamera(Twc);
|
mpMapDrawer->DrawCurrentCamera(Twc);
|
||||||
|
@ -317,7 +285,6 @@ void Viewer::Run()
|
||||||
bLocalizationMode = false;
|
bLocalizationMode = false;
|
||||||
bFollow = true;
|
bFollow = true;
|
||||||
menuFollowCamera = true;
|
menuFollowCamera = true;
|
||||||
//mpSystem->Reset();
|
|
||||||
mpSystem->ResetActiveMap();
|
mpSystem->ResetActiveMap();
|
||||||
menuReset = false;
|
menuReset = false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue