Introduction
SLAM 카테고리에서는 이미지를 활용해 카메라의 포즈(pose)를 구하는 방법들에 대해 다뤘습니다. 하지만 막상 Epipolar geometry, PnP, ICP 등 여러 알고리즘을 이용해 포즈를 구해보면 부정확한 결과를 얻게 되는데요. 왜 그런 걸까요?
이미지는 기본적으로 렌즈(lens)를 활용해 구해집니다. 초점을 모으기 위해서, 혹은 더 넓은 FOV(Field Of View)를 확보하기 위해서 등 다양한 이유로 렌즈는 평면이 아니고 굴곡을 띄게 됩니다. 여기서부터 이상과 현실에는 괴리가 존재하는 거죠. 또한, 카메라마다 기본적으로 초점 거리, 배율 등이 다릅니다. 같은 영상을 찍음에도 카메라마다 다른 카메라 포즈를 생성한다면 이것들을 구하는 의미가 있을까요?
이번 시리즈에서는 영상 이미지를 실전에서 활용하게 위해서 기본적으로 해줘야 하는 전처리들을 다룰 예정입니다. 오프닝으로 가장 기본적인 카메라 모델인 핀홀 모델(Pinhole model)을 다루도록 하겠습니다. 다른 모델들에서도 공통적으로 알아야 하는 요소들을 핀홀 모델을 통해 쉽게 설명하는데 집중했습니다 😀
추가로, Camera calibration/geometry가 무엇인지와 같은 아주 기초적인 내용은 이번 시리즈에서는 다루지 않을 건데요. 해당 내용이 궁금하신 분들은 아주 잘 정리된 다크 프로그래머 님의 글을 추천드립니다.
Pinhole camera model
핀홀 모델은 이름 그대로 바늘구멍으로 빛을 받아들이는 모델입니다. 자연스럽게 상은 뒤집히게 되지만, 현재 이 모델을 사용하는 카메라들은 SW적으로 이를 다시 뒤집어 실제 사용자에게는 정방향의 영상을 제공합니다. 또한, 단순한 작은 구멍은 빛을 모으는 효과를 키우는데 한계가 있기에 실제로는 렌즈를 사용합니다.
위의 카메라 모델을 기하학적으로 볼 수 있도록 아래와 같이 표현할 수 있습니다. 사실 이게 카메라 지오메트리(camera geometry)입니다
위 그림은 물체가 카메라에 투영되기까지의 과정을 담고 있습니다. 월드 좌표계(world coordinate system)에서 카메라 좌표계(camera coordinate system)로 변환되고, 그 다음은 이미지 평면(image plane)으로 투영됩니다. 최종적으로는 픽셀 좌표계(pixel coordinate system)으로 변환되어 우리가 보는 이미지로서 값을 반환하게 됩니다. 아래는 이러한 변환 과정을 나타낸 수식입니다.
$$\begin{align*} s \begin{bmatrix} u \\ v \\ 1 \end{bmatrix} &= \begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} r_{11} & r_{12} & r_{13} & t_1 \\ r_{21} & r_{22} & r_{23} & t_2 \\ r_{31} & r_{32} & r_{33} & t_3 \end{bmatrix} \begin{bmatrix} X \\ Y \\ Z \\ 1 \end{bmatrix} \end{align*}$$
이제부터는 이 수식이 의미하는 바를 두 단계로 나누어 설명하도록 하겠습니다.
Intrinsic parameter
$$K=\begin{bmatrix} f_x & \textrm{skew_c}f_x & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix}$$
흔히 K로 표현되는 카메라 내부 파라미터(camera intrinsic parameter)는 카메라 관점에서 3차원 물체가 이미지로 투영되는 과정을 설명해 줍니다. 그렇기에 렌즈의 특성을 나타낼 수 있는 초점거리(focal length), 주점(principal point), 비대칭계수(skew coefficient)가 포함되어 있습니다 (각각의 의미는 다크 프로그래머 님의 글을 참고 바랍니다). 이제부터 이를 이용해 어떻게 camera coordinate로 표현된 물체를 pixel coordinate으로 가져올 수 있는지 유도해 보겠습니다.
그전에 가상의 공간인 normalized plane의 존재를 알아야 하는데요. 이는 편의상 $Z$(거리)를 1로 만든 좌표로 생각하면 됩니다. 계산의 편의를 위해 존재하기도 하며, 이를 카메라의 뒤에 위치시킴으로써 이미지가 렌즈를 통과하며 상이 뒤집히는 것 역시 표현 가능합니다 (이 과정이 실제로는 ISP가 다 해줍니다). 하지만 통상적으로 계산의 편의성과 직관적인 이해를 돕기 위해 카메라와 물체의 사이에 위치시킵니다. 전자를 real image plane, 후자를 symmetric image plane이라고 합니다.
카메라 좌표계에서 포착된 점을 $P_c[X, Y, Z]$로 나타내도록 하겠습니다. 우선 real image plane으로 이 좌표를 투영시켜 보겠습니다. 여기서는 초점거리($f$)와 카메라와 실제 점까지의 거리($Z$)의 비례 관계를 이용합니다.
$$\frac{Z}{f}=-\frac{X}{X'}=-\frac{Y}{Y'}$$
계산의 편의를 위해 symmetric image plane을 이용해 ($-$) 부호를 제거하겠습니다. 그리고 식을 정리하면 아래와 같은 식을 얻을 수 있습니다.
$$X'=f \frac{X}{Z}, \quad Y'=f \frac{Y}{Z}$$
이제 camera coordinate $P$를 image plane 내 $P'$으로 투영했습니다. 이제부터는 $P'$을 픽셀 좌표계로 보내보도록 하겠습니다. 우선 image plane은 camera coordinate의 특성을 그대로 계승해 주점(principal point)을 갖고 있습니다. 그러나 우리가 보는 픽셀 좌표계는 이미지의 좌측 상단이 원점으로 표현되죠. 또한, 더 이상 m, cm 등의 단위가 아닌 pixel이 단위로서 존재합니다.
중심($c_x, c_y$)에 대한 평행 이동과 스케일 변환($\alpha, \beta$) 과정을 수식으로 표현하면 아래와 같습니다.
$$\left\{\begin{matrix}u=\alpha X'+c_x=\alpha f \frac{X}{Z}+c_x \\ v=\beta Y'+c_y=\beta f \frac{Y}{Z}+c_y\end{matrix}\right.$$
여기서 $\alpha f$를 $f_x$, $\beta f$를 $f_y$라고 하며, intrinsic parameter의 두 요소입니다. $\alpha,\beta$의 단위가 pixels/meters이고 $f$의 단위가 cm나 m 등 물리적 거리를 나타내기 때문에, $f_x, f_y$의 단위는 pixel임을 알 수 있습니다.
이제 3차원 좌표 $P$를 픽셀 좌표 $p$로 투영시켰습니다. 그러면 최종적으로 정리한 변환식은 어떤 형태일까요? 3차원 좌표를 2차원 좌표로 만들었기 때문에 차원이 맞지 않습니다. 계산의 편의를 위해 픽셀 좌표는 homogeneous로, 3차원 좌표는 non-homogeneous로 표현해 차원을 맞춰주면 아래와 같은 관계식을 만들고 intrinsic parameter, K를 구할 수 있습니다.
$$\begin{pmatrix} u \\ v \\ 1 \end{pmatrix}=\frac{1}{Z}\underbrace{\begin{pmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \\ \end{pmatrix}}_K\begin{pmatrix} X \\ Y \\ Z \end{pmatrix} = \frac{1}{Z}KP$$
Extrinsic parameter
위에서 카메라 좌표계에서 픽셀 좌표계로의 변환 과정을 유도해 봤습니다. 그러나 보통 문제에서 주어지는 3차원 좌표는 월드 좌표계를 활용합니다. 즉, 카메라 좌표계에서 픽셀 좌표계로의 변환 이전에 월드 좌표계에서 카메라 좌표계로 변환을 해줘야 합니다. 이는 3차원 물체는 가만히 있어도 카메라가 움직이는 경우 물체가 이미지 내에서 다르게 표현됨을 떠올리면 쉽게 이해할 수 있습니다.
이러한 관계는 월드 좌표계에서 카메라의 포즈를 구함으로서 얻을 수 있는데요. 이러한 변환식을 외부 파라미터(extrinsic/external parameter)라고 합니다. 외부 파라미터를 구하는 방법은 3D 변환 시리즈에서 다뤘으니 자세한 내용은 해당 글을 보시면 될 것 같습니다. 결론적으로 외부 파라미터를 이용해 월드 좌표계에서 픽셀 좌표계로의 변환을 아래 수식으로 표현 가능합니다.
$$Zp=Z\begin{bmatrix} u \\ v \\ 1 \end{bmatrix}=K(RP_w+t)=KTP_w$$
Reference
이미지들에 대한 출처는 클릭 시 확인하실 수 있습니다.