Chessboard 패턴의 기본 개념

카메라 캘리브레이션에서 가장 많이 사용되는 패턴 중 하나는 체스보드(Chessboard) 패턴이다. 이 패턴은 쉽게 인식 가능한 정사각형의 교차점을 통해 이미지에서 특징을 추출하는 데 매우 유용하다. 체스보드 패턴의 교차점들은 2D 이미지 공간에서 추출된 후, 3D 물리적 공간에서의 대응 좌표와 연결된다. 이를 통해 카메라의 내부 파라미터와 외부 파라미터를 추정할 수 있다.

체스보드 패턴을 이용한 캘리브레이션은 보통 다음과 같은 절차로 이루어진다: 1. 체스보드 패턴이 프린트된 보드를 여러 각도에서 촬영한다. 2. 각 이미지에서 체스보드의 교차점을 추출한다. 3. 교차점의 이미지 좌표를 실제 체스보드의 3D 좌표에 대응시킨다. 4. 이를 기반으로 카메라 매트릭스와 왜곡 계수를 계산한다.

체스보드 패턴의 수학적 모델

체스보드의 교차점들은 3D 공간에서 정규 격자로 구성되어 있으므로, 각 교차점의 좌표는 다음과 같이 표현될 수 있다. \mathbf{P}_{i,j}는 체스보드에서의 i-번째 열과 j-번째 행의 교차점 좌표이다.

\mathbf{P}_{i,j} = \begin{bmatrix} i \cdot s \\ j \cdot s \\ 0 \end{bmatrix}

여기서, s는 각 격자의 크기(단위 거리)이다.

이미지 좌표와 3D 좌표 간의 관계

카메라 캘리브레이션의 목적은 이미지 좌표와 3D 물리적 좌표 간의 관계를 추정하는 것이다. 이를 위해 다음의 투영 모델이 사용된다:

\mathbf{p}_{i,j} = \mathbf{K} \left[ \mathbf{R} \, | \, \mathbf{t} \right] \mathbf{P}_{i,j}

여기서: - \mathbf{p}_{i,j}는 이미지 상의 i,j-번째 교차점의 좌표이다. - \mathbf{K}는 카메라의 내부 파라미터 행렬이다. - \mathbf{R}은 회전 행렬, \mathbf{t}는 변환 벡터로, 카메라의 외부 파라미터를 나타낸다. - \mathbf{P}_{i,j}는 앞서 정의된 3D 공간의 교차점 좌표이다.

내부 파라미터와 외부 파라미터 추정

카메라 내부 파라미터 \mathbf{K}는 다음과 같이 정의된다:

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

여기서: - f_x, f_y는 카메라 렌즈의 초점 거리(focal length)이다. - c_x, c_y는 이미지 좌표계의 중심점이다.

외부 파라미터 \mathbf{R}, \mathbf{t}는 회전과 변환으로 이루어져 있으며, 각 이미지 프레임마다 다르게 추정된다. 이는 이미지 상의 교차점이 실제 체스보드의 3D 좌표와 어떻게 대응하는지를 결정한다.

체스보드 패턴 탐지 알고리즘

체스보드 패턴의 교차점을 탐지하기 위해서는 이미지 내의 각 교차점을 추출하는 알고리즘이 필요하다. OpenCV와 같은 라이브러리에서는 다음과 같은 메서드가 제공된다:

ret, corners = cv2.findChessboardCorners(image, (pattern_size[0], pattern_size[1]), None)

여기서 pattern_size는 체스보드의 교차점 개수를 나타낸다. 탐지된 교차점 좌표는 corners에 저장되며, 이를 통해 이미지 좌표와 실제 3D 좌표를 대응시킬 수 있다.

카메라 캘리브레이션 절차

체스보드 패턴을 이용한 카메라 캘리브레이션은 다음과 같은 단계로 이루어진다:

  1. 체스보드 이미지 촬영
    다양한 각도에서 체스보드 패턴을 촬영하여 여러 이미지 데이터를 수집한다. 체스보드를 다양한 위치와 각도에서 찍어야 내부 파라미터와 외부 파라미터를 정확히 추정할 수 있다. 보통 적어도 10장 이상의 이미지를 사용하는 것이 좋다.

  2. 교차점 탐지
    수집된 각 이미지에서 체스보드 패턴의 교차점을 탐지한다. 이를 통해 얻어진 좌표는 2D 이미지 좌표에 해당한다.

  3. 2D 이미지 좌표와 3D 체스보드 좌표의 대응
    각 교차점의 2D 이미지 좌표는 실제 체스보드의 3D 좌표와 대응된다. 앞서 정의한 \mathbf{P}_{i,j}는 3D 공간에서의 교차점 좌표이며, 대응되는 이미지 좌표는 \mathbf{p}_{i,j}이다.

  4. 최적화를 통한 내부 및 외부 파라미터 추정
    Levenberg-Marquardt 알고리즘과 같은 최적화 기법을 통해 카메라의 내부 파라미터 \mathbf{K}와 외부 파라미터 \mathbf{R}, \mathbf{t}를 추정한다. 이는 여러 이미지에서 추출된 2D-3D 대응 좌표 쌍을 기반으로 이루어진다.

  5. 왜곡 계수 계산
    카메라 렌즈의 왜곡을 보정하기 위해서는 왜곡 계수를 계산해야 한다. 왜곡은 주로 Radial 왜곡과 Tangential 왜곡으로 나뉘며, 왜곡 계수는 카메라 모델에 따라 k_1, k_2, k_3와 같은 파라미터로 정의된다.

Radial 왜곡은 다음과 같은 수식으로 표현된다:

x_{\text{distorted}} = x(1 + k_1 r^2 + k_2 r^4 + k_3 r^6)
y_{\text{distorted}} = y(1 + k_1 r^2 + k_2 r^4 + k_3 r^6)

여기서 r는 이미지 좌표에서 원점으로부터의 거리이다. Tangential 왜곡은 다음과 같이 표현된다:

x_{\text{distorted}} = x + [2p_1 xy + p_2(r^2 + 2x^2)]
y_{\text{distorted}} = y + [p_1(r^2 + 2y^2) + 2p_2 xy]

p_1p_2는 Tangential 왜곡 계수이다.

  1. 재투영 오류 평가
    캘리브레이션의 품질을 평가하기 위해 재투영 오류를 계산한다. 재투영 오류는 3D 좌표를 이미지로 투영했을 때 실제 교차점 좌표와의 차이를 나타낸다. 재투영 오류는 다음과 같은 수식으로 계산된다:
\text{Reprojection Error} = \frac{1}{N} \sum_{i=1}^{N} \| \mathbf{p}_i - \hat{\mathbf{p}}_i \|

여기서 \mathbf{p}_i는 실제 이미지에서 탐지된 좌표이고, \hat{\mathbf{p}}_i는 캘리브레이션을 통해 예측된 좌표이다.

코드 예시: OpenCV를 이용한 캘리브레이션

OpenCV에서는 체스보드 패턴을 이용한 캘리브레이션을 위한 라이브러리를 제공한다. 다음은 Python을 이용한 간단한 구현 예시이다.

import cv2
import numpy as np

pattern_size = (9, 6)
objp = np.zeros((pattern_size[0]*pattern_size[1], 3), np.float32)
objp[:, :2] = np.mgrid[0:pattern_size[0], 0:pattern_size[1]].T.reshape(-1, 2)

objpoints = [] # 3D 공간의 점
imgpoints = [] # 2D 이미지 좌표

images = ['image1.jpg', 'image2.jpg', ...] # 예시 이미지 파일 리스트
for fname in images:
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 체스보드 코너 탐지
    ret, corners = cv2.findChessboardCorners(gray, pattern_size, None)

    if ret:
        objpoints.append(objp)
        imgpoints.append(corners)

ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)

print("카메라 매트릭스:\n", mtx)
print("왜곡 계수:\n", dist)

위 코드는 여러 체스보드 이미지를 처리하여 카메라 내부 파라미터와 왜곡 계수를 계산하는 예제이다. findChessboardCorners 함수는 이미지 내에서 체스보드의 교차점을 탐지하며, 이를 통해 2D 이미지 좌표와 3D 체스보드 좌표 간의 관계를 정의한다. 최종적으로 calibrateCamera 함수를 사용해 카메라의 내부 파라미터와 왜곡 계수를 추정한다.

체스보드 영상 찍는 요령

카메라 캘리브레이션을 위한 체스보드 영상 촬영 시 정확성과 일관성을 확보하는 것이 매우 중요하다. 잘못된 촬영 방법은 캘리브레이션 결과에 영향을 미쳐 왜곡 계수나 카메라 매트릭스의 정확도를 낮출 수 있다. 다음은 캘리브레이션을 위한 체스보드 패턴 촬영 시 유의해야 할 요령이다.

1. 다양한 각도에서 촬영

카메라의 전체적인 특성을 잘 반영하려면, 체스보드 패턴을 다양한 각도에서 촬영하는 것이 필요하다. 촬영할 때는 다음과 같은 각도를 고려해야 한다: - 정면(카메라가 체스보드와 수직인 상태) - 비스듬한 각도(좌측, 우측, 상하 방향에서 기울어진 상태) - 패턴이 화면의 좌우 또는 상하로 치우친 상태

다양한 각도에서 촬영하면 왜곡 보정과 같은 과정에서 더 정확한 결과를 얻을 수 있다.

2. 여러 거리에서 촬영

체스보드를 카메라로 여러 거리에서 촬영하는 것이 중요하다. 근거리와 원거리를 모두 포함하여 체스보드를 촬영함으로써 카메라의 초점 거리와 왜곡 특성을 더 잘 반영할 수 있다. - 근거리 촬영 시에는 체스보드가 화면에 꽉 차도록 프레임에 가득 채운다. - 원거리 촬영 시에는 체스보드가 화면의 작은 영역만 차지하도록 멀리서 촬영한다.

이러한 다양한 거리에서의 촬영은 카메라 렌즈의 왜곡을 정확히 추정하는 데 도움을 준다.

3. 충분한 교차점 수 확보

촬영된 이미지에서 체스보드의 충분한 교차점을 확보하는 것이 중요하다. 체스보드 패턴에서 너무 적은 부분만 촬영되면 캘리브레이션 정확도가 떨어질 수 있다. 따라서 이미지 상에 체스보드의 많은 교차점이 포함되도록 촬영한다. - 체스보드가 너무 작은 경우에는 정확한 특징점 추출이 어려울 수 있으므로 적절한 크기로 촬영한다.

4. 조명 환경

촬영 환경의 조명 상태도 캘리브레이션 결과에 큰 영향을 미친다. 지나치게 강한 조명은 체스보드의 교차점을 인식하기 어렵게 만들 수 있으며, 너무 어두운 환경에서도 교차점이 명확히 드러나지 않을 수 있다. - 자연광 또는 고르게 분산된 실내 조명을 사용하는 것이 좋다. - 그림자가 많이 생기지 않도록 조명을 조정하여 패턴의 교차점이 명확히 보이도록 한다.

5. 패턴의 왜곡 방지

체스보드 패턴이 평평하지 않거나 구겨져 있으면 정확한 캘리브레이션을 할 수 없다. 패턴을 사용할 때는 반드시 평평한 표면에 붙이거나 고정시켜야 한다. - 종이에 프린트한 체스보드 패턴을 사용할 경우, 단단한 판에 부착하여 구김이나 왜곡이 생기지 않도록 한다. - 촬영 시에도 패턴이 휘어지거나 흔들리지 않도록 주의한다.

6. 최소한 10장 이상의 이미지 촬영

일반적으로 캘리브레이션을 정확하게 수행하기 위해서는 최소 10장 이상의 이미지를 촬영하는 것이 좋다. 다양한 각도와 거리를 고려해 여러 장의 이미지를 촬영하고, 이미지마다 다른 외부 파라미터(위치, 회전)를 반영할 수 있도록 해야 한다.

7. 이미지 해상도

촬영된 이미지의 해상도는 캘리브레이션 결과에 영향을 미칠 수 있다. 고해상도의 이미지는 작은 왜곡이나 오차를 더 잘 감지할 수 있어 더 정확한 캘리브레이션을 가능하게 한다. - 가능하면 최대 해상도로 촬영하는 것이 좋다. - 해상도가 낮을 경우, 교차점의 위치가 부정확하게 탐지될 수 있다.

8. 포커스 및 셔터 속도

카메라의 포커스가 정확하게 맞추어져 있어야 하며, 체스보드가 움직이지 않도록 안정적인 상태에서 촬영해야 한다. 셔터 속도가 너무 느리면 이미지가 흐릿해져 정확한 특징점을 추출하기 어려울 수 있다. - 자동 포커스를 사용하거나 수동으로 포커스를 조정하여 체스보드에 정확히 맞춘다. - 셔터 속도를 적절히 조정하여 선명한 이미지를 얻는다.

이러한 촬영 요령을 준수하면 더 정확한 카메라 캘리브레이션 결과를 얻을 수 있다.