본 포스트에서는 direct method 기반의 VO 알고리즘으로 유명한 DSO 논문을 리뷰한다. DSO 코드를 분석하면서 논문에서는 생략된 디테일한 부분들이 굉장히 많다는 것을 알게되었고 이미 잘 정리된 다른 분들의 자료를 참고하여 수식 유도부터 코드 리뷰까지 포함하는 정리본을 작성하게 되었다.
1. Initialization
1.1 Calibration
direct method는 밝기오차를 최적화하여 카메라의 포즈를 추정하기 때문에 이미지의 밝기 차이에 민감하다. SLAM에서 주로 사용하는 머신비전 카메라는 일반적으로 이미지의 밝기 변화에 따라 노출시간을 자동으로 조절하므로(auto exposure) 노출시간에 따른 밝기 변화가 심한 경우 direct method는 정상적으로 작동하지 않을 수 있다. 아래는 [13] 논문의 예시이다.

1.1.1 Photometric Calibration
따라서 DSO 논문에서는 VO 알고리즘에서 일반적으로 수행하는 geometric calibration과 더불어 photometric calibration이라는 방법을 수행하였다. photometric calibration은 카메라의 노출시간(exposure time), 비네팅(vignetting), 카메라 반응함수 등을 고려하여 direct method가 지속적으로 밝기오차를 최적화할 수 있도록 한다. 자세한 공식은 다음과 같다.
-
-
-
-
-
-

다음으로

DSO는 위와 같은 photometric calibration 과정을 거쳐서 노출시간 변화에 상대적으로 invarant한 이미지 영상

위 그림에서 중간의 그래프를 보면 이미지 시퀀스에 따른 노출시간의 변화를 의미한다. 값을 보면 동일한 데이터 내에서도 0.018ms ~ 10.5ms까지 최대 500배 이상의 노출시간 변화가 발생하는 것을 알 수 있다. DSO는 이러한 카메라 노출시간 변화에 따른 밝기 변화를 에러함수로 모델링하지 않고 캘리브레이션함으로써 direct method의 포즈 추정 성능을 대폭 상승시켰다.
1.2 Error Function Formulation

다음과 같이 3차원 공간 상의 한 점
-
-
-
-
-
-
1.2.1 inverse depth parameterization
DSO에서는 3차원 점
실제 inverse depth 관련 논문[14]에서는 inverse depth를 사용하면 기존 3차원 공간의 3개 파라미터 대신 6개의 파라미터를 사용한다.
하지만, DSO 논문에서는

다음으로 카메라가
-
-
-
-

위 식을 inverse depth
-
direct method는 밝기 오차 (photometric error)를 에러함수로 사용하므로 픽셀의 밝기 값의 차이를 구해야 한다. 이 때, DSO는 카메라의 exposure time을 고려하여 밝기 오차를 조정하는 파라미터를 사용한다. 이를 photometric calibration parameters (a,b)라고 한다. 또는 affine brightness transfer parameters (a,b)라고도 부른다.
-
-
-
-
-
이 때, 두 점의 픽셀 밝기 차이를 에러(error, residual)로 설정한다.


DSO는 한 점에서 밝기 차이만을 고려하지 않고 한 점 주위의 총 8개의 점들 patch 밝기 차이를 고려한다. 위 이미지와 같이 1개의 점이 생략된 이유는 성능에 크게 영향을 주지 않으면서 4번의 float 연산을 한 번에 계산할 수 있는 SSE2 레지스터를 사용하여 속도를 가속하기 위함이다.
patch를 고려하고 weighting 함수 + huber 함수까지 적용한 에러함수
-
위 공식을 풀어서 다시 표현하면 논문의 Eq (4) 공식이 된다.
임의의 weighting 함수
huber function
위 식을 컴팩트하게 표현하기 위해
이를 두 카메라 이미지 상의 모든 점들에 대해 에러를 계산하면 아래와 같다. (논문의 Eq (8) 공식)
-
-
-
1.3 Gauss-Newton Optimization
huber function까지 적용한 에러함수
이 때, DSO에서
위 함수를 least square method로 최적화하기 위해서
따라서 해당 문제를
-
-
-
1.3.1. Gauss-Newton method
자세한 과정은 다음과 같다.
1.
2.
3.
4. 위 식을 정리하면 다음과 같은 식이 나오고
5. 이를 컴팩트하게 표현하기 위해 치환하면 다음과 같다.
-
-
6. 위 식을 계산하면 최적의
1.4 Jacobian Derivation
앞서 언급한 GN 방법을 사용하여 최적화를 하기 위해서는 Jacobian
1.4.1 Derivation of photometric parameters
photometric param a,b에 대한 Jacobian은 다음과 같이 계산할 수 있다.
-
1.4.2 Derivation of relative pose
에러함수
다음으로
-
위 식을 통해
다음으로
이를 바탕으로
지금까지 유도한 공식들을 결합하여 하나의 Jacobian of relative pose로 표현하면 다음과 같다.
-
1.4.3 Derivation of inverse depth
마지막으로 Jacobian of inverse depth
이 때,
위 관계식을 사용하여
따라서
정리해보면 Initialization에서 사용하는 Jacobian들은 아래와 같다.
idepth(N)
pose(6)
photometric(2)
모든 Jacobian을 유도했으면 아래와 같이 합쳐준다.
-
-
-
최종적으로 위 Jacobian

1.5 Solving the incremental equation (Schur Complement)
Jacobian까지 모두 유도를 마쳤으면 GN 방법을 사용하여 아래와 같은 최적화를 반복해서 풀어야 한다.

하지만 실제 위 최적화 공식을 반복적으로 풀면 매우 느린 속도로 인해 정상적으로 pose tracking을 할 수 없다. 이는
-
-
-
-
-
-
-
Hessian Matrix

일반적인 경우 3차원 점의 개수가 카메라 pose보다 훨씬 많으므로 다음과 같은 거대한 행렬이 생성된다. 따라서 역행렬을 계산할 때 매우 큰 연산시간이 소요되므로 이를 빠르게 계산할 수 있는 다른 방법이 필요하다.

이 때, 일반적으로 Schur Complement를 사용하여 computational cost를 낮추어 빠르게 계산한다.
Schur Complement를 위해 양변에 아래와 같은 특수한 형태의 행렬을 곱해준다.
위 식을 전개해서
1.5.1 Forward Substitution
-
-
위 식을 통해
1.5.2 Backward Substitution
inverse depth와 관련있는 항인
최종적으로 damping 계수
2. Frames
2.1. Pose Tracking

다음으로 pose tracking을 수행하면서 키프레임을 생성하는 알고리즘은 다음과 같다. 새로운 이미지가 들어오면 해당 이미지에 해당하는 3차원 포즈를 아직 모르기 때문에 이를 예측하기 위해 DSO는 가장 최근 두 프레임

두 프레임(
각 포즈 후보마다 순차적으로 밝기 오차(photometric error)를 계산하고 이를 최적화하여 최적의 포즈를 구한다. 그리고 최적의 포즈에서 다시 한 번 밝기 오차를 구한 후(resNew) 이전 오차(resOld)와 비교하여 충분히 오차가 감소하였는지 판단한다. 충분히 오차가 감소하였다면 다른 포즈 후보를 고려하지 않고 루프를 탈출한다. (coarseTracker::trackNewestCoarse() 함수 참조)

여러 포즈 후보들 중 하나의 포즈를 선택한 후 밝기 오차는 다음과 같이 구할 수 있다.
-

이 때, 한 점의 밝기 오차만 계산하는 것이 아닌 주변 8개 점들의 밝기 오차를 모두 계산한다. 다음으로 해당 비선형 함수를 최적화하기 위해 Jacobian을 계산한다.
photometric(2)
pose(6)
해당 Jacobian을 사용하여
-
-
이 때,
포즈가 업데이트되면 다시 한 번 에러를 계산한 후 에러가 충분히 감소하였는지 판단한다. 에러가 충분히 감소하였다면 나머지 포즈 후보들을 고려하지 않고 루프를 탈출한다. 그리고 lambda 값을 절반으로 줄인다. 만약 에러가 줄어들지 않는다면 lambda 값을 4배로 늘린 후 다시 수행한다.
2.2. Keyframe Decision
매 프레임마다 pose tracking이 끝나면 해당 프레임을 키프레임으로 결정할 지 판단한다. 키프레임으로 결정하는 기준은 다음과 같다.
1. 해당 프레임이 가장 첫 프레임인가?
2. (순수 회전을 제외한) 카메라 움직임으로 인한 optical flow의 변화량 + photometric param a,b의 변화량이 일정 기준 이상인가?
3. residual 값이 이전 키프레임과 비교했을 때 급격하게 변했는가?
위 세가지 기준 중 하나라도 만족하게 되면 해당 프레임은 키프레임으로 간주된다.
3. Non-keyframes
3.1. Inverse Depth Update
키프레임으로 간주되지 않는 프레임의 경우, 해당 프레임은 현재 sliding window에 있는 키프레임들의 immature point idepth 업데이트에 사용된다.

immature point idepth update
업데이트의 자세한 과정은 다음과 같다.

1. 우선, 이전 키프레임에 존재하는 idepth를 알고 있는 immature point들을 상대포즈

2. 이 때,
-

3.
이 때,

4. 다음으로 maximum discrete search 범위를 정한 후

5. 밝기 오차가 가장 작은 점을 선정했으면 patch 내에서 밝기 오차가 두 번째로 작은 점을 선정한 후 두 오차의 비율을 통해 해당 점의 퀄리티를 계산한다.

6. 해당
7. 최적화 과정을 통해 최적의 위치
-
-
를 전개하면
이 된다. 이를 idepth를 기준으로 다시 정리하면 다음과 같은 2개의 식이 유도된다.
8. 다음과 같이 유도된 식에서 최적의 위치
x gradient가 큰 경우
y gradient가 큰 경우

여기서
References
5. [CH] DSO tracking and optimization
8. [CH] DSO photometric calibration
9. [CH] DSO code with comments
11. [CH] DSO (5) Calculation and Derivation of Null Space
12. [KR] goodgodgd's Visual Odometry and vSLAM
13. [EN] DSO Photometric Calibration paper
'Engineering' 카테고리의 다른 글
[SLAM] g2o example 코드 리뷰 (0) | 2022.06.09 |
---|---|
[SLAM] Visual LiDAR Odometry and Mapping (V-LOAM) 논문 리뷰 (0) | 2022.06.08 |
[SLAM] Depth Enhanced Monocular Odometry (DEMO) 논문 리뷰 (0) | 2022.06.08 |
[SLAM] Direct Sparse Odometry (DSO) 논문 및 코드 리뷰 (2) (11) | 2022.06.03 |
[SLAM] Lidar Odometry And Mapping (LOAM) 논문 리뷰 (29) | 2022.06.02 |