스테레오 정류

스테레오 정류(rectification)는 캘리브레이션된 스테레오 쌍의 두 이미지를 워핑하여, 두 개의 이상적이고 평행한 카메라에서 나온 것처럼 보이게 만든다: 이미지 평면은 공면(coplanar), 광학축은 평행, 행은 정렬된다. 정류 후에는 좌측 이미지의 임의 픽셀에 대한 에피폴라 선이 단순히 우측 이미지의 동일한 행이 된다.

이것이 성립하는 이유: 임의의 카메라 포즈 쌍에 대해, 에피폴라 기하는 좌측 이미지 점의 매칭을 우측 이미지의 1차원 곡선(핀홀 카메라의 경우 직선)으로 제약한다. 정류는 두 에피폴을 수평축을 따라 무한대로 매핑하여 모든 에피폴라 선을 수평이면서 수직으로 정렬되게 만드는, 이미지에 적용되는 호모그래피 쌍 HL,HRH_L, H_R이다.

정류 변환은 어떻게 계산되는가

캘리브레이션된 내부 파라미터 KL,KRK_L, K_R, 렌즈 왜곡, 카메라 간 외부 변환 (R,t)(R, t)이 주어졌을 때, OpenCV의 stereoRectify가 사용하는 고전적인 (Bouguet) 구성은 다음과 같이 진행된다:

  1. 상대 회전 분할. 각 카메라를 RR의 “절반”만큼 회전시켜, 각 이미지를 최소한으로 방해하면서 두 광학축이 평행하게 만든다.
  2. 기선에 정렬.xx축이 기선 벡터 tt를 따라 향하도록 공통 회전을 적용한다. 이제 두 에피폴 모두 무한대에 위치하므로, 에피폴라 선은 수평이 된다.
  3. 공통 가상 내부 파라미터 선택. 두 뷰에 대해 단일한 새 카메라 행렬 KnewK_{\text{new}}(동일한 ff, 동일한 주점 행)를 선택하여, 정류된 쌍이 Z=fB/dZ = fB/d를 위한 하나의 초점 거리와 하나의 기선을 갖게 한다.
  4. 리맵 테이블 굽기. 카메라별 워핑 H=KnewRrectKold1H = K_{\text{new}} R_{\text{rect}} K_{\text{old}}^{-1}은 렌즈 왜곡 보정 모델과 결합되어 룩업 테이블로 미리 계산되므로, 각 프레임을 정류하는 데는 한 번의 이미지 리맵만 필요하다.
R1, R2, P1, P2, Q, roi1, roi2 = cv2.stereoRectify(K1, D1, K2, D2, size, R, T)
mapLx, mapLy = cv2.initUndistortRectifyMap(K1, D1, R1, P1, size, cv2.CV_32FC1)
mapRx, mapRy = cv2.initUndistortRectifyMap(K2, D2, R2, P2, size, cv2.CV_32FC1)
rectL = cv2.remap(imgL, mapLx, mapLy, cv2.INTER_LINEAR)
rectR = cv2.remap(imgR, mapRx, mapRy, cv2.INTER_LINEAR)

반환된 QQ 행렬은 정류된 픽셀-플러스-시차 (u,v,d)(u, v, d)를 3D로 직접 재투영한다 — 시차-깊이 변환을 행렬 형태로 표현한 것이다.

이것이 주는 이점

정류 품질 확인하기

빠른 정상성 검사: 정류된 이미지 사이에서 특징을 매칭하고 수직 시차 vLvRv_L - v_R을 살펴본다. 잘 정류된 쌍에서는 이것이 픽셀의 작은 일부여야 한다. 시스템적인 오프셋이나 이미지 전체에 걸친 기울기는 외부 파라미터 캘리브레이션이 표류했다는 뜻이다. 로봇 운용 기간 동안 수직 시차가 증가하는 것은 리그가 충격을 받았거나 열적으로 휘고 있다는 표준적인 증상이다.

실무상 주의점

SLAM에서의 의미

거의 모든 스테레오 SLAM 프론트엔드 — ORB-SLAM2의 키포인트별 스테레오 매칭, S-PTAM, Kimera의 밀집 SGM 기반 매핑 — 는 정류된 입력을 가정한다. 실시간 속도로 프레임별 깊이를 얻는 유일한 방법이 스캔라인 탐색이기 때문이다. 정류를 이해하면 스테레오 파이프라인이 어디서 깨지는지도 알 수 있다: 잘못된 캘리브레이션, 비동기화된 셔터, 어안 광학 모두 어떤 SLAM 코드가 실행되기도 전에 정류된 모델을 위반한다.

관련 문서