2021년 8월 21일 토요일

카메라 영상에서 3차원 공간 데이터 생성을 위한 Visual SLAM 알고리즘 ORB SLAM3 빌드 및 사용하기

이 글은 카메라 사진만으로 3차원 SLAM을 수행하여, 공간 모델을 생성하는 Visual SLAM의 대표적인 알고리즘인 ORB SLAM3를 설치, 빌드하고 사용하는 방법을 간략히 설명한다. 이 기술은 카메라 비전기반으로 동작하는 자율주행장비, 네비게이션, 3차원 공간정보 생성 등에 사용할 수 있다.
ORB-SLAM 실행 결과

참고로, Visual SLAM 알고리즘은 영상의 각 프레임 이미지에서 고유의 특징점(Feature)을 얻는 것부터 시작된다. 각 프레임에서 동일한 특징점들에서 카메라의 위치와 방향을 추정한다. 다수의 동일한 특징점들로부터 카메라의 위치와 방향을 얻은 후, 이를 역으로 이용해, 각 프레임의 이미지 정보와 특징점 정보를 이용해 포인트 클라우드 맵을 생성할 수 있다. 이 과정에서 계산기하학, 복잡한 수치해석이 사용된다. 다음 그림은 이 과정을 보여준다.
특징점 기반 Visual SLAM 알고리즘(상세)

개발 환경 설치
다음과 같이 개발 환경을 미리 설치한다.

1. Ubuntu 20.04 설치
여기를 참고해, 우분투 운영체제를 먼저 설치한다.

2. OpenCV 설치
git clone https://github.com/opencv/opencv/
git clone https://github.com/opencv/opencv_contrib/
mkdir opencv/build/
cd opencv/build/
cmake -DOPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules ..
make -j8
sudo make install

3. Pangolin 설치
git clone https://github.com/stevenlovegrove/Pangolin.git
cd Pangolin
mkdir build
cd build
cmake ..
cmake --build .
4. ORB_SLAM3 설치
git clone https://github.com/UZ-SLAMLab/ORB_SLAM3.git ORB_SLAM3
cd ORB_SLAM3
chmod +x build.sh
./build.sh

이때 다음과 같은 메이크 에러가 발생할 수 있다.
/home/ktw/Projects/ORB_SLAM3/src/CameraModels/KannalaBrandt8.cpp:534:41: error: no match for ‘operator/’ (operand types are ‘cv::Matx<float, 3, 1>’ and ‘float’)
...
/home/ktw/Projects/ORB_SLAM3/src/LocalMapping.cc:628:49: error: no match for ‘operator/’ (operand types are ‘cv::Matx<float, 3, 1>’ and ‘float’)

이는 OpenCV 행렬 계산 operator / 연산자가 누락되어 발생한 것이므로, 아래와 같이 에러가 발생한 파일을 편집해, 연산자 구현을 추가해 준다. 그리고 다시 빌드한다.
// Fix by Taewook Kang.
namespace cv
{
    template<typename _Tp, int m, int n> static inline
    Matx<_Tp, m, n> operator / (const Matx<_Tp, m, n> &a, float alpha)
    {
        return Matx<_Tp, m, n>(a, 1.f / alpha, Matx_ScaleOp());
    }
}

그럼, 다음과 같이 ORB_SLAM3를 성공적으로 빌드할 수 있을 것이다.

ORB SLAM3 실행하기
우선 다음 테스트 영상 이미지 데이터를 다운로드 받는다. 참고로, 다른 테스트 파일은 여기를 방문해 다운로드할 수 있다. 이 테스트 영상은 영상 이미지와 관성 센서 데이터가 기록되어 있다.
압축파일을 폴더에 해제한다. 그리고, 아래 파일을 편집한다.
Examples\euroc_examples.sh 

euroc_examples.sh 파일 내 아래 데이터셋 경로를 압축 해제한 폴더로 설정후 저장한다. 
pathDatasetEuroc='/home/ktw/Projects/ORB_SLAM3/data''

참고로, 다운로드 받은 데이터셋은 MH_03이므로, 다음과 같이 해당 예제 실행 부분만 실행되도록 euroc_examples.sh 파일을 편집한다.
#!/bin/bash
pathDatasetEuroc='/home/ktw/Projects/ORB_SLAM3/data' #Example, it is necesary to change it by the dataset path

#------------------------------------
# Monocular Examples
# echo "Launching MH01 with Monocular sensor"
# ./Monocular/mono_euroc ../Vocabulary/ORBvoc.txt ./Monocular/EuRoC.yaml "$pathDatasetEuroc"/MH01 ./Monocular/EuRoC_TimeStamps/MH01.txt dataset-MH01_mono

# echo "Launching MH02 with Monocular sensor"
# ./Monocular/mono_euroc ../Vocabulary/ORBvoc.txt ./Monocular/EuRoC.yaml "$pathDatasetEuroc"/MH02 ./Monocular/EuRoC_TimeStamps/MH02.txt dataset-MH02_mono

echo "Launching MH03 with Monocular sensor"
./Monocular/mono_euroc ../Vocabulary/ORBvoc.txt ./Monocular/EuRoC.yaml "$pathDatasetEuroc"/MH03 ./Monocular/EuRoC_TimeStamps/MH03.txt dataset-MH03_mono

이제 euroc_examples.sh 을 실행한다. 그럼, 다음과 같은 Visual SLAM 결과를 얻을 수 있다.

스테레오 이미지에서 SLAM테스트를 위해 아래 명령을 실행한다.
mkdir -p Datasets/EuRoc
cd Datasets/EuRoc/
wget -c http://robotics.ethz.ch/~asl-datasets/ijrr_euroc_mav_dataset/machine_hall/MH_01_easy/MH_01_easy.zip
mkdir MH01
unzip MH_01_easy.zip -d MH01/

cd ..
cd ..
./Examples/Stereo/stereo_euroc ./Vocabulary/ORBvoc.txt ./Examples/Stereo/EuRoC.yaml ./Datasets/EuRoc/MH01 ./Examples/Stereo/EuRoC_TimeStamps/MH01.txt dataset-MH01_stereo

결과는 다음과 같이 잘 동작되는 것을 확인할 수 있다.

참고로, 스테레오 이미지에서 SLAM 처리는 다음과 같이 ROS(Robot Operating System)를 이용해 실행할 수 있다.
rosrun ORB_SLAM3 Stereo PATH_TO_VOCABULARY PATH_TO_SETTINGS_FILE ONLINE_RECTIFICATION

아래는 다양한 영상 데이터에서 SLAM으로 3차원 데이터 생성 테스트한 것이다.


아울러, 다음 영상같이 생성된 맵에서 밀집(Dense) 포인트 클라우드를 생성할 수 있다.

레퍼런스
Dense Point Cloud Reconstruction
ORB SLAM with ZED

2021년 8월 17일 화요일

PDAL기반 포인트 클라우드 PCD파일 LAS 및 E57로 변환하기

이 글은 PDAL(Point Data Abstraction Library)기반 포인트 클라우드 PCD파일 LAS 및 E57로 변환하는 방법을 간략히 설명한다. 

가끔 스캔 데이터를 처리하다보면, 다양한 포맷을 다루어야 할 경우가 생긴다. 특히, 스캔 데이터 파일수가 수백개 이상일 경우, 하나씩 파일을 열어 다른 형식으로 변환하는 노가다를 해야 한다. PDAL을 이용하면, 배치처리로 이런 수작업을 자동화할 수 있다. 여기서는 PDAL을 사용하거나, CloudCompare 를 이용하는 방법을 소개한다.

점군 변환 도구 소개

PDAL은 포인트 클라우드(점군) 데이터를 처리하는 라이브러리이다. C++로 개발되었으며, 다양한 입출력 데이터 형식과 필터링을 지원한다.

PDAL의 주요 기능은 다음과 같다. 

  • 점군 간 거리 계산, 선택, 밀도 조정, 분류, 정보 추출, 정렬, 분할, 병합, 공간 인덱스 생성, 변환, 배치 처리
점군 선택 기능(GDAL)

지원 형식은 여기를 참고한다.

CloudCompare는 오픈소스 기반 포인트 클라우드 뷰어, 분석 및 편집 프로그램이다. 


이 프로그램의 주요 기능은 다음과 같다.
  • LAS, E57, PCD등 다양한 포맷 지원, 데이터 변환, 세그먼테이션, 분할, 병합, 뷰어, 법선 벡터 계산, 분석, 점군 간 비교, 분석된 결과 가시화, 플러그인 지원

PDAL 설치

PDAL은 리눅스 운분투에서 다음 명령으로 설치한다.

sudo apt install pdal

윈도우에서 설치하려면, 아나콘다(anaconda)를 설치한 후, 아래 명령을 실행하면 된다.

conda install -c conda-forge pdal

데이터 형식 변환

PDAL이 설치되면, 데이터 형식 변환은 다음과 같이 명령창에서 실행하면 된다(예. E57에서 LAS변환). 
pdal translate input.e57 output.las

ROS(Robot Operating System) 등 로보틱스 기반 스캔 기술에서 많이 사용되는 PCD형식의 경우에는 PDAL이 아스키(ASCII) 텍스트 포맷만 지원하므로, PCL-TOOLS를 이용해 텍스트 형식으로 변화해 줘야한다. 설치는 아래 링크를 참고한다.
설치 후, 아래 명령을 실행해, PCD파일을 텍스트 형식으로 변환한다.
pcl_convert_pcd_ascii_binary input.pcd output.pcd

PDAL을 이용한 PCD to LAS 변환은 다음과 같다.
pdal translate input.pcd output.las

이 과정을 다음과 같이, BASH 쉘(참고 - BASH), 파워셀(참고 - powershell) 명령창에서 FOR 루프를 이용하거나, 와일드카드(*), 파이프라인이라는 배치(Batch) 기능으로 처리할 수 있다.

for f in *.pcd; do pcl_convert_pcd_ascii_binary $f ./ascii/$f 0; done
for f in *.pcd; do pdal translate ./$f $f.las; done

배치 처리 결과

이와 유사하게 파워셀에서도 다음과 같이 배치를 병렬처리할 수 있다.
ls ./dir1/*.pcd | parallel -I{} -j 4 pdal translate -i ./dir1/{/.}.pcd -o ./dir2/{/.}.las

참고로, 파이프라인 배치처리 정의 파일 문법은 다음과 같다.
{
    "pipeline": [
        {
            "type":"readers.las"
        },
        {
            "type": "filters.reprojection"
        },
        {  
            "type": "filters.smrf"
        },
        {
            "type":"filters.range",
            "limits":"Classification[2:2]"
        },
        {
            "gdaldriver":"GTiff",
            "output_type":"idw",
            "resolution" :"2.0",
            "type": "writers.gdal"
        }
    ]
}

CloudCompare(클라우드 컴페어)를 설치해 다음과 같이 변환할 수도 있다.

CloudCompare   -o  points.e57 -C_EXPORT_FMT  LAS  -SAVE_CLOUDS

마무리

좋은 도구를 잘 쓰면 몸이 편할 수 있다. 이제 수많은 스캔 데이터 파일은 이런 방식으로 처리를 자동화할 수 있다. 


참고: ROS bag to pcd
ROS를 사용해 스캔을 하면 bag데이터 형식으로 녹화할 수 있다. 이 파일은 아래와 같은 명령을 이용해 pcd파일로 변환할 수 있다.
rosbag reindex *.bag.active
rosbag fix *.bag.active repaired.bag
rosrun pcl_ros bag_to_pcd [input bag] /laser_cloud_surround pcd