로그
2025/10/31 📅
- ORB-SLAM2 환경 설정 내용 추가
2025/12/05 📅
- KITTI, TUM dataset을 이용한 예제 실습 내용 추가
- ros 연동 시도 → 실패
2025/12/20 📅
- KITTI, TUM dataset 관련 명령어 입력 수정
- 각 시퀀스별로 올바른 카메라 파라미터 및 associate file로 수정
- TUM dataset을 이용한 RGB-D SLAM 영상 추가
- Dense Map Reconstruction 내용 추가
환경 설정
과정
- conda 환경 설정
conda create -n orb-slam_env python=3.8 -y conda activate orb-slam_env
- 의존성 패키지 설치
사전 준비
sudo apt install build-essential cmake git pkg-config libgtk-3-dev \ libavcodec-dev libavformat-dev libswscale-dev libv4l-dev \ libxvidcore-dev libx264-dev libjpeg-dev libpng-dev libtiff-dev \ gfortran openexr libatlas-base-dev python3-dev python3-numpy \ libtbb2 libtbb-dev libdc1394-22-dev
opencv
- 기존에 설치되어있던 버전 삭제
sudo apt purge -y 'libopencv*' 'opencv*' sudo apt autoremove -y pip3 show opencv-python opencv-python-headless opencv-contrib-python opencv-contrib-python-headless pip3 uninstall -y opencv-python opencv-python-headless opencv-contrib-python opencv-contrib-python-headless # 해당 환경 활성화 후 conda remove -y opencv opencv-python # 남은 의존 패키지 정리(선택) conda clean -a -y
- 잘 삭제되었는지 확인
# pkg-config로 확인(없어야 정상) pkg-config --modversion opencv4 2>/dev/null || echo "opencv4 not found (OK)" # 파이썬에서 확인(없어야 정상) python3 - <<'PY' import importlib.util print(importlib.util.find_spec("cv2")) PY
- 3.4.9 버전 설치
git clone https://github.com/opencv/opencv.git git clone https://github.com/opencv/opencv_contrib.git cd opencv_contrib git checkout 3.4.9 cd ../opencv git checkout 3.4.9 mkdir build && cd build cmake -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules .. make -j8 sudo make install sudo ldconfig cmake -D CMAKE_BUILD_TYPE=RELEASE \ -D CMAKE_INSTALL_PREFIX=/usr/local \ -D WITH_TBB=ON \ -D ENABLE_FAST_MATH=1 \ -D CUDA_FAST_MATH=1 \ -D WITH_CUBLAS=1 \ -D WITH_CUDA=ON \ -D BUILD_opencv_cudacodec=OFF \ -D WITH_CUDNN=ON \ -D OPENCV_DNN_CUDA=ON \ -D CUDA_ARCH_BIN=7.5 \ -D WITH_V4L=ON \ -D WITH_QT=OFF \ -D WITH_OPENGL=ON \ -D WITH_GSTREAMER=ON \ -D OPENCV_GENERATE_PKGCONFIG=ON \ -D OPENCV_PC_FILE_NAME=opencv.pc \ -D OPENCV_ENABLE_NONFREE=ON \ -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules \ -D INSTALL_PYTHON_EXAMPLES=OFF \ -D INSTALL_C_EXAMPLES=OFF \ -D BUILD_EXAMPLES=OFF .. \ -D PYTHON3_INCLUDE_DIR=/usr/include/python3.8 \ -D PYTHON3_NUMPY_INCLUDE_DIRS=/usr/lib/python3/dist-packages/numpy/core/include/ \ -D PYTHON3_PACKAGES_PATH=/usr/lib/python3/dist-packages \ -D PYTHON3_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.8.so ..
- cv_bridge도 마찬가지로 설치
# 0) ROS 기본 환경 source /opt/ros/noetic/setup.bash # 1) catkin 도구 없으면 설치 sudo apt update sudo apt install -y python3-catkin-tools python3-rosdep # 2) OpenCV 3.4.9 경로(당신이 설치한 경로에 맞게) export OpenCV_DIR=/opt/opencv-3.4.9/share/OpenCV export LD_LIBRARY_PATH=/opt/opencv-3.4.9/lib:$LD_LIBRARY_PATH export PKG_CONFIG_PATH=/opt/opencv-3.4.9/lib/pkgconfig:$PKG_CONFIG_PATH # 3) 오버레이 워크스페이스 생성 (cv_bridge만 빌드) mkdir -p ~/cv_bridge_ws/src cd ~/cv_bridge_ws/src git clone -b noetic https://github.com/ros-perception/vision_opencv.git cd .. # 4) rosdep로 의존 설치 (opencv 관련 키는 건너뛰어 OpenCV4 끌려오는 것 방지) rosdep update rosdep install --from-paths src --ignore-src -r -y \ --skip-keys="opencv opencv3 libopencv-dev" # 5) OpenCV3를 가리키도록 CMake 인자 주고 빌드 catkin config --extend /opt/ros/noetic --cmake-args -DOpenCV_DIR=$OpenCV_DIR catkin build cv_bridge image_geometry # 6) 이 오버레이를 활성화 source ~/cv_bridge_ws/devel/setup.bash # 7) 확인: 이제 cv_bridge가 보여야 함 rospack find cv_bridge || echo "cv_bridge 여전히 안보임"
- 기존에 설치되어있던 버전 삭제
eigen
- eigen3 설치
sudo apt install libeigen3-dev
- eigen3 설치
pangolin ⭐
여기서 한 번이라도 실수하면 빌드가 실패하니, 꼭 꼼꼼히 수정해주세요!
git clone --recursive https://github.com/stevenlovegrove/Pangolin.git cd Pangolin code .catch2관련 오류를 피하기 위해Pangolin/scripts/install_prerequisites.sh파일에서if문 중에“apt”관련 부분에 있는PKGS_RECOMMENDED+=(libjpeg-dev libpng-dev catch2)를 주석처리
install_prerequisites.sh파일 실행./scripts/install_prerequisites.sh recommended
- 아까 위에서
catch2오류를 피하기 위한 줄을 다시 주석해제 해주고, branch 버전 교체# 현재 ~/your_ws/src/Pangolin에 있다고 가정 git checkout v0.5- 여기서 주의할 점은 위에서 미리 branch를 바꾸면 안됨 (만약 바꾸게 되면
install_prerequisites.sh파일이 사라짐)
- 여기서 주의할 점은 위에서 미리 branch를 바꾸면 안됨 (만약 바꾸게 되면
여기서부터 내부 파일 수정이 이루어지니 차근차근 꼼꼼히 진행 바랍니다 ⭐⭐⭐
Pangolin/CMakeModules/FindFFMPEG.cmake파일에서 대략 #63, #64번째 줄에 있는 아래 코드를sizeof(AVFormatContext::max_analyze_duration2); }" HAVE_FFMPEG_MAX_ANALYZE_DURATION2아래 코드로 수정
sizeof(AVFormatContext::max_analyze_duration); }" HAVE_FFMPEG_MAX_ANALYZE_DURATION
Pangolin/src/video/drivers/ffmpeg.cpp파일에서 대략 #37번째 줄(namespace pangolin바로 윗줄)에 아래 코드를 추가#define CODEC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER추가적으로 대략 #78, #79번째 줄에 있는 아래 코드를
TEST_PIX_FMT_RETURN(XVMC_MPEG2_MC); TEST_PIX_FMT_RETURN(XVMC_MPEG2_IDCT);아래 코드로 수정
#ifdef FF_API_XVMC TEST_PIX_FMT_RETURN(XVMC_MPEG2_MC); TEST_PIX_FMT_RETURN(XVMC_MPEG2_IDCT); #endif
대략 #101번째에서 #105번째에 있는 아래 코드도TEST_PIX_FMT_RETURN(VDPAU_H264); TEST_PIX_FMT_RETURN(VDPAU_MPEG1); TEST_PIX_FMT_RETURN(VDPAU_MPEG2); TEST_PIX_FMT_RETURN(VDPAU_WMV3); TEST_PIX_FMT_RETURN(VDPAU_VC1);아래 코드로 수정
#ifdef FF_API_VDPAU TEST_PIX_FMT_RETURN(VDPAU_H264); TEST_PIX_FMT_RETURN(VDPAU_MPEG1); TEST_PIX_FMT_RETURN(VDPAU_MPEG2); TEST_PIX_FMT_RETURN(VDPAU_WMV3); TEST_PIX_FMT_RETURN(VDPAU_VC1); #endif
마지막으로 대략 #127번째 줄에 있는 아래 코드를TEST_PIX_FMT_RETURN(VDPAU_MPEG4);아래 코드로 수정
#ifdef FF_API_VDPAU TEST_PIX_FMT_RETURN(VDPAU_MPEG4); #endif
Pangolin/include/pangolin/video/drivers/ffmpeg.h파일에서 대략 #53번째 줄(namespace pangolin바로 윗줄)에 아래 코드를 추가#define AV_CODEC_FLAG_GLOBAL_HEADER (1 << 22) #define CODEC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER #define AVFMT_RAWPICTURE 0x0020
Pangolin/src/display/device/display_x11.cpp파일에서 대략 #115번째 줄에 있는 아래 코드를GLXFBConfig* fbc = glXChooseFBConfig(display, DefaultScreen(display), visual_attribs, &fbcount);아래 코드로 수정
GLXFBConfig* fbc = glXGetFBConfigs(display, DefaultScreen(display), &fbcount);
추가적으로 대략 #115번째 줄에 있는 아래 코드를
{ throw std::runtime_error("Pangolin in X11: ..."); }아래 코드처럼 주석처리
{ // throw std::runtime_error("Pangolin in X11: ..."); }여기서부터는 빌드 과정입니다
- Pangolin 빌드
# 현재 ~/your_ws/src/Pangolin에 있다고 가정 cmake -B build cmake --build build cd build sudo make install
orb-slam2 설치
git clone https://github.com/raulmur/ORB_SLAM2.git ORB_SLAM2 cd ORB_SLAM2 code .ORB_SLAM2/include/System.h파일에서#include <unistd.h>추가#ifndef SYSTEM_H #define SYSTEM_H #include <unistd.h> // 추가 #include <string>
ORB_SLAM2/include/LoopClosing.h파일에서 대략 #49, #50번째 줄에 있는 아래 코드를typedef map<KeyFrame*,g2o::Sim3,std::less<KeyFrame*>, Eigen::aligned_allocator<std::pair<const KeyFrame*, g2o::Sim3> > > KeyFrameAndPose;아래 코드로 수정
typedef map<KeyFrame*,g2o::Sim3,std::less<KeyFrame*>, Eigen::aligned_allocator<std::pair<KeyFrame *const, g2o::Sim3> > > KeyFrameAndPose;
- orb-slam2 빌드
# 현재 ~/your_ws/src/ORB_SLAM2에 있다고 가정 chmod +x build.sh ./build.sh
위와 같이 잘 빌드가 된다면 성공!
ros1 연동
- Intel RealSense SDK 2.0 설치
sudo mkdir -p /etc/apt/keyrings curl -sSf https://librealsense.intel.com/Debian/librealsense.pgp | sudo tee /etc/apt/keyrings/librealsense.pgp > /dev/null echo "deb [signed-by=/etc/apt/keyrings/librealsense.pgp] https://librealsense.intel.com/Debian/apt-repo `lsb_release -cs` main" | \ sudo tee /etc/apt/sources.list.d/librealsense.list sudo apt-get update sudo apt-get install librealsense2-dkms librealsense2-utils librealsense2-dev librealsense2-dbg -y realsense-viewer
- Intel RealSense ROS 설치
# Create a catkin workspace Ubuntu mkdir -p ~/realsense-ros_ws/src cd ~/realsense-ros_ws/src/ # Intel RealSense ROS git clone https://github.com/IntelRealSense/realsense-ros.git cd realsense-ros/ git checkout `git tag | sort -V | grep -P "^2.\d+\.\d+" | tail -1`cd .. catkin_init_workspace cd .. catkin_make clean catkin_make -DCATKIN_ENABLE_TESTING=False -DCMAKE_BUILD_TYPE=Release catkin_make installecho "source ~/realsense-ros_ws/devel/setup.bash" >> ~/.bashrc source ~/.bashrc echo "source ~/realsense-ros_ws/devel/setup.zsh" >> ~/.zshrc source ~/.zshrc
- opencv 환경 설정 수정 및 확인
# 표준 ROS 먼저 source /opt/ros/noetic/setup.bash # 그 다음, 네가 빌드한 cv_bridge(3.4) 오버레이 source ~/opencv_ws/devel/setup.bash # 마지막으로 ORB_SLAM2 rosbuild 경로만 prepend (덮어쓰지 말기) export ROS_PACKAGE_PATH=$HOME/orb-slam_ws/src/ORB_SLAM2/Examples/ROS:$ROS_PACKAGE_PATH # 확인 rospack find cv_bridge # ← ~/cv_ws/... 를 가리켜야 함 ( /opt/ros/noetic 이면 실패) echo "$CMAKE_PREFIX_PATH" | tr ':' '\n' | head ./build_ros.sh
- Intel RealSense SDK 2.0 설치
- conda 환경 설정
예제 실습
Monocular Example - KITTI dataset
나는 00 시퀀스를 사용할 것이기 때문에, KITTI00-02.yaml 파일을 입력으로 넣어주었다.
# execute ORB-SLAM2
./Examples/Monocular/mono_kitti Vocabulary/ORBvoc.txt \
Examples/Monocular/KITTI00-02.yaml \
/home/wooseok/dataset/kitti/odometry/data_odometry_gray/dataset/sequences/00진행하면서 느낀건 orb descriptor를 통해 corner와 같은 특징을 잡아내는 모습을 visualization하여 볼 수 있어서 좋았구, 중간중간에 loop closure가 일어나는 모습도 확인할 수 있어서 신기했다.
아래는 실습한 코드가 어떻게 동작하는지 분석해본 것이다.
ORB-SLAM2 Code
# execute ORB-SLAM2 ./Examples/Monocular/mono_kitti \ Vocabulary/ORBvoc.txt \ Examples/Monocular/KITTI00-02.yaml \ /home/wooseok/dataset/kitti/odometry/data_odometry_gray/dataset/sequences/00위 명령어를 보면 총 3개의 입력을 받고 있으며, 각 입력을 살펴보겠다.
Vocabulary/ORBvoc.txt
해당 파일은 DBoW2 패키지를 통해 ORB descriptor를 tree구조로 변환한 visual vocabulary 이다. ORB-SLAM2 논문에 따르면 relocalization과 loop closure를 위해 사용되며, 장면(이미지) 전체의 특징을 빠르게 요약하여 비교하기 위해 사용된다고 한다. 
출처: Bags of Binary Words for Fast Place Recognition in Image Sequences https://github.com/dorian3d/DBoW2 에서 DBoW2 demo 파일을 제공해주고 있어서 간단한 실습을 진행해 보았다.
DBoW2
먼저 총 4개의 흑백 이미지가 준비되어 있었다.

DBoW2 demo 파일에서 사용하는 4개의 이미지 중 하나인 image0.png demo.cpp는 아래와 같은 함수들로 이루어져 있었다.
loadFeatures: 각 이미지들에 대한 ORB feature를 추출한다.changeStructure:loadFeatures내부에서 features 변수의 크기를 추출된 ORB descriptors의 개수로 맞춰준다.testVocCreation: K ^ L 크기의 vocabulary tree를 만들고 각 feature를 leaf node에 매핑한 후, TF-IDF weighting을 이용해 구한 가중치를 BowVector에 저장해준 뒤, L1-norm scoring을 통해 이미지들간의 score를 계산한다. 마지막으로 아까 만든 vocabulary를 저장한다.testDatabase:testVocCreation에서 저장한 vocabulary를 다시 로드하여 Image Retrieval을 진행한다.일단 패키지를 빌드 후 실행 파일을 열어보니 아래와 같은 결과를 얻을 수 있었다.

loadFeatures, testVocCreation의 결과 
testDatabase의 결과
Examples/Monocular/KITTI00-02.yaml%YAML:1.0 #-------------------------------------------------------------------------------------------- # Camera Parameters. Adjust them! #-------------------------------------------------------------------------------------------- # Camera calibration and distortion parameters (OpenCV) Camera.fx: 718.856 Camera.fy: 718.856 Camera.cx: 607.1928 Camera.cy: 185.2157 Camera.k1: 0.0 Camera.k2: 0.0 Camera.p1: 0.0 Camera.p2: 0.0 # Camera frames per second Camera.fps: 10.0 # Color order of the images (0: BGR, 1: RGB. It is ignored if images are grayscale) Camera.RGB: 1 #-------------------------------------------------------------------------------------------- # ORB Parameters #-------------------------------------------------------------------------------------------- # ORB Extractor: Number of features per image ORBextractor.nFeatures: 2000 # ORB Extractor: Scale factor between levels in the scale pyramid ORBextractor.scaleFactor: 1.2 # ORB Extractor: Number of levels in the scale pyramid ORBextractor.nLevels: 8 # ORB Extractor: Fast threshold # Image is divided in a grid. At each cell FAST are extracted imposing a minimum response. # Firstly we impose iniThFAST. If no corners are detected we impose a lower value minThFAST # You can lower these values if your images have low contrast ORBextractor.iniThFAST: 20 ORBextractor.minThFAST: 7 #-------------------------------------------------------------------------------------------- # Viewer Parameters #-------------------------------------------------------------------------------------------- Viewer.KeyFrameSize: 0.1 Viewer.KeyFrameLineWidth: 1 Viewer.GraphLineWidth: 1 Viewer.PointSize:2 Viewer.CameraSize: 0.15 Viewer.CameraLineWidth: 2 Viewer.ViewpointX: 0 Viewer.ViewpointY: -10 Viewer.ViewpointZ: -0.1 Viewer.ViewpointF: 2000
/home/wooseok/dataset/kitti/odometry/data_odometry_gray/dataset/sequences/00마지막은 내 로컬환경에 저장된 KITTI 데이터셋의 시퀀스 파일 주소이며, 이를 어떻게 파싱해서 사용한 것인지는 실행 파일에서 확인해 보겠다.
그러면 이제 실행 파일을 확인해 보자.
./Examples/Monocular/mono_kitti
위 코드를 보면
ORB_SLAM2namespace 안의System이라는 class 객체인SLAM을 정의하고 있다.그러면
System이라는 class는 어떤 역할을 할까?System.cc를 살펴보니 크게 아래와 같은 역할들을 수행하고 있었다.- 초기화 함수
- 센서 정보 확인 (monocular, stereo, RGB-D)
- ORB vocabulary 불러오기 (
ORBvoc.txt)
- 스레드 초기화 및 실행 (Tracking, LocalMapping, LoopClosing 등)
- 스레드 간 포인터 연결
- Tracking 함수
- 역할
- 현재 프레임의 camera pose를 계산
- 종류
- monocular, stereo, RGB-D
- 특징
- mode change (localization 활성/비활성)
- mutex lock (스레드 접근 관리용?)
- 역할
- Save Trajectory 함수
- 역할
- 모든 Keyframe의 camera pose를 world 좌표계 기준으로 복원하여 trajectory를 계산
- 종류
- TUM, KITTI
- 특징
- stereo나 RGB-D 입력에 대해서만 궤적 생성 가능
- reference frame이 삭제(cull)된 경우, spanning tree를 통해 부모 Keyframe으로 대체
- 역할
- 초기화 함수
(진행중…)
RGB-D Example - TUM dataset
- associate file
RGB-D 데이터셋(e.g. TUM)을 이용하려면 실행 명령어에 associate file을 같이 넣어줘야 한다.

위 그림에서 보이는 것처럼 ORB-SLAM2에서는 TUM 데이터셋의 여러 시퀀스들에 대한 associate file을 예시로 제공한다. 만약 위 예시에 없는 데이터셋을 이용한다면 아래 명령어를 통해 직접 생성해주자.
python associate.py PATH_TO_SEQUENCE/rgb.txt \ PATH_TO_SEQUENCE/depth.txt > associations.txt나는 freiburg1_room(fr1_room) 시퀀스를 이용할 것이기 때문에, 미리 만들어진 fr1_room.txt 파일을 그대로 사용했다.
(또한 freiburg1 관련 시퀀스는 TUM1.yaml을 써주면 된다)
- 명령어
# execute ORB-SLAM2 ./Examples/RGB-D/rgbd_tum Vocabulary/ORBvoc.txt \ Examples/RGB-D/TUM1.yaml \ /home/wooseok/dataset/tum/rgbd_dataset_freiburg1_room \ Examples/RGB-D/associations/fr1_room.txt
- 결과 (output)
- Dense Map Reconstruction
- 결과
사진



영상
voxel downsampling을 적용하니 렉이 사라졌다 (voxel_size = 0.05)
- 결과
카메라 실습
(예정)
이슈
ros 실습 (실패)
./build_ros.sh
이전에는 계속 오류나다가 갑자기 빌드가 성공해서 당황… (아마 opnecv 재빌드랑, 환경 변수 관련 설정을 다시 해주니 됐던 것 같다..) segmentation fault (core dumped)오류 발생…→ ros1 noetic 환경에서는 opencv 4.x 버전이 default로 동작하는 것 같아, 이후 아무리 시도해봐도 여기서 막혔다…
기타 이슈
undefined reference to symbol '_ZNK2cv8FileNodecviEv’# libopencv_{}.so를 ORB_SLAM2/lib에 복사 whereis libopencv_imgproc ls -l /usr/lib/x86_64-linux-gnu/libopencv_imgproc.so* ls -l /usr/lib/x86_64-linux-gnu/libopencv_core.so* sudo cp /usr/lib/x86_64-linux-gnu/libopencv_imgproc.so /home/wooseok/orb-slam_ws/src/ORB_SLAM2/lib sudo cp /usr/lib/x86_64-linux-gnu/libopencv_core.so /home/wooseok/orb-slam_ws/src/ORB_SLAM2/libORB_SLAM2/Examples/ROS/ORB_SLAM2/CMakeLists.txt수정# ORB_SLAM2/Examples/ROS/ORB_SLAM2/CMakeLists.txt 에 path 추가 # find_package(OpenCV 3.0 QUIET) # find_package(OpenCV 4.0 QUIET) find_package(OpenCV QUIET) set(LIBS ${PROJECT_SOURCE_DIR}/../../../lib/libORB_SLAM2.so # 아래 추가! ${PROJECT_SOURCE_DIR}/../../../lib/libopencv_core.so ${PROJECT_SOURCE_DIR}/../../../lib/libopencv_imgproc.so )☑️
cv_bridge관련 오류- CMakeLists.txt 파일에서 버전 4에서 3으로 낮추기
# 빌드할 opencv 버전 세팅 4 -> 3 set(_opencv_version 3) find_package(OpenCV 3 QUIET) # set(_opencv_version 4) # find_package(OpenCV 4 QUIET) if(NOT OpenCV_FOUND) message(STATUS "Did not find OpenCV 4, trying OpenCV 3") set(_opencv_version 3) endif()☑️
ros build관련 오류# opencv 재빌드 cd ~/opencv_ws/build rm -rf * cmake -D CMAKE_BUILD_TYPE=Release \ -D CMAKE_INSTALL_PREFIX=/usr/local \ -D WITH_QT=OFF \ -D WITH_GTK=ON \ -D WITH_OPENGL=ON \ ../src/opencv make -j$(nproc) sudo make install sudo ldconfig # ros 패키지 위치 관련 환경변수 설정 export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:/home/wooseok/orb-slam_ws/src/ORB_SLAM2/Examples/ROS☑️
rosrun명령어 관련segmentation fault오류- 아래
eigen 3.2.10버전이 잘 된다고 하여 기존eigen을 지우고 새로 설치해주었다
- 추가로
sudo apt install로 설치한게 아니어서, ORB SLAM2 패키지에서 수동으로 설치한eigen의 경로를 인식시키기 위해 따로 심볼릭 링크를 만들어주었다
sudo ln -s /home/wooseok/Downloads/eigen-3.2.10 /usr/include/eigen3opencv버전 호환때문에,ros연동은 포기…
Comments