스테레오 카메라 시스템 개요

스테레오 카메라 시스템은 두 개 이상의 카메라를 사용하여 3차원 공간에서 객체의 위치와 깊이를 추정하는 기술이다. 두 카메라가 서로 다른 시점에서 동일한 객체를 촬영함으로써, 두 이미지 간의 차이를 기반으로 깊이 정보를 계산할 수 있다. 이 과정은 스테레오 캘리브레이션을 통해 정확하게 이루어지며, 이는 카메라 간의 관계를 정확히 알아내는 것을 목표로 한다.

카메라 간의 관계 정의

스테레오 카메라 시스템에서 두 카메라의 상대적인 위치와 방향을 알아내기 위해서 외부 파라미터를 추정해야 한다. 외부 파라미터는 한 카메라의 좌표계를 기준으로 다른 카메라의 위치와 방향을 나타내는 매트릭스이다. 이를 나타내는 수식은 다음과 같다.

두 카메라 간의 관계는 다음과 같은 수식으로 표현된다.

\mathbf{P}_{2} = \mathbf{R} \mathbf{P}_{1} + \mathbf{t}

여기서, - \mathbf{P}_{1}은 첫 번째 카메라 좌표계에서의 점의 위치, - \mathbf{P}_{2}는 두 번째 카메라 좌표계에서의 동일한 점의 위치, - \mathbf{R}은 첫 번째 카메라에서 두 번째 카메라로의 회전 행렬, - \mathbf{t}는 첫 번째 카메라에서 두 번째 카메라로의 변위 벡터이다.

이 외부 파라미터 \mathbf{R}\mathbf{t}를 정확히 알아내는 것이 스테레오 캘리브레이션의 핵심 과제이다.

에피폴라 기하학

스테레오 카메라 시스템에서 두 카메라가 촬영한 이미지 간의 대응점을 찾기 위해 에피폴라 기하학이 사용된다. 에피폴라 기하학은 두 카메라가 서로 다른 시점에서 동일한 객체를 촬영할 때, 두 이미지 간의 점들이 어떻게 대응하는지를 설명한다.

에피폴라 기하학에서 중요한 개념은 에피폴라인과 기본 행렬(Fundamental Matrix)이다. 기본 행렬 \mathbf{F}는 두 이미지 간의 대응 관계를 정의하며, 두 이미지의 대응점 \mathbf{p}_1\mathbf{p}_2는 다음과 같은 수식을 만족해야 한다.

\mathbf{p}_2^T \mathbf{F} \mathbf{p}_1 = 0

여기서, - \mathbf{p}_1\mathbf{p}_2는 각각 첫 번째 이미지와 두 번째 이미지에서의 대응점 좌표를 나타낸다. - \mathbf{F}는 기본 행렬로, 두 카메라의 내부 및 외부 파라미터에 따라 결정된다.

스테레오 정합

스테레오 카메라 시스템에서 깊이 정보를 얻기 위해서는 두 이미지에서 동일한 객체를 나타내는 대응점을 찾아야 한다. 이 과정을 스테레오 정합(Stereo Matching)이라고 하며, 두 이미지 간의 대응점을 찾는 방식에는 여러 가지 알고리즘이 존재한다.

스테레오 정합을 통해 얻은 대응점들의 차이를 "시차"라고 하며, 이 시차를 기반으로 깊이를 추정할 수 있다. 시차는 두 이미지에서 대응점의 좌표 차이로 계산되며, 깊이 d는 시차 \mathbf{d}와 다음과 같은 수식 관계를 갖는다.

d = \frac{fB}{\mathbf{d}}

여기서, - f는 카메라의 초점 거리, - B는 두 카메라 간의 베이스라인(카메라 간 거리), - \mathbf{d}는 시차이다.

깊이 추정

스테레오 카메라 시스템의 주된 목표는 깊이를 추정하는 것이다. 위에서 언급한 시차와 베이스라인, 초점 거리 정보를 바탕으로, 각 대응점에 대한 깊이를 추정할 수 있다. 추정된 깊이 정보는 3차원 재구성 또는 객체의 위치를 계산하는 데 사용된다.

스테레오 캘리브레이션을 통해 두 카메라 간의 정확한 관계를 알아낸 후, 스테레오 정합을 통해 깊이를 계산하는 과정을 통해 시스템은 3차원 공간에서의 객체 위치를 얻을 수 있다.

스테레오 캘리브레이션 절차

스테레오 캘리브레이션은 두 카메라의 내부 파라미터, 외부 파라미터, 그리고 왜곡 계수를 추정하는 과정을 포함한다. 이러한 과정을 통해 두 카메라가 3D 공간에서 어떤 관계에 있는지를 정확하게 파악할 수 있다. 일반적으로 스테레오 캘리브레이션 절차는 다음과 같은 단계로 이루어진다.

  1. 카메라 개별 캘리브레이션
    각 카메라에 대해 내부 파라미터(초점 거리, 주점 위치)와 왜곡 계수(Radial, Tangential 왜곡)를 추정한다. 이 단계에서는 주로 Zhang의 캘리브레이션 방법이나 Chessboard 패턴을 사용하여 각 카메라의 개별적인 특성을 알아낸다.

  2. 카메라 간의 상대적 위치와 방향 추정
    두 카메라 사이의 외부 파라미터(회전 행렬 \mathbf{R}과 변위 벡터 \mathbf{t})를 추정하는 단계이다. 이 단계에서는 두 카메라에서 촬영한 동일한 객체나 패턴의 대응점을 찾고, 이를 바탕으로 두 카메라 간의 공간적 관계를 계산한다.

  3. 스테레오 정렬 및 보정
    추정된 내부 및 외부 파라미터를 이용하여 두 이미지의 정렬을 수행한다. 이 과정에서는 이미지 좌표계에서 발생하는 왜곡을 보정하고, 대응점 찾기가 용이하도록 두 이미지를 정렬한다. 특히, 에피폴라 제약 조건을 기반으로 한 정렬이 중요하다.

  4. 에피폴라 정렬
    스테레오 이미지가 정렬된 후, 두 카메라 이미지에서의 대응점은 에피폴라인 위에 위치하게 된다. 이를 에피폴라 정렬이라고 하며, 정렬된 이미지를 통해 시차 계산이 더 정확하게 이루어진다.

스테레오 정합 알고리즘

스테레오 캘리브레이션 후, 두 이미지에서 동일한 객체를 나타내는 대응점을 찾기 위한 다양한 정합 알고리즘이 존재한다. 여기서 중요한 목표는 두 이미지 간의 시차를 정확하게 계산하여 깊이를 추정하는 것이다. 대표적인 스테레오 정합 알고리즘으로는 다음과 같은 방법들이 있다.

  1. 차폐 기반 방법 (Block Matching)
    각 픽셀 주변의 작은 영역(차폐)을 설정하고, 두 이미지에서 그 차폐 간의 차이를 최소화하는 대응점을 찾는 방법이다. 일반적으로 차폐 기반 방법은 간단하고 계산 비용이 적지만, 정밀도가 떨어질 수 있다.

  2. 그래프 컷 (Graph Cut)
    스테레오 정합 문제를 그래프로 모델링하고, 최소 비용 경로를 찾아 대응점을 결정하는 방법이다. 그래프 컷 알고리즘은 에너지를 최소화하는 방식으로, 보다 정교한 정합 결과를 제공할 수 있다.

  3. 준준최적 방법 (Semi-Global Matching, SGM)
    SGM은 전역 최적화를 수행하지 않고, 비교적 낮은 계산 비용으로 좋은 정합 결과를 얻을 수 있는 방법이다. SGM은 여러 방향에서의 시차를 고려하여 최적화된 시차 지도를 생성한다.

스테레오 캘리브레이션의 실습

OpenCV를 이용한 스테레오 캘리브레이션

OpenCV는 스테레오 캘리브레이션을 위한 여러 가지 함수와 도구를 제공한다. 스테레오 캘리브레이션을 위해서는 먼저 두 카메라의 개별적인 캘리브레이션이 필요하다. 이후, 두 이미지에서 동일한 객체나 패턴을 이용하여 대응점을 찾고 이를 통해 두 카메라 간의 관계를 계산한다.

OpenCV에서 스테레오 캘리브레이션을 수행하는 주요 단계는 다음과 같다.

  1. 개별 카메라 캘리브레이션
    각 카메라에 대해 cv2.calibrateCamera 함수를 사용하여 내부 파라미터와 왜곡 계수를 추정한다.

  2. 스테레오 캘리브레이션
    cv2.stereoCalibrate 함수를 사용하여 두 카메라 간의 외부 파라미터 \mathbf{R}\mathbf{t}를 추정한다. 이 함수는 내부 파라미터와 함께 두 카메라 간의 공간적 관계를 계산한다.

  3. 스테레오 정렬
    cv2.stereoRectify 함수를 사용하여 에피폴라 정렬을 수행한다. 이 과정에서 왜곡이 제거된 이미지가 생성되어, 두 이미지에서의 대응점을 더 쉽게 찾을 수 있다.

  4. 시차 지도 계산
    cv2.StereoBM 또는 cv2.StereoSGBM과 같은 시차 계산 알고리즘을 이용하여 두 이미지 간의 시차를 계산한다.

Python 예제 코드

import cv2
import numpy as np

ret1, mtx1, dist1, rvecs1, tvecs1 = cv2.calibrateCamera(objpoints, imgpoints1, gray1.shape[::-1], None, None)
ret2, mtx2, dist2, rvecs2, tvecs2 = cv2.calibrateCamera(objpoints, imgpoints2, gray2.shape[::-1], None, None)

retval, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F = cv2.stereoCalibrate(
    objpoints, imgpoints1, imgpoints2, mtx1, dist1, mtx2, dist2, gray1.shape[::-1])

R1, R2, P1, P2, Q, validPixROI1, validPixROI2 = cv2.stereoRectify(
    cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, gray1.shape[::-1], R, T)

stereo = cv2.StereoBM_create(numDisparities=16, blockSize=15)
disparity = stereo.compute(imgL, imgR)

MATLAB을 이용한 스테레오 캘리브레이션

MATLAB에서도 스테레오 비전을 구현할 수 있는 툴박스가 제공된다. MATLAB의 스테레오 비전 툴박스에서는 stereoParams 객체를 사용하여 스테레오 캘리브레이션을 진행할 수 있다. 스테레오 비전 툴박스를 사용하여 두 카메라 간의 외부 파라미터를 추정하고, 왜곡을 보정할 수 있다.

  1. 개별 카메라 캘리브레이션
    MATLAB에서는 estimateCameraParameters 함수를 사용하여 각 카메라에 대한 내부 파라미터와 왜곡 계수를 추정한다.

  2. 스테레오 캘리브레이션
    estimateStereoParameters 함수를 사용하여 두 카메라 간의 외부 파라미터와 내부 파라미터를 함께 추정한다.

  3. 스테레오 정렬
    stereoRectify 함수를 사용하여 두 이미지 간의 에피폴라 정렬을 수행하고 왜곡을 보정한다.

스테레오 정합 및 3D 재구성

스테레오 정합을 통해 시차 지도를 얻은 후, 이를 기반으로 3D 공간에서 객체를 재구성할 수 있다. 시차 지도는 이미지 상의 각 픽셀의 깊이를 나타내며, 이 값을 사용하여 3차원 좌표를 계산할 수 있다. 시차 값을 이용하여 3D 좌표를 계산하는 공식은 다음과 같다.

\mathbf{P}_{3D} = Q \cdot \begin{bmatrix} u \\ v \\ d \\ 1 \end{bmatrix}

여기서, - \mathbf{P}_{3D}는 3D 좌표, - Q는 스테레오 정렬에서 얻어진 재투영 행렬, - u, v는 이미지에서의 좌표, - d는 시차 값이다.

시차 값이 계산된 후, 이를 이용하여 각 픽셀에 해당하는 3D 좌표를 추정할 수 있다.