https://github.com/HuajianUP/Photo-SLAM
0 安装依赖
1 | sudo apt install libeigen3 - dev libboost - all - dev libjsoncpp - dev libopengl - dev mesa - utils libglfw3 - dev libglm - dev |
支持的 LibTorch 版本最高为 2.1.2。如果你没有在 CMake 的系统搜索路径中安装 LibTorch,则需要添加其他选项来build.sh
帮助 CMake 找到 LibTorch。详情请参阅在build.sh
之前添加一行:find_package(Torch REQUIRED)
CMakeLists.txt
2选1安装,这里使用c++版本的。
[选项 1]
您可以下载 libtorch,例如cu118,然后将其解压到文件夹中./the_path_to_where_you_extracted_LibTorch
。
1 2 3 4 | # In a Terminal wget https: / / download.pytorch.org / libtorch / cu118 / libtorch - cxx11 - abi - shared - with - deps - 2.0 . 1 % 2Bcu118 . zip - O libtorch - cu118. zip unzip libtorch - cu118. zip - d . / the_path_to_where_you_extracted_LibTorch rm libtorch - cu118. zip |
cmake设置路径
1 2 | # In CMakeLists.txt set (Torch_DIR . / the_path_to_where_you_extracted_LibTorch / libtorch / share / cmake / Torch) |
自己的
1 | set (Torch_DIR "/home/dongdong/2project/1salm/Photo_SLAM/libtorch-cu118/libtorch/share/cmake/Torch" ) |
[选项 2]Conda。
如果你使用 Conda 来管理你的 Python 包,并且安装了兼容的 Pytorch,你可以设置
1 2 3 | # [For Jatson Orin] To install Pytorch in Jatson developer kit, you can run the below commands # export TORCH_INSTALL=https://developer.download.nvidia.com/compute/redist/jp/v511/pytorch/torch-2.0.0+nv23.05-cp38-cp38-linux_aarch64.whl # pip install --no-cache $TORCH_INSTALL |
cmake设置路径
1 | set (Torch_DIR / the_path_to_conda / python3.x / site - packages / torch / share / cmake / Torch) |
3 将 OpenCV 与 opencv_contrib 和 CUDA 结合使用
以 4.7.0 版本为例,查看OpenCV realeases和opencv_contrib,会找到OpenCV 4.7.0和对应的opencv_contrib 4.7.0,下载到同一目录(例如~/opencv
)并解压,
https://github.com/opencv/opencv/archive/refs/tags/4.7.0.tar.gz
https://github.com/opencv/opencv_contrib/archive/refs/tags/4.7.0.tar.gz
注意修改安装路径
1 | DCMAKE_INSTALL_PREFIX |
修改扩展库路径
1 | DOPENCV_EXTRA_MODULES_PATH |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | cmake - DCMAKE_BUILD_TYPE = RELEASE \ - DWITH_CUDA = ON \ - DWITH_CUDNN = ON \ - DOPENCV_DNN_CUDA = ON \ - DWITH_NVCUVID = ON \ - DCUDA_TOOLKIT_ROOT_DIR = / usr / local / cuda - 11.8 \ - DOPENCV_EXTRA_MODULES_PATH = "/home/dongdong/2project/1salm/Photo_SLAM/opencv47/opencv_contrib-4.7.0/modules" \ - DCMAKE_INSTALL_PREFIX = "/home/dongdong/2project/1salm/Photo_SLAM/opencv47/install_opencv47" \ - DBUILD_TIFF = ON \ - DBUILD_ZLIB = ON \ - DBUILD_JASPER = ON \ - DBUILD_CCALIB = ON \ - DBUILD_JPEG = ON \ - DWITH_FFMPEG = ON \ .. |
编译
sudo make -j30
安装
sudo make install
设置路径
set(OpenCV_DIR /your_preferred_path/lib/cmake/opencv4)
自己的路径
1 2 | # 设置自己的路径 set (OpenCV_DIR "/home/dongdong/2project/1salm/Photo_SLAM/opencv47/install_opencv47/lib/cmake/opencv4" ) |
修改1
修改2
报错问题1 忽略不管
安装工程Photo-SLAM
1 2 3 4 | git clone https: / / github.com / HuajianUP / Photo - SLAM.git cd Photo - SLAM / chmod + x . / build.sh . / build.sh |
编译过程 脚本自动执行,也可以跟着脚本手动执行,看看 哪一步除了问题。
先编译orb slam3的库和工程
然后编译photo工程
编译成功
如果需要删除某个文件夹
sudo rm -r build
测试脚本
执行权限
1 | sudo chmod + x . / * .sh |
1 2 3 4 5 6 7 | .. / bin / tum_mono \ .. / ORB - SLAM3 / Vocabulary / ORBvoc.txt \ .. / cfg / ORB_SLAM3 / Monocular / TUM / tum_freiburg1_desk.yaml \ 相机内参 需要改 .. / cfg / gaussian_mapper / Monocular / TUM / tum_mono.yaml \ 高斯训练参数 不用改 / home / rapidlab / dataset / VSLAM / TUM / rgbd_dataset_freiburg1_desk \ 数据地址 .. / results / tum_mono_$i / rgbd_dataset_freiburg1_desk \ 结果保存位置 no_viewer 是否可视化 |
自己改造的文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | / * * * This file is part of Photo - SLAM * * Copyright (C) 2023 - 2024 Longwei Li and Hui Cheng, Sun Yat - sen University. * Copyright (C) 2023 - 2024 Huajian Huang and Sai - Kit Yeung, Hong Kong University of Science and Technology. * * Photo - SLAM is free software: you can redistribute it and / or modify it under the terms of the GNU General Public * License as published by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Photo - SLAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with Photo - SLAM. * If not , see <http: / / www.gnu.org / licenses / >. * / #include <torch/torch.h> #include <iostream> #include <algorithm> #include <fstream> #include <chrono> #include <ctime> #include <sstream> #include <thread> #include <filesystem> #include <memory> #include <opencv2/core/core.hpp> #include "ORB-SLAM3/include/System.h" #include "include/gaussian_mapper.h" #include "viewer/imgui_viewer.h" void LoadImages(const std::string &strFile, std::vector<std::string> &vstrImageFilenames, std::vector<double> &vTimestamps); void LoadImages_DJI(const std::string &strFile, std::vector<std::string> &vstrImageFilenames, std::vector<double> &vTimestamps); void saveTrackingTime(std::vector< float > &vTimesTrack, const std::string &strSavePath); void saveGpuPeakMemoryUsage(std::filesystem::path pathSave); int main( int argc, char * * argv) { if (argc ! = 6 && argc ! = 7 ) { std::cerr << std::endl << "Usage: " << argv[ 0 ] << " path_to_vocabulary" / * 1 * / << " path_to_ORB_SLAM3_settings" / * 2 * / << " path_to_gaussian_mapping_settings" / * 3 * / << " path_to_sequence" / * 4 * / << " path_to_trajectory_output_directory/" / * 5 * / << " (optional)no_viewer" / * 6 * / << std::endl; return 1 ; } bool use_viewer = true; if (argc = = 7 ) use_viewer = (std::string(argv[ 6 ]) = = "no_viewer" ? false : true); std::string output_directory = std::string(argv[ 5 ]); if (output_directory.back() ! = '/' ) output_directory + = "/" ; std::filesystem::path output_dir(output_directory); / / Retrieve paths to images std::vector<std::string> vstrImageFilenamesRGB; std::vector<double> vTimestamps; / / std::string strFile = std::string(argv[ 4 ]) + "/rgb.txt" ; std::string strFile = std::string(argv[ 4 ]) + "/slam_config/gnss.txt" ; std::cout << "strFile: " << strFile << std::endl; LoadImages_DJI(strFile, vstrImageFilenamesRGB, vTimestamps); / / Check consistency in the number of images and depthmaps int nImages = vstrImageFilenamesRGB.size(); if (vstrImageFilenamesRGB.empty()) { std::cerr << std::endl << "No images found in provided path." << std::endl; return 1 ; } / / Device torch::DeviceType device_type; if (torch::cuda::is_available()) { std::cout << "CUDA available! Training on GPU." << std::endl; device_type = torch::kCUDA; } else { std::cout << "Training on CPU." << std::endl; device_type = torch::kCPU; } / / Create SLAM system. It initializes all system threads and gets ready to process frames. std::shared_ptr<ORB_SLAM3::System> pSLAM = std::make_shared<ORB_SLAM3::System>( argv[ 1 ], argv[ 2 ], ORB_SLAM3::System::MONOCULAR); float imageScale = pSLAM - >GetImageScale(); / / Create GaussianMapper std::filesystem::path gaussian_cfg_path(argv[ 3 ]); std::shared_ptr<GaussianMapper> pGausMapper = std::make_shared<GaussianMapper>( pSLAM, gaussian_cfg_path, output_dir, 0 , device_type); std::thread training_thd(&GaussianMapper::run, pGausMapper.get()); / / Create Gaussian Viewer std::thread viewer_thd; std::shared_ptr<ImGuiViewer> pViewer; if (use_viewer) { pViewer = std::make_shared<ImGuiViewer>(pSLAM, pGausMapper); viewer_thd = std::thread(&ImGuiViewer::run, pViewer.get()); } / / Vector for tracking time statistics std::vector< float > vTimesTrack; vTimesTrack.resize(nImages); std::cout << std::endl << "-------" << std::endl; std::cout << "Start processing sequence ..." << std::endl; std::cout << "Images in the sequence: " << nImages << std::endl << std::endl; / / Main loop cv::Mat im; for ( int ni = 0 ; ni < nImages; ni + + ) { if (pSLAM - >isShutDown()) break ; / / Read image and depthmap from file std::string image_name = std::string(argv[ 4 ]) + "/images/" + vstrImageFilenamesRGB[ni]; std::cout<< "image_name " << image_name << std::endl; if (std::filesystem::exists(image_name)) { std::cout << "文件存在!\n" ; } else { std::cout << "文件不存在!\n" ; continue ; } im = cv::imread(image_name, cv::IMREAD_UNCHANGED); / / ,cv::IMREAD_UNCHANGED); cv::cvtColor(im, im, CV_BGR2RGB); double tframe = vTimestamps[ni]; if (im.empty()) { std::cerr << std::endl << "Failed to load image at: " << std::string(argv[ 4 ]) << "/" << vstrImageFilenamesRGB[ni] << std::endl; return 1 ; } if (imageScale ! = 1.f ) { int width = im.cols * imageScale; int height = im.rows * imageScale; cv::resize(im, im, cv::Size(width, height)); } std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); / / Pass the image to the SLAM system pSLAM - >TrackMonocular(im, tframe, std::vector<ORB_SLAM3::IMU::Point>(), vstrImageFilenamesRGB[ni]); std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now(); double ttrack = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - t1).count(); vTimesTrack[ni] = ttrack; / / Wait to load the next frame double T = 0 ; if (ni < nImages - 1 ) T = vTimestamps[ni + 1 ] - tframe; else if (ni > 0 ) T = tframe - vTimestamps[ni - 1 ]; if (ttrack < T) usleep((T - ttrack) * 1e6 ); } / / Stop all threads pSLAM - >Shutdown(); training_thd.join(); if (use_viewer) viewer_thd.join(); / / GPU peak usage saveGpuPeakMemoryUsage(output_dir / "GpuPeakUsageMB.txt" ); / / Tracking time statistics saveTrackingTime(vTimesTrack, (output_dir / "TrackingTime.txt" ).string()); / / Save camera trajectory pSLAM - >SaveTrajectoryTUM((output_dir / "CameraTrajectory_TUM.txt" ).string()); pSLAM - >SaveKeyFrameTrajectoryTUM((output_dir / "KeyFrameTrajectory_TUM.txt" ).string()); pSLAM - >SaveTrajectoryEuRoC((output_dir / "CameraTrajectory_EuRoC.txt" ).string()); pSLAM - >SaveKeyFrameTrajectoryEuRoC((output_dir / "KeyFrameTrajectory_EuRoC.txt" ).string()); / / pSLAM - >SaveTrajectoryKITTI((output_dir / "CameraTrajectory_KITTI.txt" ).string()); return 0 ; } double time_stamp = 0 ; void LoadImages_DJI(const std::string &strFile, std::vector<std::string> &vstrImageFilenames, std::vector<double> &vTimestamps) { std::ifstream file (strFile); / / 打开txt文件 if (! file ) { std::cerr << "无法打开文件!" << std::endl; } std::string line; while (std::getline( file , line)) { / / 逐行读取文件 std::istringstream ss(line); / / 使用 stringstream 解析每一行 std::string image_name; vTimestamps.push_back(time_stamp); time_stamp = time_stamp + 2 ; / / 秒一张 ss >> image_name; / / 提取第一列图像名称 vstrImageFilenames.push_back(image_name); std::cout<< "time_stamp " << time_stamp << " 名字 " << image_name << std::endl; } } void LoadImages(const std::string &strFile, std::vector<std::string> &vstrImageFilenames, std::vector<double> &vTimestamps) { ifstream f; f. open (strFile.c_str()); / / skip first three lines string s0; std::getline(f,s0); std::getline(f,s0); std::getline(f,s0); while (!f.eof()) { std::string s; std::getline(f,s); if (!s.empty()) { std::stringstream ss; ss << s; double t; std::string sRGB; ss >> t; vTimestamps.push_back(t); ss >> sRGB; vstrImageFilenames.push_back(sRGB); } } } void saveTrackingTime(std::vector< float > &vTimesTrack, const std::string &strSavePath) { std::ofstream out; out. open (strSavePath.c_str()); std::size_t nImages = vTimesTrack.size(); float totaltime = 0 ; for ( int ni = 0 ; ni < nImages; ni + + ) { out << std::fixed << std::setprecision( 4 ) << vTimesTrack[ni] << std::endl; totaltime + = vTimesTrack[ni]; } / / std::sort(vTimesTrack.begin(), vTimesTrack.end()); / / out << "-------" << std::endl; / / out << std::fixed << std::setprecision( 4 ) / / << "median tracking time: " << vTimesTrack[nImages / 2 ] << std::endl; / / out << std::fixed << std::setprecision( 4 ) / / << "mean tracking time: " << totaltime / nImages << std::endl; out.close(); } void saveGpuPeakMemoryUsage(std::filesystem::path pathSave) { namespace c10Alloc = c10::cuda::CUDACachingAllocator; c10Alloc::DeviceStats mem_stats = c10Alloc::getDeviceStats( 0 ); c10Alloc::Stat reserved_bytes = mem_stats.reserved_bytes[static_cast< int >(c10Alloc::StatType::AGGREGATE)]; float max_reserved_MB = reserved_bytes.peak / ( 1024.0 * 1024.0 ); c10Alloc::Stat alloc_bytes = mem_stats.allocated_bytes[static_cast< int >(c10Alloc::StatType::AGGREGATE)]; float max_alloc_MB = alloc_bytes.peak / ( 1024.0 * 1024.0 ); std::ofstream out(pathSave); out << "Peak reserved (MB): " << max_reserved_MB << std::endl; out << "Peak allocated (MB): " << max_alloc_MB << std::endl; out.close(); } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
2023-12-02 IMU eskf使用
2023-12-02 路由器拨号上网
2021-12-02 (1)打印过程
2021-12-02 jetson nx系统卡备份和烧录
2021-12-02 Jetson Xavier/NX/Nano 采用SSD或SD卡为系统盘
2021-12-02 论文编写工具使用(0)写作工具汇总