MATLAB을 활용한 카메라 캘리브레이션 개요

MATLAB은 강력한 수치 해석 기능과 이미지 처리 툴박스를 제공하여, 카메라 캘리브레이션을 손쉽게 구현할 수 있다. MATLAB의 Camera Calibration Toolbox는 다양한 카메라 파라미터를 추정하고, 왜곡을 보정하며, 이미지에서 객체의 위치를 정확하게 추정하는데 사용된다. 이 섹션에서는 MATLAB을 이용한 카메라 캘리브레이션 과정의 세부 사항을 설명하고, 실제 코드를 통해 구현 방법을 다룰 것이다.

1. 기본 카메라 모델과 파라미터 설명

MATLAB에서 카메라 모델은 일반적으로 핀홀 카메라 모델을 기반으로 하며, 이 모델은 내부(intrinsic) 및 외부(extrinsic) 파라미터로 구성된다.

카메라의 내부 파라미터

카메라의 내부 파라미터는 렌즈의 특성 및 이미지 센서의 구조와 관련된 요소들이다. 이는 다음과 같은 변수들로 정의된다:

\mathbf{K} = \begin{bmatrix} f_x & s & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix}

여기서: - f_x, f_y: 카메라의 초점 거리(focal length)로, 픽셀 단위로 표현된다. - s: 이미지 센서의 비대칭성을 나타내는 스큐(skew) 파라미터이다. - c_x, c_y: 이미지 센서의 중심점(coordinate center) 좌표이다.

외부 파라미터

외부 파라미터는 카메라와 월드 좌표계 간의 관계를 나타내며, 회전 행렬 \mathbf{R}과 변환 벡터 \mathbf{t}로 정의된다. 이는 월드 좌표계에서 카메라 좌표계로의 변환을 다음과 같이 표현할 수 있다:

\mathbf{P}_{cam} = \mathbf{R} \mathbf{P}_{world} + \mathbf{t}

여기서: - \mathbf{P}_{world}: 월드 좌표계에서의 3D 점이다. - \mathbf{P}_{cam}: 카메라 좌표계에서의 3D 점이다. - \mathbf{R}: 3x3 회전 행렬이다. - \mathbf{t}: 3x1 변환 벡터이다.

이러한 내부 및 외부 파라미터는 캘리브레이션 과정에서 추정되며, MATLAB에서 제공하는 함수들을 통해 계산된다.

2. MATLAB에서 캘리브레이션을 위한 준비 과정

MATLAB을 이용해 카메라 캘리브레이션을 수행하기 전에 필요한 준비 작업이 있다. 가장 일반적인 방법은 chessboard 패턴을 사용하여 여러 각도에서 이미지를 촬영한 후, 각 이미지에서 체스보드 코너의 좌표를 추출하여 캘리브레이션을 진행하는 것이다.

Camera Calibration Toolbox 설치

Camera Calibration Toolbox는 MATLAB의 기본 툴박스에 포함되어 있으므로, 추가적으로 설치할 필요는 없다. MATLAB의 명령 창에서 다음과 같이 툴박스를 불러올 수 있다:

calibrationTool;

이를 통해 GUI 기반의 캘리브레이션 도구를 사용할 수 있다. GUI는 코너 감지, 이미지 불러오기, 결과 시각화 등을 제공한다.

체스보드 패턴 준비 및 촬영

카메라 캘리브레이션을 위해서는 일정한 간격으로 정렬된 체스보드 패턴이 필요하다. 각 패턴의 각도 및 거리에서 촬영한 여러 이미지가 필요하며, 다양한 각도에서 최소한 10장 이상의 이미지를 촬영하는 것이 권장된다.

이미지를 준비한 후 MATLAB으로 불러와 캘리브레이션을 진행할 수 있다.

3. 캘리브레이션 수행

캘리브레이션 이미지 불러오기

다음과 같은 MATLAB 코드를 사용하여 촬영된 캘리브레이션 이미지를 불러올 수 있다:

images = imageDatastore('calibrationImages/');

이 코드를 사용하여 체스보드 패턴이 포함된 이미지를 불러온 후, 각 이미지에서 코너를 자동으로 감지하는 과정을 진행할 수 있다.

코너 감지

코너 감지는 MATLAB에서 제공하는 detectCheckerboardPoints 함수를 통해 수행된다. 이 함수는 입력 이미지에서 체스보드의 코너 위치를 자동으로 감지하여 반환한다.

[imagePoints, boardSize] = detectCheckerboardPoints(images.Files);

여기서: - imagePoints: 이미지 좌표에서의 코너 점 좌표들이 저장된다. - boardSize: 체스보드의 내부 코너 수를 반환한다.

카메라 파라미터 추정

코너 점이 감지되면, estimateCameraParameters 함수를 사용하여 카메라의 내부 및 외부 파라미터를 추정할 수 있다.

params = estimateCameraParameters(imagePoints, worldPoints);

여기서: - imagePoints: 감지된 이미지 좌표의 코너 점들이다. - worldPoints: 월드 좌표에서의 대응 코너 점들이다. - params: 추정된 카메라 파라미터를 포함한 구조체이다.

카메라 파라미터가 추정되면, 내부 파라미터 \mathbf{K}와 외부 파라미터 \mathbf{R}, \mathbf{t}를 얻을 수 있다.

4. 캘리브레이션 결과 확인 및 시각화

카메라 파라미터를 추정한 후, MATLAB에서는 다양한 시각화 도구를 제공하여 결과를 확인할 수 있다. 특히, 재투영 오류(reprojection error)를 시각화하여 캘리브레이션의 정확도를 평가할 수 있다.

재투영 오류 분석

재투영 오류는 3D 월드 좌표에서 추정된 2D 이미지 좌표와 실제 측정된 2D 이미지 좌표 간의 차이를 나타낸다. 이 값이 작을수록 캘리브레이션이 정확하게 수행된 것이다. MATLAB에서 재투영 오류를 시각화하려면 다음과 같은 코드를 사용할 수 있다:

showReprojectionErrors(params);

이 함수는 각 이미지에 대해 재투영된 점과 실제 측정된 점 간의 차이를 시각적으로 보여준다. 시각적으로 확인하여 오류가 큰 이미지나 특정 구간이 있는지 확인할 수 있다.

카메라 위치 시각화

추정된 외부 파라미터를 사용하여, 카메라의 위치와 방향을 3D 공간에서 시각화할 수 있다. 이는 캘리브레이션 중에 각 이미지가 찍힌 카메라의 위치와 자세를 시각적으로 확인하는 데 유용하다.

figure;
showExtrinsics(params);

이 코드는 3D 좌표계에서 각 카메라의 위치와 방향을 시각화해 준다. 여러 각도에서 찍힌 이미지들이 잘 배치되었는지 확인할 수 있다.

5. 왜곡 보정

캘리브레이션 후에는 왜곡된 이미지를 보정할 수 있다. 카메라 렌즈는 일반적으로 Radial 및 Tangential 왜곡을 일으키며, 이를 MATLAB에서 보정하는 방법은 간단한다.

왜곡 보정 적용

undistortImage 함수를 사용하여 왜곡된 이미지를 보정할 수 있다. 보정된 이미지는 카메라 렌즈의 왜곡을 제거한 결과를 포함한다.

undistortedImage = undistortImage(distortedImage, params);

여기서: - distortedImage: 원래 왜곡된 이미지이다. - undistortedImage: 보정된 이미지이다. - params: 캘리브레이션된 카메라 파라미터이다.

이 과정을 통해 보정된 이미지에서 왜곡이 어떻게 제거되는지 확인할 수 있다.

6. 3D 객체 위치 추정

카메라 캘리브레이션을 통해, 이제 2D 이미지에서 3D 객체의 위치를 추정할 수 있다. 이를 위해 추정된 카메라 파라미터를 사용하여 월드 좌표계에서의 3D 위치를 계산할 수 있다.

2D 이미지에서 3D 점 복원

카메라 좌표계에서의 3D 점을 복원하기 위해서는 역투영 과정을 사용해야 한다. 주어진 이미지 좌표 \mathbf{p}_{img}에서 월드 좌표계의 3D 점 \mathbf{P}_{world}를 추정하는 과정은 다음과 같이 표현된다:

\mathbf{P}_{world} = \mathbf{R}^{-1} (\mathbf{K}^{-1} \mathbf{p}_{img} - \mathbf{t})

여기서: - \mathbf{p}_{img}: 이미지 좌표에서의 2D 점이다. - \mathbf{K}: 카메라의 내부 파라미터 행렬이다. - \mathbf{R}, \mathbf{t}: 외부 파라미터 행렬이다.

MATLAB에서 이 과정을 수행하는 코드는 다음과 같다:

worldPoints = pointsToWorld(params, R, t, imagePoints);

이 코드는 이미지 좌표에 대응하는 월드 좌표의 3D 점들을 반환한다.